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>
This commit is contained in:
parent
bc9e09360f
commit
a450b4550d
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue