headlamp 0.1.60__py3-none-macosx_11_0_arm64.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.
headlamp/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ """
2
+ PyPI wrapper for the Headlamp CLI.
3
+
4
+ The `headlamp` console entrypoint executes a bundled platform binary located at:
5
+ `headlamp/bin/headlamp` or `headlamp/bin/headlamp.exe`.
6
+ """
headlamp/_bin.py ADDED
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import platform
5
+ from pathlib import Path
6
+
7
+ try:
8
+ # Python 3.9+
9
+ from importlib import resources as importlib_resources # type: ignore
10
+ except Exception: # pragma: no cover
11
+ import importlib_resources # type: ignore
12
+
13
+
14
+ _OVERRIDE_ENV = "HEADLAMP_PYPI_BIN_OVERRIDE"
15
+
16
+
17
+ def _default_binary_resource_name() -> str:
18
+ return "headlamp.exe" if platform.system().lower().startswith("win") else "headlamp"
19
+
20
+
21
+ def get_binary_path() -> Path:
22
+ """
23
+ Returns the absolute path to the bundled `headlamp` binary.
24
+
25
+ Test override:
26
+ - If `HEADLAMP_PYPI_BIN_OVERRIDE` is set, that path is used (if it exists).
27
+ """
28
+
29
+ override = os.environ.get(_OVERRIDE_ENV, "").strip()
30
+ if override:
31
+ p = Path(override).expanduser()
32
+ if not p.is_absolute():
33
+ p = (Path.cwd() / p).resolve()
34
+ if not p.exists():
35
+ raise FileNotFoundError(
36
+ f"headlamp (PyPI): override binary not found at {_OVERRIDE_ENV}={p}"
37
+ )
38
+ return p
39
+
40
+ resource_name = _default_binary_resource_name()
41
+
42
+ try:
43
+ # pkg is headlamp.bin (a namespace for resources)
44
+ bin_dir = importlib_resources.files("headlamp").joinpath("bin")
45
+ candidate = bin_dir.joinpath(resource_name)
46
+ candidate_path = Path(str(candidate))
47
+ except Exception as e: # pragma: no cover
48
+ raise FileNotFoundError(
49
+ "headlamp (PyPI): could not resolve bundled binary resources"
50
+ ) from e
51
+
52
+ if not candidate_path.exists():
53
+ raise FileNotFoundError(_missing_binary_message(candidate_path))
54
+ return candidate_path
55
+
56
+
57
+ def _missing_binary_message(expected_path: Path) -> str:
58
+ return (
59
+ "headlamp (PyPI): bundled headlamp binary not found.\n"
60
+ f"Expected at: {expected_path}\n\n"
61
+ "This usually means you installed an sdist (source distribution) or a wheel for a\n"
62
+ "different platform.\n\n"
63
+ "Fix:\n"
64
+ " - Reinstall wheels only: pip install --only-binary :all: headlamp\n"
65
+ )
66
+
headlamp/_cli.py ADDED
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import subprocess
5
+ import sys
6
+
7
+ from ._bin import get_binary_path
8
+
9
+
10
+ def main() -> None:
11
+ try:
12
+ bin_path = get_binary_path()
13
+ except FileNotFoundError as e:
14
+ sys.stderr.write(str(e).rstrip() + os.linesep)
15
+ raise SystemExit(1)
16
+
17
+ argv = [str(bin_path), *sys.argv[1:]]
18
+ try:
19
+ completed = subprocess.run(argv)
20
+ except FileNotFoundError:
21
+ sys.stderr.write(f"headlamp (PyPI): failed to execute: {bin_path}{os.linesep}")
22
+ raise SystemExit(1)
23
+
24
+ raise SystemExit(completed.returncode)
25
+
headlamp/bin/headlamp ADDED
Binary file
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: headlamp
3
+ Version: 0.1.60
4
+ Summary: Dependency-graph based test runner in Rust that supports Rust, Python, and JavaScript.
5
+ Author: David Piper
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/dbpiper/headlamp
8
+ Project-URL: Repository, https://github.com/dbpiper/headlamp
9
+ Keywords: testing,cli,pytest,jest,nextest
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Headlamp
16
+
17
+ Headlamp is a **Rust-powered test UX CLI**: smarter test selection, cleaner output, and a unified workflow across **jest**, **Rust tests (headlamp runner)**, **cargo test**, **cargo nextest**, and **pytest**.
18
+
19
+ Headlamp is useful when you want a consistent way to run tests across different projects and keep feedback fast as your repo grows. It can select tests based on what changed, surface failures in a readable format, and keep common defaults (like runner args and coverage settings) in a single config file so your team doesn’t have to remember a long list of flags.
20
+
21
+ ## Why Headlamp
22
+
23
+ - **One CLI, many runners**: `--runner=headlamp|jest|cargo-nextest|cargo-test|pytest`
24
+ - **Selection that scales**: run what changed (`--changed`) and what’s related (dependency-graph driven)
25
+ - **Coverage-first UX**: coverage output you can actually read
26
+ - **Fast**: Rust core + caching
27
+
28
+ ## Installation
29
+
30
+ ### npm (Node.js projects)
31
+
32
+ Requirements:
33
+
34
+ - Node **>= 18**
35
+
36
+ Install:
37
+
38
+ ```bash
39
+ npm i -D headlamp
40
+ ```
41
+
42
+ Run:
43
+
44
+ ```bash
45
+ npx headlamp --help
46
+ ```
47
+
48
+ ### Cargo (Rust projects)
49
+
50
+ Install from crates.io:
51
+
52
+ ```bash
53
+ cargo install headlamp
54
+ ```
55
+
56
+ ### Python (pytest projects)
57
+
58
+ Install:
59
+
60
+ ```bash
61
+ pip install headlamp
62
+ ```
63
+
64
+ ```bash
65
+ headlamp --runner=pytest
66
+ ```
67
+
68
+ ## Peer dependencies (system requirements)
69
+
70
+ Headlamp is a wrapper around your project’s runners. It does **not** vendor the runners themselves, so you need the runner executables available in your environment for the features you’re using.
71
+
72
+ ### Common (all runners)
73
+
74
+ - **Git**: required for `--changed=...` modes (e.g. `--changed=branch`).
75
+
76
+ ### Jest runner (`--runner=jest`)
77
+
78
+ - **Node.js**: required.
79
+ - **Jest installed in the repo**: Headlamp expects Jest to be runnable from your project (typically `./node_modules/.bin/jest`).
80
+ - **Coverage** (`--coverage`): requires Jest coverage support (standard Jest `--coverage` + reporters). Headlamp formats/prints coverage from generated reports.
81
+
82
+ ### Pytest runner (`--runner=pytest`)
83
+
84
+ - **Python 3**: required.
85
+ - **pytest**: must be on `PATH` (`pytest` / `pytest.exe`).
86
+ - **Coverage** (`--coverage`): requires `pytest-cov` (Headlamp enables coverage and passes `--cov` flags; branch coverage uses `--cov-branch`).
87
+
88
+ ### Headlamp (native Rust runner) (`--runner=headlamp`)
89
+
90
+ - **Rust toolchain**: `cargo` + `rustc`.
91
+ - **Per-test timings**: requires a preinstalled nightly toolchain (Headlamp enables libtest JSON + `--report-time` only when nightly is available).
92
+ - Install via: `rustup toolchain install nightly`
93
+
94
+ ### Cargo test runner (`--runner=cargo-test`)
95
+
96
+ - **Rust toolchain**: `cargo` + `rustc`.
97
+ - **Coverage** (`--coverage`): collected via LLVM tools from `rustup` (**no `cargo-llvm-cov` dependency**).
98
+ - Install via: `rustup component add llvm-tools-preview`
99
+
100
+ ### Cargo nextest runner (`--runner=cargo-nextest`)
101
+
102
+ - **Rust toolchain**: `cargo` + `rustc`.
103
+ - **nextest**: requires **`cargo-nextest`** (`cargo install cargo-nextest`).
104
+ - **Coverage** (`--coverage`): collected via LLVM tools from `rustup` (**no `cargo-llvm-cov` dependency**).
105
+ - Install via: `rustup component add llvm-tools-preview`
106
+
107
+ ## Quickstart
108
+
109
+ ### Jest
110
+
111
+ ```bash
112
+ npx headlamp --runner=jest
113
+ ```
114
+
115
+ Forward runner args after `--` (unknown args are forwarded):
116
+
117
+ ```bash
118
+ npx headlamp --runner=jest -- --runInBand
119
+ ```
120
+
121
+ ### Cargo nextest / cargo test
122
+
123
+ ```bash
124
+ headlamp --runner=cargo-nextest
125
+ headlamp --runner=cargo-test
126
+ ```
127
+
128
+ Requirements:
129
+
130
+ - `--runner=cargo-nextest`: requires `cargo-nextest` to be installed.
131
+ - Install via: `cargo install cargo-nextest` (or your preferred installer)
132
+
133
+ ## CLI
134
+
135
+ Run `headlamp --help` to see the up-to-date flags list.
136
+
137
+ Highlights:
138
+
139
+ - **runners**: `--runner=headlamp|jest|pytest|cargo-nextest|cargo-test`
140
+ - **changed selection**: `--changed=all|staged|unstaged|branch|lastCommit|lastRelease`
141
+ - `lastRelease` selects changes since the previous stable SemVer release tag
142
+ - **coverage**: `--coverage` plus `--coverage-ui`, `--coverage-detail`, thresholds, etc.
143
+ - **artifacts** (default: none): `--keep-artifacts` to keep runner artifacts on disk
144
+
145
+ Legacy aliases (still accepted, but not recommended):
146
+
147
+ - `--keepArtifacts`
148
+ - `--coverage.detail`
149
+
150
+ ## Configuration
151
+
152
+ Headlamp discovers config from your repo root. Supported file names:
153
+
154
+ - `headlamp.toml` (highest precedence)
155
+ - `headlamp.config.ts`
156
+ - `headlamp.config.js`
157
+ - `headlamp.config.mjs`
158
+ - `headlamp.config.cjs`
159
+ - `headlamp.config.json`
160
+ - `headlamp.config.json5`
161
+ - `headlamp.config.jsonc`
162
+ - `headlamp.config.yaml`
163
+ - `headlamp.config.yml`
164
+ - `.headlamprc` plus `.headlamprc.*` variants (`.json`, `.json5`, `.jsonc`, `.yaml`, `.yml`, `.js`, `.cjs`, `.mjs`, `.ts`)
165
+
166
+ Headlamp also supports embedded TOML config (lower precedence than explicit config files):
167
+
168
+ - `pyproject.toml` under `[tool.headlamp]`
169
+ - `Cargo.toml` under `[package.metadata.headlamp]`
170
+
171
+ ### Example: `headlamp.toml` (recommended for Rust + Python)
172
+
173
+ ```toml
174
+ # Run tests sequentially (useful for very heavy integration tests)
175
+ sequential = true
176
+
177
+ [coverage]
178
+ abort_on_failure = true
179
+ mode = "auto"
180
+ page_fit = true
181
+ keep_artifacts = false
182
+
183
+ [changed]
184
+ depth = 20
185
+ ```
186
+
187
+ ### Example: `headlamp.config.ts`
188
+
189
+ Rules:
190
+
191
+ - Must have a **default export**
192
+ - Only **relative imports** are supported inside the config file (`./` and `../`)
193
+
194
+ ```ts
195
+ export default {
196
+ // Runner defaults
197
+ jestArgs: ["--runInBand"],
198
+
199
+ // Run once before tests (npm script name or a shell command)
200
+ bootstrapCommand: "test:jest:bootstrap",
201
+
202
+ // Global toggles
203
+ ci: false,
204
+ verbose: false,
205
+ noCache: false,
206
+ keepArtifacts: false,
207
+
208
+ // Coverage defaults
209
+ coverage: true,
210
+ coverageUi: "both",
211
+ coverage: {
212
+ abortOnFailure: true,
213
+ mode: "auto",
214
+ pageFit: true,
215
+ },
216
+
217
+ // Changed selection defaults
218
+ changed: { depth: 2 },
219
+ };
220
+ ```
221
+
222
+ ## Artifacts (coverage, caches, temp files)
223
+
224
+ By default, headlamp runs **artifact-free**: it uses an ephemeral per-run workspace and **does not leave files behind** in your repo (e.g. `coverage/`, `.coverage`, `.pytest_cache`, `target/`) or OS temp.
225
+
226
+ If you need artifacts on disk (for example, to upload coverage reports in CI), opt out:
227
+
228
+ - CLI: `--keep-artifacts`
229
+ - Config: `keepArtifacts: true`
230
+
231
+ ## Contributing
232
+
233
+ Pull requests are welcome. For large changes, open an issue first to align on direction.
234
+
235
+ ## Support
236
+
237
+ - Bug reports and feature requests: GitHub Issues
238
+
239
+ ## License
240
+
241
+ MIT — see `LICENSE`.
@@ -0,0 +1,9 @@
1
+ headlamp-0.1.60.dist-info/RECORD,,
2
+ headlamp-0.1.60.dist-info/WHEEL,sha256=0wJZkrMXhHamlhyeyzwHZC6TVoCduvm5-sXAkwO3M0I,133
3
+ headlamp-0.1.60.dist-info/entry_points.txt,sha256=LGS3na55nE6Ut1Es24pTJn6KNgz3UOiNTYZRE2urwgU,48
4
+ headlamp-0.1.60.dist-info/top_level.txt,sha256=eRZTjDhtIwmMCPa_qwcrLUl5OgT0gNtzjq58QS569K0,9
5
+ headlamp-0.1.60.dist-info/METADATA,sha256=36AzlYrRL-TTYNJMPbdWqsk5ccsUYQ-BSFY8wZfqElU,6843
6
+ headlamp/_cli.py,sha256=q9ihu8IP0E5aNjgS4l4TRaP7GNhzpkiRPn8E-Ye9iQM,580
7
+ headlamp/__init__.py,sha256=it3ellGUCNveQ94VrupKnDtN-5KiThF3eIhCO27V14U,181
8
+ headlamp/_bin.py,sha256=IaqveR8dNiphXcQcsR5DeS0h4O8X-8TN_062qNZIo_o,2045
9
+ headlamp/bin/headlamp,sha256=hHdDgMRSHc-xi9cP-v1FEOU1SLlLyEt5711gGBGwbYM,5082672
@@ -0,0 +1,6 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-macosx_11_0_arm64
5
+ Generator: delocate 0.13.0
6
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ headlamp = headlamp._cli:main
@@ -0,0 +1 @@
1
+ headlamp