codepulse-cli 0.1.0__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,227 @@
1
+ Metadata-Version: 2.5
2
+ Name: codepulse-cli
3
+ Version: 0.1.0
4
+ Summary: Reveal a codebase's health from its git history — hotspots, bus factor, hidden coupling, and a CI risk gate.
5
+ Project-URL: Homepage, https://github.com/Mehouelley/codepulse
6
+ Project-URL: Repository, https://github.com/Mehouelley/codepulse
7
+ Project-URL: Issues, https://github.com/Mehouelley/codepulse/issues
8
+ Author-email: Mehouelley <fabricemehouelley43@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: code-health,code-quality,devops,git,hotspots,static-analysis,technical-debt
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Topic :: Software Development :: Quality Assurance
19
+ Classifier: Topic :: Software Development :: Version Control :: Git
20
+ Requires-Python: >=3.10
21
+ Provides-Extra: dev
22
+ Requires-Dist: build>=1.0; extra == 'dev'
23
+ Requires-Dist: pytest>=7; extra == 'dev'
24
+ Requires-Dist: twine>=5.0; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # 🩺 CodePulse
28
+
29
+ [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-CodePulse-2088FF?logo=github&logoColor=white)](https://github.com/marketplace/actions/codepulse-risk-gate)
30
+ [![tests](https://github.com/Mehouelley/codepulse/actions/workflows/tests.yml/badge.svg)](https://github.com/Mehouelley/codepulse/actions/workflows/tests.yml)
31
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
32
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
33
+ [![Zero dependencies](https://img.shields.io/badge/dependencies-none-brightgreen.svg)](pyproject.toml)
34
+
35
+ **Reveal a codebase's health from its git history.**
36
+
37
+ Linters read your code. CodePulse reads your code's *history* — and that reveals
38
+ things no linter can see: where bugs are born, what knowledge lives in one
39
+ person's head, and which files are secretly glued together.
40
+
41
+ Because it works purely from git history, **CodePulse works on any language**,
42
+ with **zero dependencies** beyond git and Python.
43
+
44
+ ---
45
+
46
+ ## Demo
47
+
48
+ <!-- Render docs/demo.gif from demo.tape with `vhs demo.tape`, then:
49
+ ![demo](docs/demo.gif) -->
50
+
51
+ ```console
52
+ $ codepulse . --badge
53
+ Grade: B (83/100)
54
+ -2 bus factor (9 fichiers à auteur unique)
55
+ -15 pression hotspots en hausse
56
+ ![code health](https://img.shields.io/badge/code%20health-B%20(83)-green)
57
+
58
+ $ codepulse . --changed origin/main
59
+ 🔴 Release risk: HIGH (100/100)
60
+ 56 changed files · 2 high-risk
61
+ [100] crates/ui-egui/src/lib.rs (hotspot majeur)
62
+ [ 70] crates/layout/src/para.rs (zone active, auteur unique)
63
+ 👥 Relecteurs suggérés: Valentin Klein (29/37 fichiers), Dmitrii Khlapov (22/37)
64
+
65
+ $ codepulse . --who crates/ui-egui/src/canvas.rs
66
+ crates/ui-egui/src/canvas.rs — 64 commits, 22 auteur(s), dernier changement 2026-10-12
67
+ 45% 29 commits Valentin Klein
68
+ 11% 7 commits Dmitrii Khlapov
69
+ ```
70
+
71
+ > A recordable [`demo.tape`](demo.tape) (for [VHS](https://github.com/charmbracelet/vhs))
72
+ > generates an animated `docs/demo.gif` of the above.
73
+
74
+ ---
75
+
76
+ ## What it shows
77
+
78
+ | Signal | Question it answers |
79
+ |---|---|
80
+ | 🔥 **Hotspots** | *Where do I refactor first?* Files that are both complex and changed constantly — the birthplace of most bugs. |
81
+ | 👥 **Bus factor** | *What breaks if someone leaves?* Files actively maintained by a single person. |
82
+ | 🔗 **Hidden coupling** | *What really depends on what?* Files that almost always change together, even when the code doesn't show a link. |
83
+ | 🏆 **Contributors** | Who is active across the analyzed window. |
84
+
85
+ The result is a single self-contained **HTML dashboard** you can open anywhere
86
+ or email to your team.
87
+
88
+ ---
89
+
90
+ ## Quick start
91
+
92
+ ```bash
93
+ # From a git repository:
94
+ python -m codepulse /path/to/repo --open
95
+
96
+ # Common options:
97
+ python -m codepulse . --since "6 months ago" --top 30 -o health.html
98
+ ```
99
+
100
+ > Running from the source checkout? Prefix with `PYTHONPATH=src`, or install it:
101
+ > `pip install -e .` then just run `codepulse`.
102
+
103
+ ### Options
104
+
105
+ | Flag | Meaning |
106
+ |---|---|
107
+ | `repo` | Path to a git repository (default: current directory) |
108
+ | `-o, --output` | Output HTML path (default: `codepulse-report.html`) |
109
+ | `--since` | Only commits after a date, e.g. `"6 months ago"` |
110
+ | `--max-count N` | Limit to the N most recent commits |
111
+ | `--top N` | Rows per table (default: 20) |
112
+ | `--open` | Open the report in a browser when done |
113
+ | `--who PATH` | Show who knows a file best (from history) and exit |
114
+ | `--badge` | Print a shields.io health-badge snippet and exit |
115
+ | `--ignore GLOB` | Exclude paths matching a glob (repeatable) |
116
+
117
+ ---
118
+
119
+ ## Use in CI (the risk gate)
120
+
121
+ CodePulse can score *only the files a change touches* against the repo's risk
122
+ map, then set an exit code so your pipeline can warn or block.
123
+
124
+ ```bash
125
+ # Score what this branch changed vs main; fail the job on HIGH risk.
126
+ python -m codepulse . --changed origin/main --fail-on HIGH
127
+
128
+ # Machine-readable output for dashboards / PR comments:
129
+ python -m codepulse . --changed origin/main --format json
130
+ ```
131
+
132
+ Output (JSON):
133
+
134
+ ```json
135
+ {
136
+ "level": "HIGH",
137
+ "score": 100,
138
+ "high_risk_count": 1,
139
+ "files": [
140
+ { "path": "auth.py", "risk": 100, "commits": 6, "loc": 7,
141
+ "reasons": ["hotspot majeur", "auteur unique (Alice)"] }
142
+ ]
143
+ }
144
+ ```
145
+
146
+ ### GitHub Action (two lines)
147
+
148
+ Add CodePulse to any repository as a reusable Action — it scores each PR, posts
149
+ a **sticky comment** (updated in place, never spammed), and fails the check on
150
+ `HIGH` risk:
151
+
152
+ ```yaml
153
+ name: CodePulse
154
+ on: pull_request
155
+ permissions:
156
+ contents: read
157
+ pull-requests: write
158
+ jobs:
159
+ risk:
160
+ runs-on: ubuntu-latest
161
+ steps:
162
+ - uses: actions/checkout@v4
163
+ with: { fetch-depth: 0 } # full history is required
164
+ - uses: Mehouelley/codepulse@v0.1.0
165
+ with:
166
+ fail-on: HIGH # or MEDIUM / LOW / '' to never fail
167
+ ```
168
+
169
+ The PR comment looks like:
170
+
171
+ > 🩺 **CodePulse — Risque : 🔴 HIGH (100/100)**
172
+ > 38 fichiers modifiés · 1 à risque élevé
173
+ >
174
+ > 👥 **Relecteurs suggérés** : Valentin Klein (29/37 fichiers), Dmitrii Khlapov (22/37)
175
+
176
+ Prefer a plain workflow with no external action? One ships in
177
+ [`.github/workflows/codepulse.yml`](.github/workflows/codepulse.yml) — copy it in as-is.
178
+
179
+ **Why DevOps cares:** a release is roughly as risky as its riskiest file.
180
+ Touching a well-known hotspot — or a file only one person understands — is
181
+ exactly where change-failure-rate (a DORA metric) comes from. The gate makes
182
+ that risk visible *before* merge, not after an incident.
183
+
184
+ ---
185
+
186
+ ## How it works
187
+
188
+ 1. Parses `git log --numstat` into commits and file changes (no merges).
189
+ 2. Accumulates per-file history: commit count, authors, size on disk.
190
+ 3. Derives the signals:
191
+ - **Hotspot score** = `commits × complexity`, where complexity estimates
192
+ decision points (branch keywords + boolean operators) — far better than
193
+ raw line count at telling "big but simple" from "dense and risky".
194
+ - **Bus factor risk** = files with ≥3 commits but exactly one author.
195
+ - **Coupling degree** = `commits-together / min(individual commits)`,
196
+ ignoring bulk commits that touch many files at once.
197
+
198
+ Inspired by the "code as a crime scene" approach to software analysis, made
199
+ simple enough to run in one command.
200
+
201
+ ---
202
+
203
+ ## Roadmap
204
+
205
+ - [x] Risk gate: score a change set, JSON output, CI exit code
206
+ - [x] Ignore globs / path filters for generated & data files
207
+ - [x] Post the gate result as a sticky PR comment (GitHub Action)
208
+ - [x] Trend over time (adaptive day/week/month buckets + hotspot-pressure verdict)
209
+ - [x] Complexity-based hotspots (decision-point estimate instead of line count)
210
+ - [x] Suggested PR reviewers from code ownership (in gate text/json/comment)
211
+ - [x] `--who <file>` — who knows this code best
212
+ - [x] `--badge` — shareable A–F health badge for your README
213
+ - [x] Orphaned-code section — complex files nobody touches anymore
214
+
215
+ ## Development
216
+
217
+ ```bash
218
+ pip install -e ".[dev]"
219
+ pytest
220
+ ```
221
+
222
+ The suite covers the complexity estimator, git parsing, every analyzer, and an
223
+ end-to-end run against a throwaway git repo. CI runs it on Python 3.10 and 3.12.
224
+
225
+ ## License
226
+
227
+ MIT
@@ -0,0 +1,13 @@
1
+ codepulse/__init__.py,sha256=jW-hGA5peoqijasFQ0hDLc1fTtc7LozQaV5ZRzWY_f0,92
2
+ codepulse/__main__.py,sha256=k1ocEWawweo1qCJWNFAAvyxz3tcY13dzvCenHszij30,48
3
+ codepulse/analyzers.py,sha256=ud2UwDJgJRu-Rq53QHoS2yBQRvRPjbULf4TGy8likr8,16631
4
+ codepulse/charts.py,sha256=wATHjaENoB73HlDHPpC_tzNrdTTAG0-Bq2P2VclCnLc,5252
5
+ codepulse/cli.py,sha256=ho1A7WiaWecYQCO4fIHyXkkceVvIsr-agsmyxUWJK_k,10434
6
+ codepulse/complexity.py,sha256=ITi8LogGzzlPEfTlF3m1u-z6cX__3-ojsy0pfuDuYAA,1543
7
+ codepulse/git_data.py,sha256=0KIKVjHYLkMopeRx33joHs9xaYUBn0b_FEUMPW7bSiY,3957
8
+ codepulse/report.py,sha256=pBISRg7BL_ztJ5Y1TTK_BL4ApyY9vVgkFdXT1NkZqGA,11509
9
+ codepulse_cli-0.1.0.dist-info/METADATA,sha256=8IuNze80TShJ_HqvIlsnQ3AfgVi5d4yELL3HdsAkgGk,8242
10
+ codepulse_cli-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
11
+ codepulse_cli-0.1.0.dist-info/entry_points.txt,sha256=xRsekBS_9RQ0fx-UagKqWflKPqnxwpJSS2AtWCPIoK0,49
12
+ codepulse_cli-0.1.0.dist-info/licenses/LICENSE,sha256=7eRQbii3vNO5cyKCcZYA4mEET6Ctb4twFp59UettDfs,1067
13
+ codepulse_cli-0.1.0.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
+ codepulse = codepulse.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mehouelley
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.