repofail 0.2.3__tar.gz → 0.2.5__tar.gz

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.
Files changed (61) hide show
  1. repofail-0.2.5/.gitignore +22 -0
  2. {repofail-0.2.3 → repofail-0.2.5}/Formula/repofail.rb +6 -4
  3. repofail-0.2.3/README.md → repofail-0.2.5/PKG-INFO +125 -10
  4. repofail-0.2.3/PKG-INFO → repofail-0.2.5/README.md +106 -23
  5. {repofail-0.2.3 → repofail-0.2.5}/pyproject.toml +12 -1
  6. repofail-0.2.5/repofail/__init__.py +8 -0
  7. repofail-0.2.3/.gitignore +0 -8
  8. repofail-0.2.3/repofail/__init__.py +0 -3
  9. {repofail-0.2.3 → repofail-0.2.5}/.github/workflows/publish.yml +0 -0
  10. {repofail-0.2.3 → repofail-0.2.5}/.github/workflows/repofail.yml +0 -0
  11. {repofail-0.2.3 → repofail-0.2.5}/CONTRIBUTING.md +0 -0
  12. {repofail-0.2.3 → repofail-0.2.5}/RULES.md +0 -0
  13. {repofail-0.2.3 → repofail-0.2.5}/contract.json +0 -0
  14. {repofail-0.2.3 → repofail-0.2.5}/docs/assets/demo-autogpt.png +0 -0
  15. {repofail-0.2.3 → repofail-0.2.5}/docs/assets/repofail-logo.png +0 -0
  16. {repofail-0.2.3 → repofail-0.2.5}/docs/logo.png +0 -0
  17. {repofail-0.2.3 → repofail-0.2.5}/docs/screenshots/high_failure.png +0 -0
  18. {repofail-0.2.3 → repofail-0.2.5}/docs/screenshots/nodefail.gif +0 -0
  19. {repofail-0.2.3 → repofail-0.2.5}/repofail/cli.py +0 -0
  20. {repofail-0.2.3 → repofail-0.2.5}/repofail/contract.py +0 -0
  21. {repofail-0.2.3 → repofail-0.2.5}/repofail/engine.py +0 -0
  22. {repofail-0.2.3 → repofail-0.2.5}/repofail/fleet.py +0 -0
  23. {repofail-0.2.3 → repofail-0.2.5}/repofail/format.py +0 -0
  24. {repofail-0.2.3 → repofail-0.2.5}/repofail/models.py +0 -0
  25. {repofail-0.2.3 → repofail-0.2.5}/repofail/risk.py +0 -0
  26. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/__init__.py +0 -0
  27. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/abi_wheel_mismatch.py +0 -0
  28. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/apple_silicon.py +0 -0
  29. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/base.py +0 -0
  30. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/docker_only.py +0 -0
  31. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/gpu_memory.py +0 -0
  32. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/info_signals.py +0 -0
  33. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/lock_file_missing.py +0 -0
  34. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/ml_niche.py +0 -0
  35. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/native_toolchain.py +0 -0
  36. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/node_engine.py +0 -0
  37. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/node_eol.py +0 -0
  38. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/node_windows.py +0 -0
  39. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/port_collision.py +0 -0
  40. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/python_eol.py +0 -0
  41. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/python_version.py +0 -0
  42. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/registry.py +0 -0
  43. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/spec_drift.py +0 -0
  44. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/system_libs.py +0 -0
  45. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/torch_cuda.py +0 -0
  46. {repofail-0.2.3 → repofail-0.2.5}/repofail/rules/yaml_loader.py +0 -0
  47. {repofail-0.2.3 → repofail-0.2.5}/repofail/scanner/__init__.py +0 -0
  48. {repofail-0.2.3 → repofail-0.2.5}/repofail/scanner/ast_scan.py +0 -0
  49. {repofail-0.2.3 → repofail-0.2.5}/repofail/scanner/host.py +0 -0
  50. {repofail-0.2.3 → repofail-0.2.5}/repofail/scanner/parsers.py +0 -0
  51. {repofail-0.2.3 → repofail-0.2.5}/repofail/scanner/repo.py +0 -0
  52. {repofail-0.2.3 → repofail-0.2.5}/repofail/telemetry.py +0 -0
  53. {repofail-0.2.3 → repofail-0.2.5}/tests/__init__.py +0 -0
  54. {repofail-0.2.3 → repofail-0.2.5}/tests/test_cli_stage2.py +0 -0
  55. {repofail-0.2.3 → repofail-0.2.5}/tests/test_contract.py +0 -0
  56. {repofail-0.2.3 → repofail-0.2.5}/tests/test_fleet.py +0 -0
  57. {repofail-0.2.3 → repofail-0.2.5}/tests/test_integration.py +0 -0
  58. {repofail-0.2.3 → repofail-0.2.5}/tests/test_ml_rules.py +0 -0
  59. {repofail-0.2.3 → repofail-0.2.5}/tests/test_rules.py +0 -0
  60. {repofail-0.2.3 → repofail-0.2.5}/tests/test_scanner.py +0 -0
  61. {repofail-0.2.3 → repofail-0.2.5}/tests/test_telemetry.py +0 -0
