Repository navigation
Expand file tree
/
Copy pathcheck_dist
More file actions
executable file
·71 lines (59 loc) · 2.57 KB
/
Copy pathcheck_dist
File metadata and controls
executable file
·71 lines (59 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env bash
#
# Copyright 2009-2026 Joshua Bronson. All rights reserved.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Inspect built distributions before they are published. Nothing else does: the tests import
# from a wheel but never look inside one, and the release workflows went straight from `uv build`
# to publishing. That is how 0.24.0 shipped a wheel whose RECORD listed hex-encoded hashes
# instead of the urlsafe-base64 the spec requires (#406) with every check still green.
#
# Usage: ./check_dist [dist_dir] (dist_dir defaults to ./dist, where `uv build` writes)
set -euo pipefail
log() {
>&2 printf "> %s\n" "$@"
}
main() {
local dist_dir=${1:-dist}
declare -r hint="Hint: Use 'nix develop' to bootstrap a development environment"
if ! command -v uv >/dev/null 2>&1; then
log "Error: No 'uv' on PATH. $hint"
exit 1
fi
shopt -s nullglob
local -a wheels=("$dist_dir"/*.whl)
local -a sdists=("$dist_dir"/*.tar.gz)
# Guard against a false pass: with no artifacts to check, everything below trivially succeeds.
if [[ ${#wheels[@]} -eq 0 || ${#sdists[@]} -eq 0 ]]; then
log "Error: expected at least one wheel and one sdist in '$dist_dir'," \
" but found ${#wheels[@]} and ${#sdists[@]}. Run 'uv build' first?"
exit 1
fi
# The check that #406 needed. installer recomputes the hash and size of every file in the
# wheel and compares them to what RECORD claims, so a RECORD that is malformed (not just
# stale) fails here on every entry.
log "Validating each wheel's RECORD..."
uv run --no-project --with installer python - "${wheels[@]}" <<'PY'
import sys
from installer.sources import WheelFile
for path in sys.argv[1:]:
try:
with WheelFile.open(path) as wheel:
wheel.validate_record()
except Exception as exc: # noqa: BLE001 (report the issues, not a traceback)
print(f'RECORD INVALID: {path}', file=sys.stderr)
for issue in getattr(exc, 'issues', None) or [exc]:
print(f' {issue}', file=sys.stderr)
sys.exit(1)
print(f'RECORD ok: {path}')
PY
# Orthogonal to the above: catches metadata that PyPI would reject or render wrong, e.g. a
# README that no longer parses as reStructuredText.
log "Checking metadata renders..."
uv run --no-project --with twine twine check "${wheels[@]}" "${sdists[@]}"
log "Distributions OK: ${#wheels[@]} wheel(s), ${#sdists[@]} sdist(s) in '$dist_dir'"
}
main "$@"