diff options
author | Dylan Baker <dylan.c.baker@intel.com> | 2021-01-05 11:46:49 -0800 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-01-07 00:07:56 +0000 |
commit | a450b4550d5d66bc9826b22a4d1435faf31a4cb2 (patch) | |
tree | 3d457ffba0f99617811b51309a6fa123c79eb3ed /bin | |
parent | bc9e09360f824612468a8a8d34987bbf7f820b86 (diff) | |
download | mesa-a450b4550d5d66bc9826b22a4d1435faf31a4cb2.tar.gz |
bin/gen_calendar_entries: Add support for extending a release
Acked-by: Eric Engestrom <eric@engestrom.ch>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8341>
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/gen_calendar_entries.py | 68 | ||||
-rw-r--r-- | bin/gen_calendar_entries_test.py | 109 |
2 files changed, 167 insertions, 10 deletions
diff --git a/bin/gen_calendar_entries.py b/bin/gen_calendar_entries.py index 45562eefec8..dcf3773db77 100755 --- a/bin/gen_calendar_entries.py +++ b/bin/gen_calendar_entries.py @@ -113,6 +113,69 @@ def release_candidate(args: RCArguments) -> None: commit(f'docs: Add calendar entries for {major}.{minor} release candidates.') +def extend(args: ExtendArguments) -> None: + """Extend a release.""" + @contextlib.contextmanager + def write_existing(writer: _csv._writer, current: typing.List[CalendarRowType]) -> typing.Iterator[CalendarRowType]: + """Write the orinal file, yield to insert new entries. + + This is a bit clever, basically what happens it writes out the + original csv file until it reaches the start of the release after the + one we're appending, then it yields the last row. When control is + returned it writes out the rest of the original calendar data. + """ + last_row: typing.Optional[CalendarRowType] = None + in_wanted = False + for row in current: + if in_wanted and row[0]: + in_wanted = False + assert last_row is not None + yield last_row + if row[0] == args.series: + in_wanted = True + if in_wanted and len(row) >= 5 and row[4] in {LAST_RELEASE.format(args.series), OR_FINAL.format(args.series)}: + # If this was the last planned release and we're adding more, + # then we need to remove that message and add it elsewhere + r = list(row) + r[4] = None + # Mypy can't figure this out… + row = typing.cast('CalendarRowType', tuple(r)) + last_row = row + writer.writerow(row) + # If this is the only entry we can hit a case where the contextmanager + # hasn't yielded + if in_wanted: + yield row + + current = read_calendar() + + with CALENDAR_CSV.open('w') as f: + writer = csv.writer(f) + with write_existing(writer, current) as row: + # Get rid of -rcX as well + if '-rc' in row[2]: + first_point = int(row[2].split('rc')[-1]) + 1 + template = '{}.0-rc{}' + days = 7 + else: + first_point = int(row[2].split('-')[0].split('.')[-1]) + 1 + template = '{}.{}' + days = 14 + + date = datetime.date.fromisoformat(row[1]) + for i in range(first_point, first_point + args.count): + date = date + datetime.timedelta(days=days) + r = [None, date.isoformat(), template.format(args.series, i), row[3], None] + if i == first_point + args.count - 1: + if days == 14: + r[4] = LAST_RELEASE.format(args.series) + else: + r[4] = OR_FINAL.format(args.series) + writer.writerow(r) + + commit(f'docs: Extend calendar entries for {args.series} by {args.count} releases.') + + def main() -> None: parser = argparse.ArgumentParser() sub = parser.add_subparsers() @@ -121,6 +184,11 @@ def main() -> None: rc.add_argument('manager', help="the name of the person managing the release.") rc.set_defaults(func=release_candidate) + ex = sub.add_parser('extend', help='Generate additional entries for a release.') + ex.add_argument('series', help='The series to extend, such as "29.3" or "30.0".') + ex.add_argument('count', type=int, help='The number of new entries to add.') + ex.set_defaults(func=extend) + args = parser.parse_args() args.func(args) diff --git a/bin/gen_calendar_entries_test.py b/bin/gen_calendar_entries_test.py index 30df79d4008..70536ba0f0d 100644 --- a/bin/gen_calendar_entries_test.py +++ b/bin/gen_calendar_entries_test.py @@ -25,15 +25,30 @@ from __future__ import annotations from unittest import mock import argparse import csv +import contextlib import tempfile import os import pathlib +import typing import pytest from . import gen_calendar_entries +@contextlib.contextmanager +def mock_csv(data: typing.List[gen_calendar_entries.CalendarRowType]) -> typing.Iterator[None]: + """Replace the actual CSV data with our test data.""" + with tempfile.TemporaryDirectory() as d: + c = os.path.join(d, 'calendar.csv') + with open(c, 'w') as f: + writer = csv.writer(f) + writer.writerows(data) + + with mock.patch('bin.gen_calendar_entries.CALENDAR_CSV', pathlib.Path(c)): + yield + + @pytest.fixture(autouse=True, scope='module') def disable_git_commits() -> None: """Mock out the commit function so no git commits are made durring testing.""" @@ -81,19 +96,13 @@ class TestRC: yield @pytest.fixture(autouse=True) - def mock_data(self) -> None: + def csv(self) -> None: """inject our test data..""" - with tempfile.TemporaryDirectory() as d: - c = os.path.join(d, 'calendar.csv') - with open(c, 'w') as f: - writer = csv.writer(f) - writer.writerows(self.ORIGINAL_DATA) - - with mock.patch('bin.gen_calendar_entries.CALENDAR_CSV', pathlib.Path(c)): - yield + with mock_csv(self.ORIGINAL_DATA): + yield def test_basic(self) -> None: - args = argparse.Namespace() + args: gen_calendar_entries.RCArguments = argparse.Namespace() args.manager = "Dylan Baker" gen_calendar_entries.release_candidate(args) @@ -106,3 +115,83 @@ class TestRC: actual = gen_calendar_entries.read_calendar() assert actual == expected + + +class TestExtend: + + def test_one_release(self) -> None: + data = [ + ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), + ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), + ] + + args: gen_calendar_entries.ExtendArguments = argparse.Namespace() + args.series = '20.3' + args.count = 2 + + with mock_csv(data): + gen_calendar_entries.extend(args) + actual = gen_calendar_entries.read_calendar() + + expected = [ + data[0], + ('', '2021-01-27', '20.3.4', 'Dylan Baker', ''), + ('', '2021-02-10', '20.3.5', 'Dylan Baker', ''), + ('', '2021-02-24', '20.3.6', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), + ] + + assert actual == expected + def test_one_release(self) -> None: + data = [ + ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), + ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), + ('21.0', '2021-01-13', '21.0.1', 'Dylan Baker', ''), + ('', '2021-01-27', '21.0.2', 'Dylan Baker', ''), + ('', '2021-02-10', '21.0.3', 'Dylan Baker', ''), + ('', '2021-02-24', '21.0.4', 'Dylan Baker', 'This is the last planned release of the 21.0.x series.'), + ] + + args: gen_calendar_entries.ExtendArguments = argparse.Namespace() + args.series = '21.0' + args.count = 1 + + with mock_csv(data): + gen_calendar_entries.extend(args) + actual = gen_calendar_entries.read_calendar() + + expected = data.copy() + d = list(data[-1]) + d[-1] = '' + expected[-1] = tuple(d) + expected.extend([ + ('', '2021-03-10', '21.0.5', 'Dylan Baker', 'This is the last planned release of the 21.0.x series.'), + ]) + + assert actual == expected + + def test_rc(self) -> None: + data = [ + ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), + ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), + ('21.0', '2021-01-13', '21.0.0-rc1', 'Dylan Baker', ''), + ('', '2021-01-20', '21.0.0-rc2', 'Dylan Baker', gen_calendar_entries.OR_FINAL.format('21.0')), + ] + + args: gen_calendar_entries.ExtendArguments = argparse.Namespace() + args.series = '21.0' + args.count = 2 + + with mock_csv(data): + gen_calendar_entries.extend(args) + actual = gen_calendar_entries.read_calendar() + + expected = data.copy() + d = list(expected[-1]) + d[-1] = '' + expected[-1] = tuple(d) + expected.extend([ + ('', '2021-01-27', '21.0.0-rc3', 'Dylan Baker', ''), + ('', '2021-02-03', '21.0.0-rc4', 'Dylan Baker', gen_calendar_entries.OR_FINAL.format('21.0')), + ]) + + assert actual == expected |