repoglance 0.4.2__tar.gz → 0.5.0__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 (66) hide show
  1. repoglance-0.5.0/.repoglance-badge.json +1 -0
  2. {repoglance-0.4.2 → repoglance-0.5.0}/CHANGELOG.md +30 -0
  3. {repoglance-0.4.2 → repoglance-0.5.0}/PKG-INFO +21 -6
  4. {repoglance-0.4.2 → repoglance-0.5.0}/README.md +20 -5
  5. {repoglance-0.4.2 → repoglance-0.5.0}/action.yml +49 -0
  6. repoglance-0.5.0/assets/demo.svg +423 -0
  7. repoglance-0.5.0/assets/showcase/flask.svg +324 -0
  8. repoglance-0.5.0/assets/showcase/httpie.svg +363 -0
  9. repoglance-0.5.0/assets/showcase/requests.svg +338 -0
  10. {repoglance-0.4.2 → repoglance-0.5.0}/pyproject.toml +1 -1
  11. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/__init__.py +1 -1
  12. repoglance-0.5.0/src/repoglance/analytics.py +165 -0
  13. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/cache.py +10 -3
  14. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/cli.py +15 -4
  15. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/complexity.py +34 -7
  16. repoglance-0.5.0/src/repoglance/covreport.py +101 -0
  17. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/gitinfo.py +14 -0
  18. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/report.py +44 -1
  19. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/scanner.py +21 -9
  20. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_v041.py +14 -0
  21. repoglance-0.5.0/tests/test_v050.py +81 -0
  22. repoglance-0.4.2/.repoglance-badge.json +0 -1
  23. repoglance-0.4.2/assets/demo.svg +0 -391
  24. repoglance-0.4.2/assets/showcase/flask.svg +0 -312
  25. repoglance-0.4.2/assets/showcase/httpie.svg +0 -351
  26. repoglance-0.4.2/assets/showcase/requests.svg +0 -326
  27. {repoglance-0.4.2 → repoglance-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  28. {repoglance-0.4.2 → repoglance-0.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  29. {repoglance-0.4.2 → repoglance-0.5.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  30. {repoglance-0.4.2 → repoglance-0.5.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  31. {repoglance-0.4.2 → repoglance-0.5.0}/.github/workflows/ci.yml +0 -0
  32. {repoglance-0.4.2 → repoglance-0.5.0}/.github/workflows/release.yml +0 -0
  33. {repoglance-0.4.2 → repoglance-0.5.0}/.github/workflows/repoglance.yml +0 -0
  34. {repoglance-0.4.2 → repoglance-0.5.0}/.gitignore +0 -0
  35. {repoglance-0.4.2 → repoglance-0.5.0}/.pre-commit-hooks.yaml +0 -0
  36. {repoglance-0.4.2 → repoglance-0.5.0}/CODE_OF_CONDUCT.md +0 -0
  37. {repoglance-0.4.2 → repoglance-0.5.0}/CONTRIBUTING.md +0 -0
  38. {repoglance-0.4.2 → repoglance-0.5.0}/Dockerfile +0 -0
  39. {repoglance-0.4.2 → repoglance-0.5.0}/LICENSE +0 -0
  40. {repoglance-0.4.2 → repoglance-0.5.0}/RELEASING.md +0 -0
  41. {repoglance-0.4.2 → repoglance-0.5.0}/SECURITY.md +0 -0
  42. {repoglance-0.4.2 → repoglance-0.5.0}/assets/badge.svg +0 -0
  43. {repoglance-0.4.2 → repoglance-0.5.0}/assets/demo.tape +0 -0
  44. {repoglance-0.4.2 → repoglance-0.5.0}/benchmarks/bench.py +0 -0
  45. {repoglance-0.4.2 → repoglance-0.5.0}/docs/index.md +0 -0
  46. {repoglance-0.4.2 → repoglance-0.5.0}/editors/vscode/README.md +0 -0
  47. {repoglance-0.4.2 → repoglance-0.5.0}/editors/vscode/extension.js +0 -0
  48. {repoglance-0.4.2 → repoglance-0.5.0}/editors/vscode/package.json +0 -0
  49. {repoglance-0.4.2 → repoglance-0.5.0}/integrations/gitlab-ci.yml +0 -0
  50. {repoglance-0.4.2 → repoglance-0.5.0}/mkdocs.yml +0 -0
  51. {repoglance-0.4.2 → repoglance-0.5.0}/packaging/homebrew/repoglance.rb +0 -0
  52. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/__main__.py +0 -0
  53. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/badge.py +0 -0
  54. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/config.py +0 -0
  55. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/dedup.py +0 -0
  56. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/languages.py +0 -0
  57. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/metrics.py +0 -0
  58. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/plugins.py +0 -0
  59. {repoglance-0.4.2 → repoglance-0.5.0}/src/repoglance/vendored.py +0 -0
  60. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_cli.py +0 -0
  61. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_complexity.py +0 -0
  62. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_features.py +0 -0
  63. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_scanner.py +0 -0
  64. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_scanner_extra.py +0 -0
  65. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_v030.py +0 -0
  66. {repoglance-0.4.2 → repoglance-0.5.0}/tests/test_v040.py +0 -0
@@ -0,0 +1 @@
1
+ {"schemaVersion": 1, "label": "repoglance", "message": "3.4k loc \u2022 Python", "color": "blue"}
@@ -4,6 +4,36 @@ All notable changes to this project are documented here. The format is based on
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.5.0] - 2026-08-01
8
+
9
+ ### Added
10
+ - **Refactor priority**: files ranked by **churn × complexity** — frequently
11
+ changed *and* complex code, the classic "fix this first" signal. Shown as a
12
+ panel and in JSON (`risk`).
13
+ - **Coverage × complexity** (`--coverage <cobertura.xml|lcov>`): surfaces
14
+ complex, poorly-covered files (risk = complexity × (1 − coverage)).
15
+ - **Python quality**: docstring and type-hint coverage across functions.
16
+ - **Import graph** (`--imports`): intra-repo Python module coupling and
17
+ **circular-import detection**.
18
+ - **Longest functions**: biggest functions by logical lines (in JSON).
19
+ - **Activity trend**: commits-per-month sparkline in the git panel.
20
+ - **GitHub Action inline annotations** (`annotations: true`): a Check Run places
21
+ complexity warnings on the exact lines in a PR.
22
+
23
+ ## [0.4.3] - 2026-08-01
24
+
25
+ ### Added
26
+ - **`--fast` mode**: counts only (languages, LOC, sizes), skipping per-function
27
+ complexity parsing — the expensive step. Combined with the process pool this
28
+ scans **20 million lines in ~4.4 s** (~4.5M LOC/s). Use it for size/inventory
29
+ passes on very large monorepos; drop it for full complexity/health analysis.
30
+
31
+ ### Changed
32
+ - **Python complexity now uses CPython's C-accelerated `ast`** instead of the
33
+ pure-Python tokenizer, roughly **halving full-analysis time on Python-heavy
34
+ repos** (Django 415k LOC: ~10 s → ~5 s on 8 cores). Other languages still use
35
+ lizard. Adaptive process-pool chunk sizing reduces IPC overhead.
36
+
7
37
  ## [0.4.2] - 2026-08-01
8
38
 
9
39
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: repoglance
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: Instant, gorgeous insight into any code repository — languages, complexity hotspots, TODOs and git activity in one terminal command.
5
5
  Project-URL: Homepage, https://github.com/SRJ-ai/repoglance
6
6
  Project-URL: Repository, https://github.com/SRJ-ai/repoglance
@@ -112,6 +112,8 @@ repoglance --ci --fail-under 70 --max-complexity 25 # gate a build
112
112
  repoglance --include "src/**" --exclude "**/*_pb2.py" # glob filters
113
113
  repoglance --duplicates # detect copy-paste blocks
114
114
  repoglance --owners # attribute hotspots to authors (git blame)
115
+ repoglance --imports # python import graph + circular imports
116
+ repoglance --coverage coverage.xml # cross coverage with complexity
115
117
  repoglance --cache .rg.cache # incremental cache for fast repeat runs
116
118
  repoglance --watch # live re-render on file changes
117
119
  repoglance --no-git --jobs 8
@@ -132,6 +134,11 @@ repoglance --json | jq '.languages.Python.code'
132
134
  | **Languages** | Lines of code per language, ranked, with % bars |
133
135
  | **Complexity hotspots** | Real per-function cyclomatic complexity across 15+ languages (C/C++, Java, C#, JS, TS, Go, Rust, Ruby, PHP, Swift, Kotlin, Python…) via [lizard](https://github.com/terryyin/lizard) |
134
136
  | **Maintainability index** | Approximate MI (0–100) from complexity, size and token counts |
137
+ | **Refactor priority** | Files ranked by churn × complexity — what to fix first |
138
+ | **Coverage risk** | Cross a coverage report with complexity (`--coverage`): complex + untested = danger |
139
+ | **Python quality** | Docstring and type-hint coverage across functions |
140
+ | **Import graph** | Python module coupling + circular-import detection (`--imports`) |
141
+ | **Longest functions** | The biggest functions by logical lines |
135
142
  | **Duplicate code** | Copy-paste blocks across files, with a duplication % |
136
143
  | **TODO tracker** | Every `TODO` / `FIXME` / `HACK` / `XXX` / `BUG` with file:line |
137
144
  | **Biggest files & directories** | Where the mass and the worst complexity live |
@@ -155,6 +162,9 @@ gives you artifacts you can put in a PR or a README.
155
162
  |---|:---:|:---:|:---:|:---:|
156
163
  | Lines-of-code by language | ✅ | ✅ | ✅ | ✅ |
157
164
  | Per-function complexity (15+ langs) | ✅ | ❌ | ⚠️ file-level | ❌ |
165
+ | **Refactor priority (churn × complexity)** | ✅ | ❌ | ❌ | ❌ |
166
+ | **Coverage × complexity risk** | ✅ | ❌ | ❌ | ❌ |
167
+ | **Circular-import detection** | ✅ | ❌ | ❌ | ❌ |
158
168
  | Maintainability index | ✅ | ❌ | ❌ | ❌ |
159
169
  | TODO / FIXME tracker | ✅ | ❌ | ❌ | ❌ |
160
170
  | Git activity (authors, churn) | ✅ | ❌ | ❌ | ❌ |
@@ -302,11 +312,16 @@ millions of lines, thousands of files — not just small projects:
302
312
 
303
313
  Measured on Django (3,180 files, ~415k lines of code), single machine:
304
314
 
305
- | Run | Time |
306
- |---|--:|
307
- | Cold scan, threads | ~20.5 s |
308
- | Cold scan, process pool (auto on large repos) | ~10.1 s |
309
- | Re-run with `--cache` | ~1.1 s |
315
+ | Run | Repo | Time |
316
+ |---|---|--:|
317
+ | Cold scan, full analysis (8 cores) | Django, 415k LOC | ~5.0 s |
318
+ | Re-run with `--cache` | Django, 415k LOC | ~1.1 s |
319
+ | **`--fast` (counts only), process pool** | **20,000,000 LOC** | **~4.4 s** |
320
+
321
+ `--fast` skips per-function complexity parsing (the expensive step) and reports
322
+ languages, line counts and sizes only — that's what makes a 20-million-line
323
+ scan finish in seconds (~4.5M LOC/s here). Drop `--fast` when you want the full
324
+ complexity/health analysis.
310
325
 
311
326
  The cold scan is dominated by real per-function complexity parsing. The process
312
327
  pool spreads that across cores (~2× here); the incremental cache (`--cache
@@ -80,6 +80,8 @@ repoglance --ci --fail-under 70 --max-complexity 25 # gate a build
80
80
  repoglance --include "src/**" --exclude "**/*_pb2.py" # glob filters
81
81
  repoglance --duplicates # detect copy-paste blocks
82
82
  repoglance --owners # attribute hotspots to authors (git blame)
83
+ repoglance --imports # python import graph + circular imports
84
+ repoglance --coverage coverage.xml # cross coverage with complexity
83
85
  repoglance --cache .rg.cache # incremental cache for fast repeat runs
84
86
  repoglance --watch # live re-render on file changes
85
87
  repoglance --no-git --jobs 8
@@ -100,6 +102,11 @@ repoglance --json | jq '.languages.Python.code'
100
102
  | **Languages** | Lines of code per language, ranked, with % bars |
101
103
  | **Complexity hotspots** | Real per-function cyclomatic complexity across 15+ languages (C/C++, Java, C#, JS, TS, Go, Rust, Ruby, PHP, Swift, Kotlin, Python…) via [lizard](https://github.com/terryyin/lizard) |
102
104
  | **Maintainability index** | Approximate MI (0–100) from complexity, size and token counts |
105
+ | **Refactor priority** | Files ranked by churn × complexity — what to fix first |
106
+ | **Coverage risk** | Cross a coverage report with complexity (`--coverage`): complex + untested = danger |
107
+ | **Python quality** | Docstring and type-hint coverage across functions |
108
+ | **Import graph** | Python module coupling + circular-import detection (`--imports`) |
109
+ | **Longest functions** | The biggest functions by logical lines |
103
110
  | **Duplicate code** | Copy-paste blocks across files, with a duplication % |
104
111
  | **TODO tracker** | Every `TODO` / `FIXME` / `HACK` / `XXX` / `BUG` with file:line |
105
112
  | **Biggest files & directories** | Where the mass and the worst complexity live |
@@ -123,6 +130,9 @@ gives you artifacts you can put in a PR or a README.
123
130
  |---|:---:|:---:|:---:|:---:|
124
131
  | Lines-of-code by language | ✅ | ✅ | ✅ | ✅ |
125
132
  | Per-function complexity (15+ langs) | ✅ | ❌ | ⚠️ file-level | ❌ |
133
+ | **Refactor priority (churn × complexity)** | ✅ | ❌ | ❌ | ❌ |
134
+ | **Coverage × complexity risk** | ✅ | ❌ | ❌ | ❌ |
135
+ | **Circular-import detection** | ✅ | ❌ | ❌ | ❌ |
126
136
  | Maintainability index | ✅ | ❌ | ❌ | ❌ |
127
137
  | TODO / FIXME tracker | ✅ | ❌ | ❌ | ❌ |
128
138
  | Git activity (authors, churn) | ✅ | ❌ | ❌ | ❌ |
@@ -270,11 +280,16 @@ millions of lines, thousands of files — not just small projects:
270
280
 
271
281
  Measured on Django (3,180 files, ~415k lines of code), single machine:
272
282
 
273
- | Run | Time |
274
- |---|--:|
275
- | Cold scan, threads | ~20.5 s |
276
- | Cold scan, process pool (auto on large repos) | ~10.1 s |
277
- | Re-run with `--cache` | ~1.1 s |
283
+ | Run | Repo | Time |
284
+ |---|---|--:|
285
+ | Cold scan, full analysis (8 cores) | Django, 415k LOC | ~5.0 s |
286
+ | Re-run with `--cache` | Django, 415k LOC | ~1.1 s |
287
+ | **`--fast` (counts only), process pool** | **20,000,000 LOC** | **~4.4 s** |
288
+
289
+ `--fast` skips per-function complexity parsing (the expensive step) and reports
290
+ languages, line counts and sizes only — that's what makes a 20-million-line
291
+ scan finish in seconds (~4.5M LOC/s here). Drop `--fast` when you want the full
292
+ complexity/health analysis.
278
293
 
279
294
  The cold scan is dominated by real per-function complexity parsing. The process
280
295
  pool spreads that across cores (~2× here); the incremental cache (`--cache
@@ -29,6 +29,14 @@ inputs:
29
29
  description: "Only analyze files changed since this git ref (e.g. origin/main). Empty = whole repo."
30
30
  required: false
31
31
  default: ""
32
+ annotations:
33
+ description: "Create a Check Run with inline complexity annotations on the PR (requires checks: write)."
34
+ required: false
35
+ default: "false"
36
+ annotation-threshold:
37
+ description: "Minimum complexity to annotate inline."
38
+ required: false
39
+ default: "15"
32
40
  github-token:
33
41
  description: "Token used to post the PR comment."
34
42
  required: false
@@ -83,6 +91,47 @@ runs:
83
91
  gh api -X POST "repos/${{ github.repository }}/issues/$pr/comments" -f body="$body" >/dev/null
84
92
  fi
85
93
 
94
+ - name: Inline annotations (Check Run)
95
+ if: ${{ inputs.annotations == 'true' }}
96
+ shell: bash
97
+ env:
98
+ GH_TOKEN: ${{ inputs.github-token }}
99
+ run: |
100
+ repoglance "${{ inputs.path }}" --json > "$RUNNER_TEMP/repoglance.json"
101
+ python - "$RUNNER_TEMP/repoglance.json" "${{ inputs.annotation-threshold }}" <<'PY' > "$RUNNER_TEMP/checkrun.json"
102
+ import json, sys
103
+ report = json.load(open(sys.argv[1]))
104
+ threshold = int(sys.argv[2])
105
+ anns = []
106
+ for h in report.get("hotspots", []):
107
+ if h["complexity"] < threshold:
108
+ continue
109
+ anns.append({
110
+ "path": h["path"],
111
+ "start_line": max(1, h["line"]),
112
+ "end_line": max(1, h["line"]),
113
+ "annotation_level": "failure" if h["complexity"] >= 25 else "warning",
114
+ "message": f"Function '{h['name']}' has cyclomatic complexity {h['complexity']}.",
115
+ "title": "High complexity",
116
+ })
117
+ health = report.get("health", {})
118
+ out = {
119
+ "name": "repoglance",
120
+ "head_sha": "__SHA__",
121
+ "status": "completed",
122
+ "conclusion": "neutral",
123
+ "output": {
124
+ "title": f"Health {health.get('score','?')}/100 ({health.get('grade','?')})",
125
+ "summary": f"{len(anns)} complexity hotspot(s) at or above {threshold}.",
126
+ "annotations": anns[:50],
127
+ },
128
+ }
129
+ print(json.dumps(out))
130
+ PY
131
+ sha="${{ github.event.pull_request.head.sha || github.sha }}"
132
+ sed -i "s/__SHA__/$sha/" "$RUNNER_TEMP/checkrun.json"
133
+ gh api -X POST "repos/${{ github.repository }}/check-runs" --input "$RUNNER_TEMP/checkrun.json" >/dev/null || true
134
+
86
135
  - name: Gate
87
136
  shell: bash
88
137
  run: |