@@ -0,0 +1,22 @@
1
+ dist/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ *.egg-info/
6
+ .eggs/
7
+ .venv/
8
+ .venv-check/
9
+ venv/
10
+ testenv/
11
+ VISION.md
12
+ repofail-contract.json
13
+
14
+ # Sensitive / local-only (never commit)
15
+ .env
16
+ .env.local
17
+ .env.*.local
18
+ .secrets
19
+ secrets.yaml
20
+ .credentials
21
+ *.pem
22
+ .DS_Store
@@ -1,18 +1,20 @@
1
1
  # Homebrew formula for repofail
2
2
  # To use: copy to your tap repo (e.g. homebrew-tap/Formula/repofail.rb)
3
- # Then: brew tap jayvenn21/tap && brew install repofail
4
- # Or: brew install --formula Formula/repofail.rb (from this repo)
3
+ # Then: brew tap jayvenn21/tap && brew install jayvenn21/tap/repofail
5
4
  #
6
5
  # Homebrew uses --no-deps when installing the main package, so all Python
7
6
  # dependencies must be declared as resources below.
7
+ # If SHA256 fails after pushing a new tag, get the correct hash with:
8
+ # curl -sL https://github.com/jayvenn21/repofail/archive/refs/tags/vX.Y.Z.tar.gz | shasum -a 256
8
9
 
9
10
  class Repofail < Formula
10
11
  include Language::Python::Virtualenv
11
12
 
12
13
  desc "Deterministic runtime compatibility analyzer"
13
14
  homepage "https://github.com/jayvenn21/repofail"
14
- url "https://github.com/jayvenn21/repofail/archive/refs/tags/v0.2.2.tar.gz"
15
- sha256 "331055c40ec70a9ffb4f14f801bddf519014aaff1db1e5c0955b2f35e46da219"
15
+ url "https://github.com/jayvenn21/repofail/archive/refs/tags/v0.2.5.tar.gz"
16
+ # Replace with v0.2.5 tarball SHA after tagging: curl -sL https://github.com/jayvenn21/repofail/archive/refs/tags/v0.2.5.tar.gz | shasum -a 256
17
+ sha256 "d5558cd419c8d46bdc958064cb97f963d1ea793866414c025906ec15033512ed"
16
18
  license "MIT"
17
19
 
18
20
  # App supports Python 3.10+. We use 3.12 for current Homebrew; change to
@@ -1,5 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: repofail
3
+ Version: 0.2.5
4
+ Summary: Predict why a repository will fail on your machine before you run it.
5
+ Author: Jayanth
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: 3.10
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Programming Language :: Python :: Implementation :: CPython
12
+ Requires-Python: >=3.10
13
+ Requires-Dist: pyyaml>=6.0
14
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
15
+ Requires-Dist: typer>=0.9.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest>=7.0; extra == 'dev'
18
+ Description-Content-Type: text/markdown
19
+
1
20
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/jayvenn21/repofail/v0.2.2/docs/logo.png" width="180" alt="repofail logo">
21
+ <img src="https://raw.githubusercontent.com/jayvenn21/repofail/main/docs/logo.png" width="180" alt="repofail logo">
3
22
  </p>
