Mesa (master): bin: Add script for manipulating the release calendar

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 7 00:10:43 UTC 2021


Module: Mesa
Branch: master
Commit: bc9e09360f824612468a8a8d34987bbf7f820b86
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bc9e09360f824612468a8a8d34987bbf7f820b86

Author: Dylan Baker <dylan.c.baker at intel.com>
Date:   Mon Jan  4 16:04:45 2021 -0800

bin: Add script for manipulating the release calendar

Currently it only handles creating entries for a new rc.

Acked-by: Eric Engestrom <eric at engestrom.ch>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8341>

---

 bin/gen_calendar_entries.py      | 129 +++++++++++++++++++++++++++++++++++++++
 bin/gen_calendar_entries_test.py | 108 ++++++++++++++++++++++++++++++++
 docs/release-calendar.csv        |   4 +-
 3 files changed, 239 insertions(+), 2 deletions(-)

diff --git a/bin/gen_calendar_entries.py b/bin/gen_calendar_entries.py
new file mode 100755
index 00000000000..45562eefec8
--- /dev/null
+++ b/bin/gen_calendar_entries.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: MIT
+
+# Copyright © 2021 Intel Corporation
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""Helper script for manipulating the release calendar."""
+
+from __future__ import annotations
+import argparse
+import csv
+import contextlib
+import datetime
+import pathlib
+import subprocess
+import typing
+
+if typing.TYPE_CHECKING:
+    import _csv
+    from typing_extensions import Protocol
+
+    class RCArguments(Protocol):
+        """Typing information for release-candidate command arguments."""
+
+        manager: str
+
+    class ExtendArguments(Protocol):
+        """Typing information for extend command arguments."""
+
+        series: str
+        count: int
+
+
+    CalendarRowType = typing.Tuple[typing.Optional[str], str, str, str, typing.Optional[str]]
+
+
+_ROOT = pathlib.Path(__file__).parent.parent
+CALENDAR_CSV = _ROOT / 'docs' / 'release-calendar.csv'
+VERSION = _ROOT / 'VERSION'
+LAST_RELEASE = 'This is the last planned release of the {}.x series.'
+OR_FINAL = 'Or {}.0 final.'
+
+
+def read_calendar() -> typing.List[CalendarRowType]:
+    """Read the calendar and return a list of it's rows."""
+    with CALENDAR_CSV.open('r') as f:
+        return [typing.cast('CalendarRowType', tuple(r)) for r in csv.reader(f)]
+
+
+def commit(message: str) -> None:
+    """Commit the changes the the release-calendar.csv file."""
+    subprocess.run(['git', 'commit', str(CALENDAR_CSV), '--message', message])
+
+
+
+def _calculate_release_start(major: str, minor: str) -> datetime.date:
+    """Calclulate the start of the release for release candidates.
+
+    This is quarterly, on the second wednesday, in Januray, April, July, and Octobor.
+    """
+    quarter = datetime.date.fromisoformat(f'20{major}-0{[1, 4, 7, 10][int(minor)]}-01')
+
+    # Wednesday is 3
+    day = quarter.isoweekday()
+    if day > 3:
+        # this will walk back into the previous month, it's much simpler to
+        # duplicate the 14 than handle the calculations for the month and year
+        # changing.
+        return quarter.replace(day=quarter.day - day + 3 + 14)
+    elif day < 3:
+        quarter = quarter.replace(day=quarter.day + 3 - day)
+    return quarter.replace(day=quarter.day + 14)
+
+
+
+def release_candidate(args: RCArguments) -> None:
+    """Add release candidate entries."""
+    with VERSION.open('r') as f:
+        version = f.read().rstrip('-devel')
+    major, minor, _ = version.split('.')
+    date = _calculate_release_start(major, minor)
+
+    data = read_calendar()
+
+    with CALENDAR_CSV.open('w') as f:
+        writer = csv.writer(f)
+        writer.writerows(data)
+
+        writer.writerow([f'{major}.{minor}', date.isoformat(), f'{major}.{minor}.0-rc1', args.manager])
+        for row in range(2, 4):
+            date = date + datetime.timedelta(days=7)
+            writer.writerow([None, date.isoformat(), f'{major}.{minor}.0-rc{row}', args.manager])
+        date = date + datetime.timedelta(days=7)
+        writer.writerow([None, date.isoformat(), f'{major}.{minor}.0-rc4', args.manager, OR_FINAL.format(f'{major}.{minor}')])
+
+    commit(f'docs: Add calendar entries for {major}.{minor} release candidates.')
+
+
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    sub = parser.add_subparsers()
+
+    rc = sub.add_parser('release-candidate', aliases=['rc'], help='Generate calendar entries for a release candidate.')
+    rc.add_argument('manager', help="the name of the person managing the release.")
+    rc.set_defaults(func=release_candidate)
+
+    args = parser.parse_args()
+    args.func(args)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/bin/gen_calendar_entries_test.py b/bin/gen_calendar_entries_test.py
new file mode 100644
index 00000000000..30df79d4008
--- /dev/null
+++ b/bin/gen_calendar_entries_test.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: MIT
+
+# Copyright © 2021 Intel Corporation
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from __future__ import annotations
+from unittest import mock
+import argparse
+import csv
+import tempfile
+import os
+import pathlib
+
+import pytest
+
+from . import gen_calendar_entries
+
+
+ at pytest.fixture(autouse=True, scope='module')
+def disable_git_commits() -> None:
+    """Mock out the commit function so no git commits are made durring testing."""
+    with mock.patch('bin.gen_calendar_entries.commit', mock.Mock()):
+        yield
+
+
+class TestReleaseStart:
+
+    def test_first_is_wednesday(self) -> None:
+        d = gen_calendar_entries._calculate_release_start('20', '0')
+        assert d.day == 15
+        assert d.month == 1
+        assert d.year == 2020
+
+    def test_first_is_before_wednesday(self) -> None:
+        d = gen_calendar_entries._calculate_release_start('19', '0')
+        assert d.day == 16
+        assert d.month == 1
+        assert d.year == 2019
+
+    def test_first_is_after_wednesday(self) -> None:
+        d = gen_calendar_entries._calculate_release_start('21', '0')
+        assert d.day == 13
+        assert d.month == 1
+        assert d.year == 2021
+
+
+class TestRC:
+
+    ORIGINAL_DATA = [
+        ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''),
+        ('',     '2021-01-27', '20.3.4', 'Dylan Baker', 'Last planned release of the 20.3.x series'),
+    ]
+
+    @pytest.fixture(autouse=True, scope='class')
+    def mock_version(self) -> None:
+        """Keep the version set at a specific value."""
+        with tempfile.TemporaryDirectory() as d:
+            v = os.path.join(d, 'version')
+            with open(v, 'w') as f:
+                f.write('21.0.0-devel\n')
+
+            with mock.patch('bin.gen_calendar_entries.VERSION', pathlib.Path(v)):
+                yield
+
+    @pytest.fixture(autouse=True)
+    def mock_data(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
+
+    def test_basic(self) -> None:
+        args = argparse.Namespace()
+        args.manager = "Dylan Baker"
+        gen_calendar_entries.release_candidate(args)
+
+        expected = self.ORIGINAL_DATA.copy()
+        expected.append(('21.0', '2021-01-13', f'21.0.0-rc1', 'Dylan Baker'))
+        expected.append((    '', '2021-01-20', f'21.0.0-rc2', 'Dylan Baker'))
+        expected.append((    '', '2021-01-27', f'21.0.0-rc3', 'Dylan Baker'))
+        expected.append((    '', '2021-02-03', f'21.0.0-rc4', 'Dylan Baker', 'Or 21.0.0 final.'))
+
+        actual = gen_calendar_entries.read_calendar()
+
+        assert actual == expected
diff --git a/docs/release-calendar.csv b/docs/release-calendar.csv
index 9eec289f955..c6de990a20f 100644
--- a/docs/release-calendar.csv
+++ b/docs/release-calendar.csv
@@ -1,2 +1,2 @@
-20.3, 2021-01-13, 20.3.3, Dylan Baker,
-    , 2021-01-27, 20.3.4, Dylan Baker,
+20.3, 2021-01-13, 20.3.3, Dylan Baker,
+    , 2021-01-27, 20.3.4, Dylan Baker,



More information about the mesa-commit mailing list