VirtualBox

source: vbox/trunk/src/VBox/Additions/3D/mesa/mesa-21.3.8/bin/gen_calendar_entries.py

最後變更 在這個檔案是 96488,由 vboxsync 提交於 2 年 前

Additions/3D/mesa: Export to OSE and remove symlinks.

  • 屬性 svn:eol-style 設為 LF
  • 屬性 svn:executable 設為 *
檔案大小: 9.5 KB
 
1#!/usr/bin/env python3
2# SPDX-License-Identifier: MIT
3
4# Copyright © 2021 Intel Corporation
5
6# Permission is hereby granted, free of charge, to any person obtaining a copy
7# of this software and associated documentation files (the "Software"), to deal
8# in the Software without restriction, including without limitation the rights
9# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10# copies of the Software, and to permit persons to whom the Software is
11# furnished to do so, subject to the following conditions:
12
13# The above copyright notice and this permission notice shall be included in
14# all copies or substantial portions of the Software.
15
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22# SOFTWARE.
23
24"""Helper script for manipulating the release calendar."""
25
26from __future__ import annotations
27import argparse
28import csv
29import contextlib
30import datetime
31import pathlib
32import subprocess
33import typing
34
35if typing.TYPE_CHECKING:
36 import _csv
37 from typing_extensions import Protocol
38
39 class RCArguments(Protocol):
40 """Typing information for release-candidate command arguments."""
41
42 manager: str
43
44 class FinalArguments(Protocol):
45 """Typing information for release command arguments."""
46
47 series: str
48 manager: str
49 zero_released: bool
50
51 class ExtendArguments(Protocol):
52 """Typing information for extend command arguments."""
53
54 series: str
55 count: int
56
57
58 CalendarRowType = typing.Tuple[typing.Optional[str], str, str, str, typing.Optional[str]]
59
60
61_ROOT = pathlib.Path(__file__).parent.parent
62CALENDAR_CSV = _ROOT / 'docs' / 'release-calendar.csv'
63VERSION = _ROOT / 'VERSION'
64LAST_RELEASE = 'This is the last planned release of the {}.x series.'
65OR_FINAL = 'Or {}.0 final.'
66
67
68def read_calendar() -> typing.List[CalendarRowType]:
69 """Read the calendar and return a list of it's rows."""
70 with CALENDAR_CSV.open('r') as f:
71 return [typing.cast('CalendarRowType', tuple(r)) for r in csv.reader(f)]
72
73
74def commit(message: str) -> None:
75 """Commit the changes the the release-calendar.csv file."""
76 subprocess.run(['git', 'commit', str(CALENDAR_CSV), '--message', message])
77
78
79
80def _calculate_release_start(major: str, minor: str) -> datetime.date:
81 """Calclulate the start of the release for release candidates.
82
83 This is quarterly, on the second wednesday, in Januray, April, July, and Octobor.
84 """
85 quarter = datetime.date.fromisoformat(f'20{major}-0{[1, 4, 7, 10][int(minor)]}-01')
86
87 # Wednesday is 3
88 day = quarter.isoweekday()
89 if day > 3:
90 # this will walk back into the previous month, it's much simpler to
91 # duplicate the 14 than handle the calculations for the month and year
92 # changing.
93 return quarter.replace(day=quarter.day - day + 3 + 14)
94 elif day < 3:
95 quarter = quarter.replace(day=quarter.day + 3 - day)
96 return quarter.replace(day=quarter.day + 14)
97
98
99def release_candidate(args: RCArguments) -> None:
100 """Add release candidate entries."""
101 with VERSION.open('r') as f:
102 version = f.read().rstrip('-devel')
103 major, minor, _ = version.split('.')
104 date = _calculate_release_start(major, minor)
105
106 data = read_calendar()
107
108 with CALENDAR_CSV.open('w') as f:
109 writer = csv.writer(f)
110 writer.writerows(data)
111
112 writer.writerow([f'{major}.{minor}', date.isoformat(), f'{major}.{minor}.0-rc1', args.manager])
113 for row in range(2, 4):
114 date = date + datetime.timedelta(days=7)
115 writer.writerow([None, date.isoformat(), f'{major}.{minor}.0-rc{row}', args.manager])
116 date = date + datetime.timedelta(days=7)
117 writer.writerow([None, date.isoformat(), f'{major}.{minor}.0-rc4', args.manager, OR_FINAL.format(f'{major}.{minor}')])
118
119 commit(f'docs: Add calendar entries for {major}.{minor} release candidates.')
120
121
122def _calculate_next_release_date(next_is_zero: bool) -> datetime.date:
123 """Calculate the date of the next release.
124
125 If the next is .0, we have the release in seven days, if the next is .1,
126 then it's in 14
127 """
128 date = datetime.date.today()
129 day = date.isoweekday()
130 if day < 3:
131 delta = 3 - day
132 elif day > 3:
133 # this will walk back into the previous month, it's much simpler to
134 # duplicate the 14 than handle the calculations for the month and year
135 # changing.
136 delta = (3 - day)
137 else:
138 delta = 0
139 delta += 7
140 if not next_is_zero:
141 delta += 7
142 return date + datetime.timedelta(days=delta)
143
144
145def final_release(args: FinalArguments) -> None:
146 """Add final release entries."""
147 data = read_calendar()
148 date = _calculate_next_release_date(not args.zero_released)
149
150 with CALENDAR_CSV.open('w') as f:
151 writer = csv.writer(f)
152 writer.writerows(data)
153
154 base = 1 if args.zero_released else 0
155
156 writer.writerow([args.series, date.isoformat(), f'{args.series}.{base}', args.manager])
157 for row in range(base + 1, 3):
158 date = date + datetime.timedelta(days=14)
159 writer.writerow([None, date.isoformat(), f'{args.series}.{row}', args.manager])
160 date = date + datetime.timedelta(days=14)
161 writer.writerow([None, date.isoformat(), f'{args.series}.3', args.manager, LAST_RELEASE.format(args.series)])
162
163 commit(f'docs: Add calendar entries for {args.series} release.')
164
165
166def extend(args: ExtendArguments) -> None:
167 """Extend a release."""
168 @contextlib.contextmanager
169 def write_existing(writer: _csv._writer, current: typing.List[CalendarRowType]) -> typing.Iterator[CalendarRowType]:
170 """Write the orinal file, yield to insert new entries.
171
172 This is a bit clever, basically what happens it writes out the
173 original csv file until it reaches the start of the release after the
174 one we're appending, then it yields the last row. When control is
175 returned it writes out the rest of the original calendar data.
176 """
177 last_row: typing.Optional[CalendarRowType] = None
178 in_wanted = False
179 for row in current:
180 if in_wanted and row[0]:
181 in_wanted = False
182 assert last_row is not None
183 yield last_row
184 if row[0] == args.series:
185 in_wanted = True
186 if in_wanted and len(row) >= 5 and row[4] in {LAST_RELEASE.format(args.series), OR_FINAL.format(args.series)}:
187 # If this was the last planned release and we're adding more,
188 # then we need to remove that message and add it elsewhere
189 r = list(row)
190 r[4] = None
191 # Mypy can't figure this out…
192 row = typing.cast('CalendarRowType', tuple(r))
193 last_row = row
194 writer.writerow(row)
195 # If this is the only entry we can hit a case where the contextmanager
196 # hasn't yielded
197 if in_wanted:
198 yield row
199
200 current = read_calendar()
201
202 with CALENDAR_CSV.open('w') as f:
203 writer = csv.writer(f)
204 with write_existing(writer, current) as row:
205 # Get rid of -rcX as well
206 if '-rc' in row[2]:
207 first_point = int(row[2].split('rc')[-1]) + 1
208 template = '{}.0-rc{}'
209 days = 7
210 else:
211 first_point = int(row[2].split('-')[0].split('.')[-1]) + 1
212 template = '{}.{}'
213 days = 14
214
215 date = datetime.date.fromisoformat(row[1])
216 for i in range(first_point, first_point + args.count):
217 date = date + datetime.timedelta(days=days)
218 r = [None, date.isoformat(), template.format(args.series, i), row[3], None]
219 if i == first_point + args.count - 1:
220 if days == 14:
221 r[4] = LAST_RELEASE.format(args.series)
222 else:
223 r[4] = OR_FINAL.format(args.series)
224 writer.writerow(r)
225
226 commit(f'docs: Extend calendar entries for {args.series} by {args.count} releases.')
227
228
229def main() -> None:
230 parser = argparse.ArgumentParser()
231 sub = parser.add_subparsers()
232
233 rc = sub.add_parser('release-candidate', aliases=['rc'], help='Generate calendar entries for a release candidate.')
234 rc.add_argument('manager', help="the name of the person managing the release.")
235 rc.set_defaults(func=release_candidate)
236
237 fr = sub.add_parser('release', help='Generate calendar entries for a final release.')
238 fr.add_argument('manager', help="the name of the person managing the release.")
239 fr.add_argument('series', help='The series to extend, such as "29.3" or "30.0".')
240 fr.add_argument('--zero-released', action='store_true', help='The .0 release was today, the next release is .1')
241 fr.set_defaults(func=final_release)
242
243 ex = sub.add_parser('extend', help='Generate additional entries for a release.')
244 ex.add_argument('series', help='The series to extend, such as "29.3" or "30.0".')
245 ex.add_argument('count', type=int, help='The number of new entries to add.')
246 ex.set_defaults(func=extend)
247
248 args = parser.parse_args()
249 args.func(args)
250
251
252if __name__ == "__main__":
253 main()
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette