h2h-dev-tools 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- h2h_dev_tools/__init__.py +1 -0
- h2h_dev_tools/__main__.py +43 -0
- h2h_dev_tools/atomic_files.py +32 -0
- h2h_dev_tools/bundle.py +107 -0
- h2h_dev_tools/bundle_verify.py +255 -0
- h2h_dev_tools/change_scope.py +167 -0
- h2h_dev_tools/ci_dependencies.py +70 -0
- h2h_dev_tools/dependency_audit.py +220 -0
- h2h_dev_tools/dependency_manifest.py +23 -0
- h2h_dev_tools/distribution_check.py +70 -0
- h2h_dev_tools/documentation.py +175 -0
- h2h_dev_tools/formal.py +209 -0
- h2h_dev_tools/git-flow-merge.sh +263 -0
- h2h_dev_tools/install-git-hooks.sh +34 -0
- h2h_dev_tools/migrate_v1.py +61 -0
- h2h_dev_tools/offline_wheel.py +138 -0
- h2h_dev_tools/primary-branch.sh +52 -0
- h2h_dev_tools/process.py +873 -0
- h2h_dev_tools/publish_version.py +106 -0
- h2h_dev_tools/rebuild-env.sh +80 -0
- h2h_dev_tools/version_policy.py +391 -0
- h2h_dev_tools-0.2.1.dist-info/METADATA +221 -0
- h2h_dev_tools-0.2.1.dist-info/RECORD +26 -0
- h2h_dev_tools-0.2.1.dist-info/WHEEL +4 -0
- h2h_dev_tools-0.2.1.dist-info/entry_points.txt +2 -0
- h2h_dev_tools-0.2.1.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Build a candidate wheel and run a repository-owned, offline smoke callback.
|
|
2
|
+
|
|
3
|
+
Only the candidate is installed in the temporary environment. Dependencies are
|
|
4
|
+
borrowed explicitly from the repository's development site, so this is artifact
|
|
5
|
+
validation and never evidence of clean dependency resolution.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import os
|
|
12
|
+
import subprocess
|
|
13
|
+
import sys
|
|
14
|
+
from collections.abc import Sequence
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from tempfile import TemporaryDirectory
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _python(environment: Path) -> Path:
|
|
20
|
+
return environment / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _site(python: Path, *, cwd: Path) -> Path:
|
|
24
|
+
result = subprocess.run(
|
|
25
|
+
[
|
|
26
|
+
str(python),
|
|
27
|
+
"-I",
|
|
28
|
+
"-c",
|
|
29
|
+
"import sysconfig; print(sysconfig.get_path('purelib'))",
|
|
30
|
+
],
|
|
31
|
+
cwd=cwd,
|
|
32
|
+
check=True,
|
|
33
|
+
text=True,
|
|
34
|
+
capture_output=True,
|
|
35
|
+
)
|
|
36
|
+
return Path(result.stdout.strip())
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def run_offline_smoke(
|
|
40
|
+
repository: Path, smoke_script: Path, arguments: Sequence[str] = ()
|
|
41
|
+
) -> None:
|
|
42
|
+
"""Own temporary build/install resources while the consumer owns its oracle."""
|
|
43
|
+
repository = repository.resolve(strict=True)
|
|
44
|
+
callback = (repository / smoke_script).resolve(strict=True)
|
|
45
|
+
if not callback.is_relative_to(repository) or not callback.is_file():
|
|
46
|
+
raise ValueError("Smoke callback must be a file inside the repository")
|
|
47
|
+
development_python = _python(repository / ".venv")
|
|
48
|
+
if not development_python.is_file():
|
|
49
|
+
raise ValueError(f"Missing repository-local Python: {development_python}")
|
|
50
|
+
development_site = _site(development_python, cwd=repository)
|
|
51
|
+
with TemporaryDirectory(prefix="h2h-offline-wheel-") as temporary:
|
|
52
|
+
root = Path(temporary)
|
|
53
|
+
dist = root / "dist"
|
|
54
|
+
environment = os.environ | {
|
|
55
|
+
"UV_CACHE_DIR": str(root / "uv-cache"),
|
|
56
|
+
"UV_OFFLINE": "1",
|
|
57
|
+
}
|
|
58
|
+
subprocess.run(
|
|
59
|
+
[
|
|
60
|
+
str(development_python),
|
|
61
|
+
"-m",
|
|
62
|
+
"build",
|
|
63
|
+
"--no-isolation",
|
|
64
|
+
"--outdir",
|
|
65
|
+
str(dist),
|
|
66
|
+
],
|
|
67
|
+
cwd=repository,
|
|
68
|
+
env=environment,
|
|
69
|
+
check=True,
|
|
70
|
+
)
|
|
71
|
+
wheels = list(dist.glob("*.whl"))
|
|
72
|
+
if len(wheels) != 1 or not wheels[0].is_file() or wheels[0].is_symlink():
|
|
73
|
+
raise ValueError("Build must produce exactly one regular wheel")
|
|
74
|
+
virtual_environment = root / "smoke-venv"
|
|
75
|
+
subprocess.run(
|
|
76
|
+
[
|
|
77
|
+
"uv",
|
|
78
|
+
"venv",
|
|
79
|
+
"--python",
|
|
80
|
+
str(development_python),
|
|
81
|
+
str(virtual_environment),
|
|
82
|
+
],
|
|
83
|
+
cwd=root,
|
|
84
|
+
env=environment,
|
|
85
|
+
check=True,
|
|
86
|
+
)
|
|
87
|
+
smoke_python = _python(virtual_environment)
|
|
88
|
+
subprocess.run(
|
|
89
|
+
[
|
|
90
|
+
"uv",
|
|
91
|
+
"pip",
|
|
92
|
+
"install",
|
|
93
|
+
"--python",
|
|
94
|
+
str(smoke_python),
|
|
95
|
+
"--no-deps",
|
|
96
|
+
str(wheels[0]),
|
|
97
|
+
],
|
|
98
|
+
cwd=root,
|
|
99
|
+
env=environment,
|
|
100
|
+
check=True,
|
|
101
|
+
)
|
|
102
|
+
smoke_site = _site(smoke_python, cwd=root)
|
|
103
|
+
(smoke_site / "development-dependencies.pth").write_text(
|
|
104
|
+
f"import site; site.addsitedir({str(development_site)!r})\n",
|
|
105
|
+
encoding="utf-8",
|
|
106
|
+
)
|
|
107
|
+
print(
|
|
108
|
+
"Offline wheel smoke borrows development dependencies; "
|
|
109
|
+
"it does not validate clean dependency resolution.",
|
|
110
|
+
flush=True,
|
|
111
|
+
)
|
|
112
|
+
subprocess.run(
|
|
113
|
+
[str(smoke_python), "-I", str(callback), *arguments],
|
|
114
|
+
cwd=root,
|
|
115
|
+
check=True,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def main(arguments: list[str] | None = None) -> int:
|
|
120
|
+
"""Run one callback with its arguments after an optional -- separator."""
|
|
121
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
122
|
+
parser.add_argument("--repository", required=True, type=Path)
|
|
123
|
+
parser.add_argument("--smoke-script", required=True, type=Path)
|
|
124
|
+
parser.add_argument("callback_arguments", nargs=argparse.REMAINDER)
|
|
125
|
+
options = parser.parse_args(arguments)
|
|
126
|
+
callback_arguments = options.callback_arguments
|
|
127
|
+
if callback_arguments[:1] == ["--"]:
|
|
128
|
+
callback_arguments = callback_arguments[1:]
|
|
129
|
+
try:
|
|
130
|
+
run_offline_smoke(options.repository, options.smoke_script, callback_arguments)
|
|
131
|
+
except (OSError, ValueError, subprocess.CalledProcessError) as error:
|
|
132
|
+
print(f"offline-wheel: {error}", file=sys.stderr)
|
|
133
|
+
return 1
|
|
134
|
+
return 0
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
if __name__ == "__main__":
|
|
138
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
repository_root=${1:?repository root is required}
|
|
6
|
+
cd "$repository_root"
|
|
7
|
+
|
|
8
|
+
configured_primary="$(git config --local --get workflow.primaryBranch || true)"
|
|
9
|
+
if [[ -n "$configured_primary" ]]; then
|
|
10
|
+
git show-ref --verify --quiet "refs/heads/$configured_primary" || {
|
|
11
|
+
printf 'Configured primary branch does not exist: %s\n' \
|
|
12
|
+
"$configured_primary" >&2
|
|
13
|
+
exit 1
|
|
14
|
+
}
|
|
15
|
+
printf '%s\n' "$configured_primary"
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
remote_head="$(
|
|
20
|
+
git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null \
|
|
21
|
+
|| true
|
|
22
|
+
)"
|
|
23
|
+
if [[ -n "$remote_head" ]]; then
|
|
24
|
+
primary="${remote_head#origin/}"
|
|
25
|
+
if git show-ref --verify --quiet "refs/heads/$primary"; then
|
|
26
|
+
printf '%s\n' "$primary"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
candidates=()
|
|
32
|
+
for candidate in main master; do
|
|
33
|
+
if git show-ref --verify --quiet "refs/heads/$candidate"; then
|
|
34
|
+
candidates+=("$candidate")
|
|
35
|
+
fi
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
if (( ${#candidates[@]} == 1 )); then
|
|
39
|
+
printf '%s\n' "${candidates[0]}"
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if (( ${#candidates[@]} > 1 )); then
|
|
44
|
+
printf '%s\n' \
|
|
45
|
+
'Primary branch is ambiguous; set git config --local workflow.primaryBranch.' \
|
|
46
|
+
>&2
|
|
47
|
+
else
|
|
48
|
+
printf '%s\n' \
|
|
49
|
+
'Cannot detect primary branch; set git config --local workflow.primaryBranch.' \
|
|
50
|
+
>&2
|
|
51
|
+
fi
|
|
52
|
+
exit 1
|