The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
update_version Namespace Reference

Classes

class  Fields
 
class  FileUpdater
 
class  ReplacementRule
 

Functions

tuple[str, str] normalize_version (str version)
 
tuple[str, list[str], list[str]] update_changelog (Fields fields)
 
str contributor_handle (str name)
 
 update_version (str version, datetime.datetime date, bool dry_run)
 

Variables

 GITLAB_TOKEN = os.environ.get("GITLAB_TOKEN")
 

Function Documentation

◆ contributor_handle()

str update_version.contributor_handle ( str name)

Definition at line 193 of file update_version.py.

193def contributor_handle(name: str) -> str:
194 if GITLAB_TOKEN:
195 from requests import get
196
197 users = get(
198 "https://gitlab.cern.ch/api/v4/users",
199 headers={"PRIVATE-TOKEN": GITLAB_TOKEN},
200 params={"search": name},
201 ).json()
202 if users:
203 return f'@{users[0]["username"]}'
204 return name
205
206
207@click.command()
208@click.argument("version", type=str)
209@click.argument(
210 "date",
211 type=click.DateTime(("%Y-%m-%d",)),
212 metavar="[DATE]",
213 default=datetime.datetime.now(),
214)
215@click.option(
216 "--dry-run",
217 "-n",
218 default=False,
219 is_flag=True,
220 help="only show what would change, but do not modify the files",
221)

◆ normalize_version()

tuple[str, str] update_version.normalize_version ( str version)
Convert a version in format "vXrY" or "X.Y" in the pair ("X.Y", "vXrY").

>>> normalize_version("v37r0")
('37.0', 'v37r0')
>>> normalize_version("37.0.1")
('37.0.1', 'v37r0p1')

Definition at line 26 of file update_version.py.

26def normalize_version(version: str) -> tuple[str, str]:
27 """
28 Convert a version in format "vXrY" or "X.Y" in the pair ("X.Y", "vXrY").
29
30 >>> normalize_version("v37r0")
31 ('37.0', 'v37r0')
32 >>> normalize_version("37.0.1")
33 ('37.0.1', 'v37r0p1')
34 """
35 # extract the digits
36 numbers = re.findall(r"\d+", version)
37 return (
38 ".".join(numbers),
39 "".join("{}{}".format(*pair) for pair in zip("vrpt", numbers)),
40 )
41
42
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition MsgStream.cpp:93

◆ update_changelog()

tuple[str, list[str], list[str]] update_version.update_changelog ( Fields fields)
Special updater to fill draft changelog entry.

Definition at line 122 of file update_version.py.

122def update_changelog(fields: Fields) -> tuple[str, list[str], list[str]]:
123 """
124 Special updater to fill draft changelog entry.
125 """
126 latest_tag = run(
127 ["git", "describe", "--tags", "--abbrev=0"], capture_output=True, text=True
128 ).stdout.strip()
129 # This formats the git log as a rough markdown list
130 # - collect the log formatting it such that we can machine parse it
131 changes_txt = run(
132 ["git", "log", "--first-parent", "--format=%s<=>%b|", f"{latest_tag}.."],
133 capture_output=True,
134 text=True,
135 ).stdout
136 # - removing trailing separator and make it a single line
137 changes_txt = " ".join(changes_txt.strip().rstrip("|").splitlines())
138 # - normalize issues and merge requests links
139 changes = (
140 changes_txt.replace("Closes #", "gaudi/Gaudi#")
141 .replace("See merge request ", "")
142 .split("|")
143 )
144 # - split the messages and format the list
145 changes = [
146 f"- {msg.strip()} ({', '.join(refs.split())})\n"
147 if refs.strip()
148 else f"- {msg.strip()}\n"
149 for change in changes
150 for msg, refs in ([change.split("<=>", 1)] if "<=>" in change else [])
151 ]
152 # Now we get the list of contributors
153 contributors = sorted(
154 contributor_handle(name)
155 for name in set(
156 run(
157 ["git", "log", "--format=%an", f"{latest_tag}...HEAD"],
158 capture_output=True,
159 text=True,
160 ).stdout.splitlines()
161 )
162 )
163
164 filename = "CHANGELOG.md"
165 with open(filename) as f:
166 old = f.readlines()
167 for idx, line in enumerate(old):
168 if line.startswith("## ["):
169 break
170
171 data = old[:idx]
172 data.extend(
173 [
174 "## [{tag_version}](https://gitlab.cern.ch/gaudi/Gaudi/-/releases/{tag_version}) - {date}\n".format(
175 **fields.data
176 ),
177 "\nA special thanks to all the people that contributed to this release:\n",
178 ",\n".join(contributors),
179 ".\n\n",
180 "### Changed\n",
181 "### Added\n",
182 "### Fixed\n",
183 "\n",
184 ]
185 )
186 data.extend(changes)
187 data.extend(["\n", "\n"])
188 data.extend(old[idx:])
189
190 return filename, old, data
191
192

◆ update_version()

update_version.update_version ( str version,
datetime.datetime date,
bool dry_run )
Helper to easily update the project version number in all needed files.

Definition at line 222 of file update_version.py.

222def update_version(version: str, date: datetime.datetime, dry_run: bool):
223 """
224 Helper to easily update the project version number in all needed files.
225 """
226 fields = Fields(version, date.date())
227 click.echo(
228 "Bumping version to {cmake_version} (tag: {tag_version})".format(**fields.data)
229 )
230
231 for updater in [
232 FileUpdater(
233 "CMakeLists.txt",
234 [(r"^project\‍(Gaudi VERSION", "project(Gaudi VERSION {cmake_version}")],
235 ),
236 FileUpdater(
237 "CITATION.cff",
238 [
239 (r"^version: ", "version: {tag_version}"),
240 (r"^date-released: ", "date-released: '{date}'"),
241 ],
242 ),
243 FileUpdater(
244 "docs/source/conf.py",
245 [
246 (r"^version = ", 'version = "{cmake_version}"'),
247 (r"^release = ", 'release = "{tag_version}"'),
248 ],
249 ),
250 update_changelog,
251 ]:
252 filename, old, new = updater(fields)
253
254 if old != new:
255 if dry_run:
256 sys.stdout.writelines(
257 unified_diff(
258 old,
259 new,
260 fromfile=f"a/{filename}",
261 tofile=f"b/{filename}",
262 )
263 )
264 else:
265 click.echo(f"updated {filename}")
266 with open(filename, "w") as f:
267 f.writelines(new)
268
269

Variable Documentation

◆ GITLAB_TOKEN

update_version.GITLAB_TOKEN = os.environ.get("GITLAB_TOKEN")

Definition at line 23 of file update_version.py.