4
23
 
5
24
  <h1 align="center">repofail</h1>
@@ -9,14 +28,16 @@
9
28
  </p>
10
29
 
11
30
  <p align="center">
12
- <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/v/repofail?cacheSeconds=60&cacheBust=1"></a>
13
- <img src="https://img.shields.io/badge/ci-passing-brightgreen">
14
- <img src="https://img.shields.io/badge/python-3.10+-blue">
15
- <img src="https://img.shields.io/badge/runtime-validated-success">
16
- <img src="https://img.shields.io/badge/rules-20+-informational">
31
+ <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/v/repofail" alt="PyPI"></a>
32
+ <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/pyversions/repofail" alt="Python"></a>
33
+ <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/dm/repofail" alt="Downloads"></a>
34
+ <a href="https://github.com/jayvenn21/repofail/actions"><img src="https://img.shields.io/github/actions/workflow/status/jayvenn21/repofail/repofail.yml?branch=main" alt="CI"></a>
35
+ <img src="https://img.shields.io/badge/runtime-validated-brightgreen" alt="Runtime">
36
+ <img src="https://img.shields.io/badge/rules-20%2B-blue" alt="Rules">
17
37
  </p>
18
38
 
19
39
  <p align="center">
40
+ <strong>The static analyzer for runtime compatibility.</strong><br>
20
41
  Predict why a repository will fail on your machine before you run it.
21
42
  </p>
22
43
 
@@ -33,11 +54,24 @@
33
54
  <a href="#usage">Usage</a> ·
34
55
  <a href="#rules">Rules</a> ·
35
56
  <a href="#ci-integration">CI</a> ·
36
- <a href="#contracts">Contracts</a>
57
+ <a href="#contracts">Contracts</a> ·
58
+ <a href="#faq">FAQ</a>
37
59
  </p>
38
60
 
39
61
  ---
40
62
 
63
+ ## Quickstart (30 seconds)
64
+
65
+ ```bash
66
+ pip install repofail
67
+ cd /path/to/any/repo
68
+ repofail
69
+ ```
70
+
71
+ You get a compatibility score and a list of deterministic blockers (Node version, Python range, CUDA, lock file, spec drift, etc.). No install of the repo’s dependencies. No cloud. No AI.
72
+
73
+ ---
74
+
41
75
  ## Why This Exists
42
76
 
43
77
  Most tools install dependencies.
@@ -70,13 +104,25 @@ Run it against any local clone.
70
104
  ## Example output
71
105
 
72
106
  <p align="center">
73
- <img src="https://raw.githubusercontent.com/jayvenn21/repofail/v0.2.2/docs/screenshots/nodefail.gif" width="850" alt="Node engine mismatch demo">
107
+ <img src="https://raw.githubusercontent.com/jayvenn21/repofail/main/docs/screenshots/nodefail.gif" width="850" alt="Node engine mismatch demo">
74
108
  </p>
75
109
 
76
110
  Deterministic spec violation detected — engines.node requires 22.x, host is 20.x.
77
111
 
78
112
  ---
79
113
 
