Files
RustProxy/tools/checks/dependency_upgrade_0312.py
T
2026-10-11 17:10:04 +02:00

82 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""Check the 0.31.5 dependency/source migration; optionally require a resolved lock.
This is not a substitute for rustc, cargo metadata or runtime tests.
"""
from __future__ import annotations
import argparse
from pathlib import Path
import re
import tomllib
ROOT = Path(__file__).resolve().parents[2]
parser = argparse.ArgumentParser()
parser.add_argument('--require-lock', action='store_true', help='Require the post-upgrade Cargo.lock produced by cargo update')
args = parser.parse_args()
manifest = tomllib.loads((ROOT / 'Cargo.toml').read_text())
assert manifest['package']['version'] == '0.31.5'
assert manifest['package']['rust-version'] == '1.99'
deps = manifest['dependencies']
expected_requirements = {
'argon2': '0.6', 'rand': '0.10', 'sqlx': '0.9', 'rcgen': '0.14.10',
'tower-http': '0.7.1', 'brotli': '9', 'sysinfo': '0.39',
'h3': '=2.5.20', 'tokio': '1.53.2', 'hyper': '1.12.0',
}
for name, version in expected_requirements.items():
entry = deps[name]
found = entry if isinstance(entry, str) else entry['version']
assert found == version, f'{name} requirement changed: {found!r} != {version!r}'
assert deps['h3']['package'] == 'hpx-h3'
assert deps['h3']['features'] == ['quinn']
assert deps['sqlx']['default-features'] is False
assert deps['sqlx']['features'] == ['runtime-tokio', 'sqlite']
assert set(deps['sysinfo']['features']) == {'network','system'}
assert set(deps['rcgen']['features']) == {'crypto', 'pem', 'ring'}
assert 'tls12' in deps['rustls']['features'] and 'ring' in deps['rustls']['features']
assert 'tls12' in deps['tokio-rustls']['features']
for target in ('Dockerfile', 'integrations/routeros-oci-build/Dockerfile.routeros'):
assert 'FROM rust:1.99-trixie AS build' in (ROOT / target).read_text(), target
files = [p for p in (ROOT / 'src').rglob('*.rs')]
sources = '\n'.join(p.read_text() for p in files)
for old in ('rngs::OsRng', 'rand::thread_rng()', 'SaltString::generate(',
'distributions::Alphanumeric', '.key_pair.serialize_pem()',
'hash_password(password.as_bytes(), &salt)'):
assert old not in sources, f'obsolete dependency API: {old}'
for new in ('SysRng.try_fill_bytes(', 'phc::PasswordHash',
'hash_password(password.as_bytes())', 'verify_password(password.as_bytes()',
'signing_key.serialize_pem()', 'rand::rng()'):
assert new in sources, f'missing dependency migration: {new}'
assert 'VERSION = "5.33.1"' in (ROOT / 'scripts/build/swagger_assets.py').read_text()
lock = tomllib.loads((ROOT / 'Cargo.lock').read_text())
installed: dict[str,set[str]] = {}
for item in lock['package']:
installed.setdefault(item['name'], set()).add(item['version'])
latest_required = {
'argon2': '0.6.0', 'rand': '0.10.3', 'sqlx': '0.9.0',
'rcgen': '0.14.10', 'tower-http': '0.7.1', 'brotli': '9.0.0',
'sysinfo': '0.39.6', 'hpx-h3': '2.5.20', 'hyper': '1.12.0',
'tokio': '1.53.2',
}
def compatible_update(package: str, installed_version: str, minimum: str) -> bool:
candidate = tuple(int(x) for x in installed_version.split('.')[:3])
baseline = tuple(int(x) for x in minimum.split('.')[:3])
if package == 'hpx-h3':
return candidate == baseline # Intentionally exact-pinned for the QUIC integration.
if candidate[0] != baseline[0]:
return False
if baseline[0] == 0 and candidate[1] != baseline[1]:
return False
return candidate >= baseline
missing = {name: version for name,version in latest_required.items()
if not any(compatible_update(name, candidate, version)
for candidate in installed.get(name, set()))}
if missing:
details = ', '.join(f'{name} {version}' for name,version in missing.items())
if args.require_lock:
raise SystemExit(f'FAIL: Cargo.lock not resolved to current deps: {details}. Run cargo update first.')
print(f'PENDING: lockfile still requires cargo update ({details})')
else:
print('PASS: pinned key packages found in post-upgrade lock; cargo --locked verification is still required')
print('PASS: 0.31.5 source dependency APIs, manifest, TLS features, toolchain images and Swagger pin (static only)')