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.
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.5
2
+ Name: h2h-dev-tools
3
+ Version: 0.2.1
4
+ Summary: Shared development tools and reproducible repository snapshots for H2H projects
5
+ Project-URL: Homepage, https://github.com/Kuan-Lun/h2h-dev-tools
6
+ Project-URL: Source, https://github.com/Kuan-Lun/h2h-dev-tools
7
+ Project-URL: Tracker, https://github.com/Kuan-Lun/h2h-dev-tools/issues
8
+ Author: Kuan-Lun Wang
9
+ License-Expression: GPL-3.0-only
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Classifier: Topic :: Software Development :: Quality Assurance
15
+ Requires-Python: >=3.14
16
+ Requires-Dist: packaging>=26.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: build>=1.5.0; extra == 'dev'
19
+ Requires-Dist: hatchling>=1.32.0; extra == 'dev'
20
+ Requires-Dist: mypy>=2.3.1; extra == 'dev'
21
+ Requires-Dist: pytest>=9.1.1; extra == 'dev'
22
+ Requires-Dist: ruff>=0.16.4; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # h2h-dev-tools
26
+
27
+ Shared development tools for H2H repositories. The Python package owns common
28
+ implementations; each consumer commits a verified source snapshot so its hooks
29
+ run offline against the code present in that repository's Git tree.
30
+
31
+ ## Install and synchronize
32
+
33
+ Use Python 3.14 or newer. Install the package in a development environment:
34
+
35
+ ```bash
36
+ python -m pip install h2h-dev-tools
37
+ ```
38
+
39
+ For an unpublished candidate, install an explicitly supplied wheel instead:
40
+
41
+ ```bash
42
+ python -m pip install /absolute/path/to/h2h_dev_tools-0.2.0-py3-none-any.whl
43
+ ```
44
+
45
+ Declare the components the consumer actually uses in its `pyproject.toml`:
46
+
47
+ ```toml
48
+ [tool.h2h-dev-tools]
49
+ components = ["change-scope", "dependencies", "documentation", "git-flow"]
50
+ ```
51
+
52
+ Then generate or update the snapshot:
53
+
54
+ ```bash
55
+ h2h-dev-tools sync --repository /absolute/path/to/consumer
56
+ h2h-dev-tools verify --repository /absolute/path/to/consumer
57
+ ```
58
+
59
+ Selection is explicit. The generator includes each selected component's complete
60
+ dependency closure and removes previously verified files that are no longer
61
+ selected. Verification rejects stale selection, modified files and unknown files.
62
+ Python modules and shell resources share the same hash-bound manifest.
63
+
64
+ | Component | Responsibility |
65
+ | --- | --- |
66
+ | `atomic-files` | Atomic byte publication with explicit replace or no-replace semantics; callers own JSON and directory policy |
67
+ | `change-scope`, `documentation` | Exact Git candidate classification and documentation checks |
68
+ | `dependencies`, `dependency-audit` | Declared dependencies, registry candidates and reviewed audit receipts |
69
+ | `version-policy` | Task-level release impact, version and audit validation |
70
+ | `primary-branch`, `git-flow`, `hooks`, `environment` | Local branch selection, safe merge lifecycle, hook installation and environment rebuild |
71
+ | `publish-version` | Version transition across a complete push |
72
+ | `distribution-check` | Installed requirements, RECORD and import-origin validation |
73
+ | `offline-wheel` | Temporary candidate-wheel environment with development dependencies and a local smoke callback |
74
+ | `process` | Owned process trees, deadlines, signal deferral and Windows Job start gates |
75
+ | `formal` | Pinned TLC download and offline host/Docker execution |
76
+
77
+ Schema-1 snapshots from 0.1 use a fixed payload and are not accepted by normal
78
+ schema-2 verification or sync. After declaring components, convert once:
79
+
80
+ ```bash
81
+ h2h-dev-tools migrate-v1 --repository /absolute/path/to/consumer
82
+ ```
83
+
84
+ The converter verifies the complete old manifest, file set and hashes before
85
+ updating generated files. It preserves unrelated files and rejects edited or
86
+ incomplete snapshots. This conversion changes development tools only; application
87
+ databases, archives and runtime environments do not need conversion.
88
+
89
+ Review the resulting consumer diff, run that repository's checks and commit the
90
+ snapshot update on its task branch. Sync is an explicit source update; it does
91
+ not commit, merge, push or publish. Consumers do not need this installed package
92
+ to run their committed snapshots, and do not add it to runtime dependencies.
93
+
94
+ The consumer snapshot lives in `scripts/_shared/h2h_dev_tools/`. Its tracked
95
+ `manifest.json` identifies the toolkit version and source payload hashes; these
96
+ are payload identities, not the wheel archive hash. Generated snapshots must
97
+ never be edited manually. A consumer checks its local snapshot without network
98
+ or an installed copy of the tool:
99
+
100
+ ```bash
101
+ python scripts/_shared/h2h_dev_tools/bundle_verify.py --repository .
102
+ ```
103
+
104
+ The manifest detects changed or incomplete source files; it is not a signature
105
+ or proof of the publisher's identity. Review the package source and consumer diff
106
+ before adopting an update.
107
+
108
+ Sync writes individual files before replacing the manifest. An interrupted update
109
+ can therefore leave a bundle that verification and later sync deliberately reject.
110
+ Inspect and preserve any pending edits first. If this consumer already has a
111
+ committed bundle, restore only that generated directory from the intended known
112
+ good commit, then run sync again; do not restore the whole repository or overwrite
113
+ unrelated changes. For example, after confirming `HEAD` contains the bundle you
114
+ intend to recover:
115
+
116
+ ```bash
117
+ git diff -- scripts/_shared/h2h_dev_tools
118
+ git diff --cached -- scripts/_shared/h2h_dev_tools
119
+ git restore --source=HEAD --worktree -- scripts/_shared/h2h_dev_tools
120
+ h2h-dev-tools sync --repository .
121
+ ```
122
+
123
+ The restore command changes only working files; after sync, review and stage the
124
+ complete updated bundle using the consumer's normal workflow.
125
+
126
+ For an interrupted first sync with no committed bundle, preserve the incomplete
127
+ directory outside `scripts/_shared/` after inspecting its contents, then sync into
128
+ the vacant destination. The tool never treats unknown files as disposable.
129
+
130
+ Thin repository entry points supply their own root and policies. Core schema
131
+ checks, adapter tests, pytest selectors, timeout budgets, formal targets and
132
+ deployment acceptance remain owned by their original repositories. Shell bootstrap
133
+ resources run before a `.venv` exists; they do not import the Python package.
134
+
135
+ Version paths are declared in `[tool.h2h.version]`; dependency inventory comes
136
+ from the project manifests. Shared version evaluation considers only commits that
137
+ actually change release surface. Hook installation refuses to replace an existing
138
+ third-party hook directory. Rebuild validates explicit source overrides before
139
+ replacing the environment. Merge checks dirty worktrees, in-progress Git operations
140
+ and stable refs; it runs the local candidate review/gate and aborts on failure.
141
+ Already-integrated tasks use checked cleanup without another merge or gate.
142
+
143
+ The low-level process launch API is silent and accepts file-backed stdout/stderr.
144
+ Its caller must defer signals until it owns the returned process. `run_command`
145
+ provides that lifecycle, reserves cleanup time, rejects surviving descendants and
146
+ verifies the final absolute deadline. Local callers select their budgets and
147
+ signals. POSIX children that deliberately detach and Docker-daemon-owned resources
148
+ are outside the owned-tree guarantee. Windows behavior also runs in the dedicated
149
+ Windows workflow; a POSIX test run does not substitute for it.
150
+
151
+ The `offline-wheel` component owns temporary build/install directories for
152
+ consumer wheel smoke checks. A consumer supplies its own validation script:
153
+
154
+ ```bash
155
+ .venv/bin/python scripts/_shared/h2h_dev_tools/offline_wheel.py \
156
+ --repository . --smoke-script scripts/check-installed-wheel.py
157
+ ```
158
+
159
+ Arguments following `--` are forwarded unchanged to that script. The helper
160
+ builds fresh distributions with the repository's development Python and build
161
+ backend, requires exactly one wheel, then installs only that wheel in a temporary
162
+ venv with `uv` in offline mode. It explicitly adds the development site for the
163
+ callback's dependencies and runs the callback with `python -I` from the temporary
164
+ directory. The callback owns package import/metadata checks, CLI checks and domain
165
+ oracles; arguments naming repository files must therefore be absolute paths.
166
+ Success and ordinary failure both remove the temporary environment. A surrounding
167
+ runner still owns the aggregate deadline and process-tree termination policy.
168
+ This checks the candidate artifact with development dependencies; it does **not**
169
+ prove clean dependency resolution or compatibility of an index-selected cohort.
170
+ The toolkit's own isolated resolver smoke and hbrowser's target-directory smoke
171
+ have different contracts and do not use this component.
172
+
173
+ ## Develop this repository
174
+
175
+ ```bash
176
+ scripts/rebuild-env.sh
177
+ scripts/install-git-hooks.sh
178
+ scripts/check-fast.sh
179
+ scripts/check-full.sh
180
+ ```
181
+
182
+ The expected primary branch is `master`. Create a dedicated task branch before
183
+ changing tracked files, then finish with `scripts/git-flow-merge.sh`. The merge
184
+ hook validates the real staged candidate and its version impact before running
185
+ the applicable documentation or full gate. `scripts/format.sh` applies formatters;
186
+ the check commands are read-only. Ruff and strict mypy use `pyproject.toml`.
187
+
188
+ The full gate builds fresh distributions, then installs the sdist-derived wheel
189
+ in a new environment with normal, offline pip resolution. Only the installed
190
+ `packaging` distribution is copied into that environment as dependency evidence;
191
+ no editable project or development-site fallback is used. The smoke verifies
192
+ package and metadata locations, runtime requirements, both CLI entry points, and
193
+ real snapshot export plus standalone verification.
194
+ This is an offline distribution check, not a registry-backed clean-resolution test.
195
+
196
+ ## Releases
197
+
198
+ `pyproject.toml` is the sole project-version source. The initial version is
199
+ `0.1.0`; subsequent compatible releases increment the third component, and
200
+ breaking changes increment the second component while it is below 1.0.
201
+ The shipped development tools and snapshot format are release surface even
202
+ though consumers use them only for development.
203
+
204
+ Before committing a release version, review dependency candidates and generate
205
+ the version-bound audit evidence:
206
+
207
+ ```bash
208
+ .venv/bin/python scripts/audit-dependencies.py \
209
+ --review-note "Release notes and compatibility validation results"
210
+ ```
211
+
212
+ GitHub's `publish.yml` workflow uses PyPI Trusted Publishing with environment
213
+ `pypi`. Normal default-branch pushes publish only when the version increases over
214
+ the whole push. Creating the branch does not publish. The first release can use
215
+ an explicitly authorized workflow dispatch with the exact project version; it
216
+ still requires the default branch and builds and verifies distributions first.
217
+ The PyPI publisher must match owner `Kuan-Lun`, repository `h2h-dev-tools`, workflow
218
+ `publish.yml` and environment `pypi`. Configuring this workflow does not execute a
219
+ release or validate the remote publisher configuration.
220
+
221
+ Licensed under GPL-3.0-only; see [LICENSE](LICENSE).
@@ -0,0 +1,26 @@
1
+ h2h_dev_tools/__init__.py,sha256=A9GWMmXyiAhbQ1HPxsph_Dvrc7LWWtfNAJjuaggNsJQ,61
2
+ h2h_dev_tools/__main__.py,sha256=5gVwaVTaJpwxhjBqkkmkHl5gz46ZDWzPjKSIzcZ6qbY,1479
3
+ h2h_dev_tools/atomic_files.py,sha256=wKmiRho4thT3TGqQJDvy3fDIzlQnrGP8b6PwCVNJDns,1115
4
+ h2h_dev_tools/bundle.py,sha256=ASMS2ohoA3GnV-x0XUvw4mdRaarvutpz-de-H71L5YQ,3903
5
+ h2h_dev_tools/bundle_verify.py,sha256=lIthJD_gnAQuAK2V-HBWwSnTPhoC_5zhic7xErk7wyw,10217
6
+ h2h_dev_tools/change_scope.py,sha256=Ozrgys6MKEpdSa9awtWdH3JKzJN7E8uBHNwhSbgYt_w,5641
7
+ h2h_dev_tools/ci_dependencies.py,sha256=-tr3qoWFLrTkO2DP3dvlroh0Pa0VdGcpQX2re2piOFM,2251
8
+ h2h_dev_tools/dependency_audit.py,sha256=umtq_GZk8VBTj_ncbgbYN8NBkB7A_6GxojZTsXeytus,7325
9
+ h2h_dev_tools/dependency_manifest.py,sha256=s6LS2bcXQc1xCkd_HKQe0nh4hZCAFubsB4xbRt9du2I,748
10
+ h2h_dev_tools/distribution_check.py,sha256=FexIx7KocV2ZEDCemRnNhYerXUo9Y-R_lriy18LeYpQ,2675
11
+ h2h_dev_tools/documentation.py,sha256=xUyVxyEHlnz9KITPdVJ1TqkoMCFI8580cRdGH0ofA8I,7199
12
+ h2h_dev_tools/formal.py,sha256=w83O3pMavG6wmPZUYC4ykvDsZHnV2VOc5FIe1GmAlrM,7517
13
+ h2h_dev_tools/git-flow-merge.sh,sha256=axjmelrmDwS6Y_ChnpYuiGE9bZ2cfwXo2yefJ7s39z8,8844
14
+ h2h_dev_tools/install-git-hooks.sh,sha256=Dq0OwtxYOHI2sMZ1r1zRsPWypzNXgc8WAHpsQHAfjOw,1195
15
+ h2h_dev_tools/migrate_v1.py,sha256=Fv20cgJZODZmTADS7sD_NMGooCQr34jGQ2ehxWTjGGA,1867
16
+ h2h_dev_tools/offline_wheel.py,sha256=JP_PinRiCgi6FS54uGWsCkoMKN4VLdzVyJlfb5mMyMc,4665
17
+ h2h_dev_tools/primary-branch.sh,sha256=YC8sY2WeELbcg1_EAmv5Nx2d7x_LScvb-r5_t7TXaqU,1335
18
+ h2h_dev_tools/process.py,sha256=gcd4r5KZeU1WgH9xmsgVaf6ld6zHplJHDEpGgiD7FLw,30594
19
+ h2h_dev_tools/publish_version.py,sha256=6LtAVGzvsNqPgt7g7zPquA7cOq4HTAAVlp9CcTOC9IE,3297
20
+ h2h_dev_tools/rebuild-env.sh,sha256=ynaDTXKQ0qMMpkiLqVLS-UWPQyl-vt9MSitazbQs-Rc,2268
21
+ h2h_dev_tools/version_policy.py,sha256=Hsdo8NzvCdUxumQK_ocgQhfAIuUouoBI6UReams9dtY,14555
22
+ h2h_dev_tools-0.2.1.dist-info/METADATA,sha256=Z3fn9ms1HIkM0_nDI2G7XgvL4nvJXpMOVRhePgvqJpY,10901
23
+ h2h_dev_tools-0.2.1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
24
+ h2h_dev_tools-0.2.1.dist-info/entry_points.txt,sha256=zmRCf22OP2D7yY3jh9Yr8636gJawoQ9DZqK30H9Ipmo,62
25
+ h2h_dev_tools-0.2.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
26
+ h2h_dev_tools-0.2.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ h2h-dev-tools = h2h_dev_tools.__main__:main