114
+ ## Case studies
115
+
116
+ | Scenario | Without repofail | With repofail |
117
+ |----------|------------------|----------------|
118
+ | **Node engine mismatch** | Clone → `npm install` → `EBADENGINE` → search, fix, retry | `repofail .` → "Node 22.x required, host is 20.x" + suggested fix in &lt;1s |
119
+ | **CUDA on laptop** | Clone → `pip install` → run → `RuntimeError: CUDA unavailable` | `repofail .` → "Hard-coded CUDA path, host has no GPU" before you run |
120
+ | **Spec drift (Python)** | CI passes, local fails; pyproject says 3.11, Docker uses 3.9 | `repofail .` → "Spec drift — 3 distinct Python targets" + where they differ |
121
+
122
+ Try the demos: [node engine](https://github.com/jayvenn21/repofail-demo-node-engine), [spec drift](https://github.com/jayvenn21/repofail-demo-spec-drift), [CUDA hardcoded](https://github.com/jayvenn21/repofail-demo-cuda-hardcoded).
123
+
124
+ ---
125
+
80
126
  ## Install
81
127
 
82
128
  **From PyPI (recommended)**
@@ -85,12 +131,25 @@ Deterministic spec violation detected — engines.node requires 22.x, host is 20
85
131
  pip install repofail
86
132
  ```
87
133
 
88
- Or with pipx (isolated CLI install):
134
+ **One-liner (curl)**
135
+
136
+ ```bash
137
+ curl -sSL https://raw.githubusercontent.com/jayvenn21/repofail/main/install.sh | bash
138
+ ```
139
+
140
+ **pipx (isolated CLI)**
89
141
 
90
142
  ```bash
91
143
  pipx install repofail
92
144
  ```
93
145
 
146
+ **Homebrew** (formula: [jayvenn21/homebrew-tap](https://github.com/jayvenn21/homebrew-tap))
147
+
148
+ ```bash
149
+ brew tap jayvenn21/tap
150
+ brew install jayvenn21/tap/repofail
151
+ ```
152
+
94
153
  **From source (development)**
95
154
 
96
155
  ```bash
@@ -139,6 +198,31 @@ repofail s -j # Stats with JSON output
139
198
 
140
199
  ## CI integration
141
200
 
201
+ **Option A — Reusable action (comment on PR + fail CI)**
202
+
203
+ ```yaml
204
+ name: repofail
205
+ on:
206
+ pull_request:
207
+ branches: [main, master]
208
+ jobs:
209
+ check:
210
+ runs-on: ubuntu-latest
211
+ steps:
212
+ - uses: actions/checkout@v4
213
+ - uses: jayvenn21/repofail/.github/actions/repofail@main
214
+ with:
215
+ path: .
216
+ fail_on: HIGH
217
+ comment: 'true'
218
+ upload_artifact: 'true'
219
+ pr_number: ${{ github.event.pull_request.number }}
220
+ ```
221
+
222
+ The action installs repofail, runs a compatibility check, comments the Markdown report on the PR, uploads the JSON artifact, and fails the job if violations meet the threshold.
223
+
224
+ **Option B — Inline (no comment)**
225
+
142
226
  ```yaml
143
227
  - uses: actions/checkout@v4
144
228
  - uses: actions/setup-python@v5
@@ -157,7 +241,7 @@ repofail gen . -o contract.json
157
241
  repofail check contract.json
158
242
  ```
159
243
 
160
- Versioned runtime expectations. Teams share contracts. CI checks drift.
244
+ Versioned runtime expectations. Teams share contracts. CI checks drift. Generated contracts report the installed repofail version (from PyPI/Homebrew) so tooling stays traceable.
161
245
 
162
246
  ---
163
247
 
@@ -230,8 +314,39 @@ Extensible via `.repofail/rules.yaml`.
230
314
 
231
315
  ---
232
316
 
317
+ ## FAQ
318
+
319
+ **Does repofail install or run my project?**
320
+ No. It only reads configs and (optionally) inspects Python/JS for patterns. No `pip install`, no `npm install`, no execution.
321
+
322
+ **Does it need the internet?**
323
+ No. It runs fully offline. Host inspection uses local subprocesses (e.g. `node --version`).
324
+
325
+ **Why “deterministic”?**
326
+ Same repo + same host → same result. No ML, no heuristics that change between runs. Rules are based on config and code.
327
+
328
+ **Can I add my own rules?**
329
+ Yes. Put a `.repofail/rules.yaml` (or `repofail-rules.yaml`) in the repo and define conditions on `repo.*` and `host.*`. See `repofail -e list` for built-in rule IDs.
330
+
331
+ **What if my repo is clean?**
332
+ You get a high score (e.g. 96–100%) and “No deterministic blockers detected.” repofail does not invent problems.
333
+
334
+ ---
335
+
336
+ ## When not to use it
337
+
338
+ - **You need dependency resolution** — use pip, npm, poetry, etc. repofail does not install or resolve.
339
+ - **You need security scanning** — use Dependabot, Snyk, or similar. repofail is compatibility-only.
340
+ - **You want “AI suggested fixes”** — repofail gives deterministic, rule-based suggestions only.
341
+ - **You run only in one environment** — if every dev and CI use the same OS/runtime, the value is smaller (still useful for drift and contracts).
342
+
343
+ ---
344
+
233
345
  ## Testing
234
346
 
235
347
  ```bash
348
+ pip install -e ".[dev]"
236
349
  pytest tests/ -v
237
350
  ```
351
+
352
+ **Quick checks:** `bash -n install.sh` (syntax). The GitHub Action runs on every PR in this repo (see [.github/workflows/repofail.yml](.github/workflows/repofail.yml)); to test the reusable action, use it in another repo’s workflow on a PR.
@@ -1,18 +1,5 @@
1
- Metadata-Version: 2.4
2
- Name: repofail
3
- Version: 0.2.3
4
- Summary: Predict why a repository will fail on your machine before you run it.
5
- Author: Jayanth
6
- Requires-Python: >=3.10
7
- Requires-Dist: pyyaml>=6.0
8
- Requires-Dist: tomli>=2.0; python_version < '3.11'
9
- Requires-Dist: typer>=0.9.0
10
- Provides-Extra: dev
11
- Requires-Dist: pytest>=7.0; extra == 'dev'
12
- Description-Content-Type: text/markdown
13
-
14
1
  <p align="center">
15
- <img src="https://raw.githubusercontent.com/jayvenn21/repofail/v0.2.2/docs/logo.png" width="180" alt="repofail logo">
2
+ <img src="https://raw.githubusercontent.com/jayvenn21/repofail/main/docs/logo.png" width="180" alt="repofail logo">
16
3
  </p>
17
4
 
18
5
  <h1 align="center">repofail</h1>
@@ -22,14 +9,16 @@ Description-Content-Type: text/markdown
22
9
  </p>
23
10
 
24
11
  <p align="center">
25
- <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/v/repofail?cacheSeconds=60&cacheBust=1"></a>
26
- <img src="https://img.shields.io/badge/ci-passing-brightgreen">
27
- <img src="https://img.shields.io/badge/python-3.10+-blue">
28
- <img src="https://img.shields.io/badge/runtime-validated-success">
29
- <img src="https://img.shields.io/badge/rules-20+-informational">
12
+ <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/v/repofail" alt="PyPI"></a>
13
+ <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/pyversions/repofail" alt="Python"></a>
14
+ <a href="https://pypi.org/project/repofail/"><img src="https://img.shields.io/pypi/dm/repofail" alt="Downloads"></a>
15
+ <a href="https://github.com/jayvenn21/repofail/actions"><img src="https://img.shields.io/github/actions/workflow/status/jayvenn21/repofail/repofail.yml?branch=main" alt="CI"></a>
16
+ <img src="https://img.shields.io/badge/runtime-validated-brightgreen" alt="Runtime">
17
+ <img src="https://img.shields.io/badge/rules-20%2B-blue" alt="Rules">
30
18
  </p>
31
19
 
32
20
  <p align="center">
21
+ <strong>The static analyzer for runtime compatibility.</strong><br>
33
22
  Predict why a repository will fail on your machine before you run it.
34
23
  </p>
35
24
 
@@ -46,11 +35,24 @@ Description-Content-Type: text/markdown
46
35
  <a href="#usage">Usage</a> ·
47
36
  <a href="#rules">Rules</a> ·
48
37
  <a href="#ci-integration">CI</a> ·
49
- <a href="#contracts">Contracts</a>
38
+ <a href="#contracts">Contracts</a> ·
39
+ <a href="#faq">FAQ</a>
50
40
  </p>
51
41
 
52
42
  ---
53
43
 
44
+ ## Quickstart (30 seconds)
45
+
46
+ ```bash
47
+ pip install repofail
48
+ cd /path/to/any/repo
49
+ repofail
50
+ ```
51
+
52
+ You get a compatibility score and a list of deterministic blockers (Node version, Python range, CUDA, lock file, spec drift, etc.). No install of the repo’s dependencies. No cloud. No AI.
53
+
54
+ ---
55
+
54
56
  ## Why This Exists
55
57
 
56
58
  Most tools install dependencies.
@@ -83,13 +85,25 @@ Run it against any local clone.
83
85
  ## Example output
84
86
 
85
87
  <p align="center">
86
- <img src="https://raw.githubusercontent.com/jayvenn21/repofail/v0.2.2/docs/screenshots/nodefail.gif" width="850" alt="Node engine mismatch demo">
88
+ <img src="https://raw.githubusercontent.com/jayvenn21/repofail/main/docs/screenshots/nodefail.gif" width="850" alt="Node engine mismatch demo">
87
89
  </p>
88
90
 
89
91
  Deterministic spec violation detected — engines.node requires 22.x, host is 20.x.
90
92
 
91
93
  ---
92
94
 
95
+ ## Case studies
96
+
97
+ | Scenario | Without repofail | With repofail |
98
+ |----------|------------------|----------------|
99
+ | **Node engine mismatch** | Clone → `npm install` → `EBADENGINE` → search, fix, retry | `repofail .` → "Node 22.x required, host is 20.x" + suggested fix in &lt;1s |
100
+ | **CUDA on laptop** | Clone → `pip install` → run → `RuntimeError: CUDA unavailable` | `repofail .` → "Hard-coded CUDA path, host has no GPU" before you run |
101
+ | **Spec drift (Python)** | CI passes, local fails; pyproject says 3.11, Docker uses 3.9 | `repofail .` → "Spec drift — 3 distinct Python targets" + where they differ |
102
+
103
+ Try the demos: [node engine](https://github.com/jayvenn21/repofail-demo-node-engine), [spec drift](https://github.com/jayvenn21/repofail-demo-spec-drift), [CUDA hardcoded](https://github.com/jayvenn21/repofail-demo-cuda-hardcoded).
104
+
105
+ ---
106
+
93
107
  ## Install
94
108
 
95
109
  **From PyPI (recommended)**
@@ -98,12 +112,25 @@ Deterministic spec violation detected — engines.node requires 22.x, host is 20
98
112
  pip install repofail
99
113
  ```
100
114
 
101
- Or with pipx (isolated CLI install):
115
+ **One-liner (curl)**
116
+
117
+ ```bash
118
+ curl -sSL https://raw.githubusercontent.com/jayvenn21/repofail/main/install.sh | bash
119
+ ```
120
+
121
+ **pipx (isolated CLI)**
102
122
 
103
123
  ```bash
104
124
  pipx install repofail
105
125
  ```
106
126
 
127
+ **Homebrew** (formula: [jayvenn21/homebrew-tap](https://github.com/jayvenn21/homebrew-tap))
128
+
129
+ ```bash
130
+ brew tap jayvenn21/tap
131
+ brew install jayvenn21/tap/repofail
132
+ ```
133
+
107
134
  **From source (development)**
108
135
 
109
136
  ```bash
@@ -152,6 +179,31 @@ repofail s -j # Stats with JSON output
152
179
 
153
180
  ## CI integration
154
181
 
182
+ **Option A — Reusable action (comment on PR + fail CI)**
183
+
184
+ ```yaml
185
+ name: repofail
186
+ on:
187
+ pull_request:
188
+ branches: [main, master]
189
+ jobs:
190
+ check:
191
+ runs-on: ubuntu-latest
192
+ steps:
193
+ - uses: actions/checkout@v4
194
+ - uses: jayvenn21/repofail/.github/actions/repofail@main
195
+ with:
196
+ path: .
197
+ fail_on: HIGH
198
+ comment: 'true'
199
+ upload_artifact: 'true'
200
+ pr_number: ${{ github.event.pull_request.number }}
201
+ ```
202
+
203
+ The action installs repofail, runs a compatibility check, comments the Markdown report on the PR, uploads the JSON artifact, and fails the job if violations meet the threshold.
204
+
205
+ **Option B — Inline (no comment)**
206
+
155
207
  ```yaml
156
208
  - uses: actions/checkout@v4
157
209
  - uses: actions/setup-python@v5
@@ -170,7 +222,7 @@ repofail gen . -o contract.json
170
222
  repofail check contract.json
171
223
  ```
172
224
 
173
- Versioned runtime expectations. Teams share contracts. CI checks drift.
225
+ Versioned runtime expectations. Teams share contracts. CI checks drift. Generated contracts report the installed repofail version (from PyPI/Homebrew) so tooling stays traceable.
174
226
 
175
227
  ---
176
228
 
@@ -243,8 +295,39 @@ Extensible via `.repofail/rules.yaml`.
243
295
 
244
296
  ---
245
297
 
298
+ ## FAQ
299
+
300
+ **Does repofail install or run my project?**
301
+ No. It only reads configs and (optionally) inspects Python/JS for patterns. No `pip install`, no `npm install`, no execution.
302
+
303
+ **Does it need the internet?**
304
+ No. It runs fully offline. Host inspection uses local subprocesses (e.g. `node --version`).
305
+
306
+ **Why “deterministic”?**
307
+ Same repo + same host → same result. No ML, no heuristics that change between runs. Rules are based on config and code.
308
+
309
+ **Can I add my own rules?**
310
+ Yes. Put a `.repofail/rules.yaml` (or `repofail-rules.yaml`) in the repo and define conditions on `repo.*` and `host.*`. See `repofail -e list` for built-in rule IDs.
311
+
312
+ **What if my repo is clean?**
313
+ You get a high score (e.g. 96–100%) and “No deterministic blockers detected.” repofail does not invent problems.
314
+
315
+ ---
316
+
317
+ ## When not to use it
318
+
319
+ - **You need dependency resolution** — use pip, npm, poetry, etc. repofail does not install or resolve.
320
+ - **You need security scanning** — use Dependabot, Snyk, or similar. repofail is compatibility-only.
321
+ - **You want “AI suggested fixes”** — repofail gives deterministic, rule-based suggestions only.
322
+ - **You run only in one environment** — if every dev and CI use the same OS/runtime, the value is smaller (still useful for drift and contracts).
323
+
324
+ ---
325
+
246
326
  ## Testing
247
327
 
248
328
  ```bash
329
+ pip install -e ".[dev]"
249
330
  pytest tests/ -v
250
331
  ```
332
+
333
+ **Quick checks:** `bash -n install.sh` (syntax). The GitHub Action runs on every PR in this repo (see [.github/workflows/repofail.yml](.github/workflows/repofail.yml)); to test the reusable action, use it in another repo’s workflow on a PR.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "repofail"
7
- version = "0.2.3"
7
+ version = "0.2.5"
8
8
  description = "Predict why a repository will fail on your machine before you run it."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -14,6 +14,14 @@ dependencies = [
14
14
  "tomli>=2.0; python_version < '3.11'",
15
15
  "pyyaml>=6.0",
16
16
  ]
17
+ classifiers = [
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: Implementation :: CPython",
24
+ ]
17
25
 
18
26
  [project.scripts]
19
27
  repofail = "repofail.cli:_main"
@@ -23,3 +31,6 @@ dev = [
23
31
  "pytest>=7.0",
24
32
  ]
25
33
 
34
+ [tool.hatch.build.targets.sdist]
35
+ exclude = [".venv-check", ".venv-check/**", "testenv", "testenv/**", ".venv", ".venv/**", "venv", "venv/**"]
36
+
@@ -0,0 +1,8 @@
1
+ """repofail — Failure-oriented repo introspection."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ try:
6
+ __version__ = version("repofail")
7
+ except PackageNotFoundError:
8
+ __version__ = "0.0.0.dev0"
repofail-0.2.3/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- dist/
2
- __pycache__/
3
- *.pyc
4
- .pytest_cache/
5
- *.egg-info/
6
- .eggs/
7
- VISION.md
8
- repofail-contract.json
@@ -1,3 +0,0 @@
1
- """repofail — Failure-oriented repo introspection."""
2
-
3
- __version__ = "0.1.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes