|
1 | 1 | #!/usr/bin/env python3
|
2 | 2 |
|
3 |
| -# Copyright 2024 Benjamin Gilbert <[email protected]> |
| 3 | +# Copyright 2024-2025 Benjamin Gilbert <[email protected]> |
4 | 4 |
|
5 | 5 | # Licensed under the Apache License, Version 2.0 (the "License");
|
6 | 6 | # you may not use this file except in compliance with the License.
|
|
23 | 23 | import json
|
24 | 24 | import os
|
25 | 25 | import re
|
| 26 | +import subprocess |
26 | 27 | import sys
|
27 | 28 | import time
|
28 | 29 | from typing import TypedDict
|
@@ -104,10 +105,17 @@ def sub(name, old, new):
|
104 | 105 |
|
105 | 106 |
|
106 | 107 | @cache
|
107 |
| -def get_releases() -> dict[str, WrapInfo]: |
108 |
| - '''Parse and return releases.json.''' |
109 |
| - with open('releases.json') as f: |
110 |
| - return json.load(f) |
| 108 | +def get_releases(commit=None) -> dict[str, WrapInfo]: |
| 109 | + '''Parse and return releases.json for the specified commit or the working |
| 110 | + tree.''' |
| 111 | + if commit is not None: |
| 112 | + data = subprocess.check_output( |
| 113 | + ['git', 'cat-file', 'blob', f'{commit}:releases.json'], text=True |
| 114 | + ) |
| 115 | + else: |
| 116 | + with open('releases.json') as f: |
| 117 | + data = f.read() |
| 118 | + return json.loads(data) |
111 | 119 |
|
112 | 120 |
|
113 | 121 | def get_wrap_versions() -> dict[str, str]:
|
@@ -262,6 +270,52 @@ def do_autoupdate(args: Namespace) -> None:
|
262 | 270 | raise Exception(f"Couldn't update {failures} wraps")
|
263 | 271 |
|
264 | 272 |
|
| 273 | +def do_commit(args: Namespace) -> None: |
| 274 | + old_releases = get_releases('HEAD') |
| 275 | + new_releases = get_releases() |
| 276 | + |
| 277 | + # we don't validate any invariants checked by sanity_checks.py |
| 278 | + changed_wraps = [ |
| 279 | + name for name in new_releases |
| 280 | + if old_releases.get(name) != new_releases[name] |
| 281 | + ] |
| 282 | + if not changed_wraps: |
| 283 | + raise ValueError('Found no changes to releases.json') |
| 284 | + if len(changed_wraps) != 1: |
| 285 | + raise ValueError(f'Can only commit one wrap at a time: {changed_wraps}') |
| 286 | + name = changed_wraps[0] |
| 287 | + |
| 288 | + if not args.message: |
| 289 | + new_ver = new_releases[name]['versions'][0] |
| 290 | + try: |
| 291 | + old_ver = old_releases[name]['versions'][0] |
| 292 | + except KeyError: |
| 293 | + old_ver = None |
| 294 | + if old_ver is None: |
| 295 | + args.message = 'add' |
| 296 | + elif old_ver != new_ver and new_ver.endswith('-1'): |
| 297 | + args.message = f'update from {old_ver.split("-")[0]} to {new_ver.split("-")[0]}' |
| 298 | + else: |
| 299 | + raise ValueError("Can't autogenerate commit message; specify -m") |
| 300 | + |
| 301 | + commit_files = [ |
| 302 | + 'ci_config.json', 'releases.json', f'subprojects/{name}.wrap' |
| 303 | + ] |
| 304 | + patch_dir = get_wrap_contents(name).get( |
| 305 | + 'wrap-file', 'patch_directory', fallback=None |
| 306 | + ) |
| 307 | + if patch_dir: |
| 308 | + commit_files.append(f'subprojects/packagefiles/{patch_dir}') |
| 309 | + |
| 310 | + # suppress Git summary output and recreate it ourselves so we can also |
| 311 | + # show the diffstat, to confirm we've committed the right files |
| 312 | + subprocess.check_call( |
| 313 | + ['git', 'commit', '-m', f'{name}: {args.message}', '-q'] + commit_files |
| 314 | + ) |
| 315 | + subprocess.check_call(['git', 'log', '-1', '--format=[%h] %s']) |
| 316 | + subprocess.check_call(['git', 'diff', '--stat', 'HEAD^..HEAD']) |
| 317 | + |
| 318 | + |
265 | 319 | def do_libtool_ver(args: Namespace) -> None:
|
266 | 320 | components = args.info.split(':', 2)
|
267 | 321 | components += ['0'] * (3 - len(components))
|
@@ -388,6 +442,18 @@ def main() -> None:
|
388 | 442 | )
|
389 | 443 | autoupdate.set_defaults(func=do_autoupdate)
|
390 | 444 |
|
| 445 | + commit = subparsers.add_parser( |
| 446 | + 'commit', |
| 447 | + aliases=['com'], |
| 448 | + help='commit a wrap update to Git', |
| 449 | + description='Commit a wrap update to Git.', |
| 450 | + ) |
| 451 | + commit.add_argument( |
| 452 | + '-m', '--message', metavar='text', |
| 453 | + help='commit message, without wrap name prefix' |
| 454 | + ) |
| 455 | + commit.set_defaults(func=do_commit) |
| 456 | + |
391 | 457 | libtool_ver = subparsers.add_parser(
|
392 | 458 | 'libtool-ver',
|
393 | 459 | aliases=['ltv'],
|
|
0 commit comments