repoglance 0.2.1__tar.gz → 0.3.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 (55) hide show
  1. repoglance-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +41 -0
  2. repoglance-0.3.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. repoglance-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +24 -0
  4. repoglance-0.3.0/.github/PULL_REQUEST_TEMPLATE.md +16 -0
  5. {repoglance-0.2.1 → repoglance-0.3.0}/.github/workflows/release.yml +1 -1
  6. repoglance-0.3.0/.repoglance-badge.json +1 -0
  7. repoglance-0.3.0/CHANGELOG.md +63 -0
  8. repoglance-0.3.0/CODE_OF_CONDUCT.md +35 -0
  9. repoglance-0.3.0/Dockerfile +10 -0
  10. {repoglance-0.2.1 → repoglance-0.3.0}/PKG-INFO +59 -26
  11. {repoglance-0.2.1 → repoglance-0.3.0}/README.md +53 -22
  12. {repoglance-0.2.1 → repoglance-0.3.0}/RELEASING.md +2 -2
  13. repoglance-0.3.0/SECURITY.md +27 -0
  14. {repoglance-0.2.1 → repoglance-0.3.0}/action.yml +22 -1
  15. {repoglance-0.2.1 → repoglance-0.3.0}/assets/badge.svg +7 -7
  16. repoglance-0.3.0/assets/demo.svg +329 -0
  17. repoglance-0.3.0/assets/demo.tape +17 -0
  18. repoglance-0.3.0/assets/showcase/flask.svg +308 -0
  19. repoglance-0.3.0/assets/showcase/httpie.svg +347 -0
  20. repoglance-0.3.0/assets/showcase/requests.svg +322 -0
  21. repoglance-0.3.0/docs/index.md +35 -0
  22. repoglance-0.3.0/integrations/gitlab-ci.yml +13 -0
  23. repoglance-0.3.0/mkdocs.yml +7 -0
  24. {repoglance-0.2.1 → repoglance-0.3.0}/pyproject.toml +6 -4
  25. {repoglance-0.2.1 → repoglance-0.3.0}/src/repoglance/__init__.py +1 -1
  26. repoglance-0.3.0/src/repoglance/cli.py +173 -0
  27. repoglance-0.3.0/src/repoglance/complexity.py +129 -0
  28. repoglance-0.3.0/src/repoglance/config.py +55 -0
  29. {repoglance-0.2.1 → repoglance-0.3.0}/src/repoglance/metrics.py +23 -1
  30. {repoglance-0.2.1 → repoglance-0.3.0}/src/repoglance/report.py +135 -7
  31. repoglance-0.3.0/src/repoglance/scanner.py +313 -0
  32. repoglance-0.3.0/tests/test_cli.py +54 -0
  33. repoglance-0.3.0/tests/test_scanner_extra.py +65 -0
  34. repoglance-0.3.0/tests/test_v030.py +108 -0
  35. repoglance-0.2.1/.repolens-badge.json +0 -1
  36. repoglance-0.2.1/assets/demo.svg +0 -289
  37. repoglance-0.2.1/assets/showcase/flask.svg +0 -268
  38. repoglance-0.2.1/assets/showcase/httpie.svg +0 -311
  39. repoglance-0.2.1/assets/showcase/requests.svg +0 -290
  40. repoglance-0.2.1/src/repoglance/cli.py +0 -90
  41. repoglance-0.2.1/src/repoglance/complexity.py +0 -96
  42. repoglance-0.2.1/src/repoglance/scanner.py +0 -181
  43. {repoglance-0.2.1 → repoglance-0.3.0}/.github/workflows/ci.yml +0 -0
  44. {repoglance-0.2.1 → repoglance-0.3.0}/.github/workflows/repoglance.yml +0 -0
  45. {repoglance-0.2.1 → repoglance-0.3.0}/.gitignore +0 -0
  46. {repoglance-0.2.1 → repoglance-0.3.0}/.pre-commit-hooks.yaml +0 -0
  47. {repoglance-0.2.1 → repoglance-0.3.0}/CONTRIBUTING.md +0 -0
  48. {repoglance-0.2.1 → repoglance-0.3.0}/LICENSE +0 -0
  49. {repoglance-0.2.1 → repoglance-0.3.0}/src/repoglance/__main__.py +0 -0
  50. {repoglance-0.2.1 → repoglance-0.3.0}/src/repoglance/badge.py +0 -0
  51. {repoglance-0.2.1 → repoglance-0.3.0}/src/repoglance/gitinfo.py +0 -0
  52. {repoglance-0.2.1 → repoglance-0.3.0}/src/repoglance/languages.py +0 -0
  53. {repoglance-0.2.1 → repoglance-0.3.0}/tests/test_complexity.py +0 -0
  54. {repoglance-0.2.1 → repoglance-0.3.0}/tests/test_features.py +0 -0
  55. {repoglance-0.2.1 → repoglance-0.3.0}/tests/test_scanner.py +0 -0
@@ -0,0 +1,41 @@
1
+ name: Bug report
2
+ description: Something in repoglance is broken or wrong
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: Thanks for taking the time to file a bug! Please fill in the details below.
8
+ - type: input
9
+ id: version
10
+ attributes:
11
+ label: repoglance version
12
+ description: Output of `repoglance --version`
13
+ placeholder: "repoglance, version 0.2.2"
14
+ validations:
15
+ required: true
16
+ - type: input
17
+ id: python
18
+ attributes:
19
+ label: Python version & OS
20
+ placeholder: "Python 3.11 on macOS 14"
21
+ validations:
22
+ required: true
23
+ - type: textarea
24
+ id: what-happened
25
+ attributes:
26
+ label: What happened?
27
+ description: What did you run, what did you expect, and what did you get?
28
+ placeholder: |
29
+ Command: repoglance .
30
+ Expected: ...
31
+ Actual: ...
32
+ validations:
33
+ required: true
34
+ - type: textarea
35
+ id: traceback
36
+ attributes:
37
+ label: Traceback / output
38
+ description: Paste any error output. This will be rendered as code.
39
+ render: shell
40
+ validations:
41
+ required: false
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Question or discussion
4
+ url: https://github.com/SRJ-ai/repoglance/discussions
5
+ about: Ask a question or share an idea before opening an issue.
@@ -0,0 +1,24 @@
1
+ name: Feature request
2
+ description: Suggest an idea for repoglance
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: What problem would this solve?
9
+ description: Describe the use case, not just the feature.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ description: What would you like repoglance to do?
17
+ validations:
18
+ required: false
19
+ - type: textarea
20
+ id: alternatives
21
+ attributes:
22
+ label: Alternatives considered
23
+ validations:
24
+ required: false
@@ -0,0 +1,16 @@
1
+ <!-- Thanks for contributing to repoglance! -->
2
+
3
+ ## What does this change?
4
+
5
+ <!-- A short description of the change and why. -->
6
+
7
+ ## Checklist
8
+
9
+ - [ ] Tests added or updated (`python -m pytest -q` passes)
10
+ - [ ] Docs / README updated if behavior changed
11
+ - [ ] Runtime deps still limited to `rich` + `click`
12
+ - [ ] For a new language: added to `EXT_LANG` (and comment prefixes if relevant)
13
+
14
+ ## Related issues
15
+
16
+ <!-- e.g. Closes #123 -->
@@ -5,7 +5,7 @@ name: Release
5
5
  #
6
6
  # One-time setup on PyPI: create the project's "pending publisher" at
7
7
  # https://pypi.org/manage/account/publishing/ with
8
- # owner: SRJ-ai repo: repolens workflow: release.yml environment: pypi
8
+ # owner: SRJ-ai repo: repoglance workflow: release.yml environment: pypi
9
9
 
10
10
  on:
11
11
  push:
@@ -0,0 +1 @@
1
+ {"schemaVersion": 1, "label": "repoglance", "message": "2.3k loc \u2022 Python", "color": "blue"}
@@ -0,0 +1,63 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.3.0] - 2026-08-01
8
+
9
+ ### Added
10
+ - **Real cyclomatic complexity across 15+ languages** via `lizard` (C/C++, Java,
11
+ C#, JavaScript, TypeScript, Go, Rust, Ruby, PHP, Swift, Kotlin, Python and
12
+ more). Python keeps an AST fallback; a keyword heuristic remains as last
13
+ resort. Complexity for non-Python languages is now trustworthy, not a guess.
14
+ - **Maintainability index** (0–100), approximate Microsoft MI from complexity,
15
+ size and token counts.
16
+ - **Diff mode** `--since <rev>`: analyze only files changed since a git ref —
17
+ ideal for PRs. The Action exposes it via `diff-base`.
18
+ - **Baselines & regression ratchet**: `--baseline` snapshots a report;
19
+ `--compare` shows health/complexity/TODO/LOC deltas; `--fail-on-regression`
20
+ fails only on new or worse complexity.
21
+ - **SARIF output** (`--sarif`) for GitHub code scanning; the Action can upload
22
+ it (`sarif: true`) so hotspots appear inline on the Files changed tab.
23
+ - **CSV output** (`--csv`) and a **per-directory rollup** (report + JSON).
24
+ - **Config file**: `.repoglance.toml` or `[tool.repoglance]` in pyproject.
25
+ - **Glob include/exclude** (`--include` / `--exclude`) beyond directory names.
26
+ - **Parallel scanning** (`--jobs`) via a thread pool.
27
+ - Docker image, GitLab CI template, and mkdocs docs scaffold.
28
+
29
+ ## [0.2.2] - 2026-08-01
30
+
31
+ ### Added
32
+ - Respect the repository's `.gitignore`: when scanning a git repo, the file
33
+ list comes from `git ls-files` so ignored files are excluded (matches the
34
+ behavior of `tokei`/`scc`). Non-git directories still use a pruned walk.
35
+ - Count C-style `/* ... */` block comments when classifying lines, improving the
36
+ comment ratio (and therefore the health score) for C-family languages.
37
+ - Expanded test suite: CLI end-to-end (`click` runner), `.gitignore` handling,
38
+ block comments, and inline complexity scoring.
39
+
40
+ ### Changed
41
+ - Every file is now read exactly once. Complexity is computed during the scan
42
+ from the text already in memory instead of re-reading every file in a second
43
+ pass — roughly halving I/O on large repositories.
44
+
45
+ ## [0.2.1] - 2026-08-01
46
+
47
+ ### Changed
48
+ - Marketplace listing name set to a globally-unique title.
49
+
50
+ ## [0.2.0] - 2026-08-01
51
+
52
+ ### Changed
53
+ - Renamed the PyPI package and CLI to **repoglance** (the GitHub repository is
54
+ unchanged). Only line-comment TODO markers are counted, avoiding false
55
+ positives from prose and marker lists.
56
+
57
+ ## [0.1.0] - 2026-08-01
58
+
59
+ ### Added
60
+ - Initial release: rich terminal report (languages, complexity hotspots, TODO
61
+ tracker, biggest files, git activity), health score, JSON/Markdown/SVG/HTML
62
+ output, self-contained and dynamic badges, CI gate, GitHub Action, and
63
+ pre-commit hook.
@@ -0,0 +1,35 @@
1
+ # Code of Conduct
2
+
3
+ ## Our pledge
4
+
5
+ We as members, contributors, and maintainers pledge to make participation in
6
+ the repoglance community a harassment-free experience for everyone, regardless
7
+ of age, body size, visible or invisible disability, ethnicity, sex
8
+ characteristics, gender identity and expression, level of experience,
9
+ education, socio-economic status, nationality, personal appearance, race,
10
+ religion, or sexual identity and orientation.
11
+
12
+ ## Our standards
13
+
14
+ Examples of behavior that contributes to a positive environment:
15
+
16
+ - Being respectful of differing opinions, viewpoints, and experiences
17
+ - Giving and gracefully accepting constructive feedback
18
+ - Focusing on what is best for the community
19
+ - Showing empathy toward other community members
20
+
21
+ Unacceptable behavior includes harassment, insulting or derogatory comments,
22
+ personal or political attacks, publishing others' private information, and
23
+ other conduct which could reasonably be considered inappropriate.
24
+
25
+ ## Enforcement
26
+
27
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
28
+ reported to the project maintainers. All complaints will be reviewed and
29
+ investigated promptly and fairly. Maintainers are obligated to respect the
30
+ privacy and security of the reporter of any incident.
31
+
32
+ ## Attribution
33
+
34
+ This Code of Conduct is adapted from the
35
+ [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
@@ -0,0 +1,10 @@
1
+ # Minimal image to run repoglance against a mounted repository.
2
+ # docker build -t repoglance .
3
+ # docker run --rm -v "$PWD:/repo" repoglance /repo
4
+ FROM python:3.12-slim
5
+
6
+ RUN pip install --no-cache-dir repoglance
7
+
8
+ WORKDIR /repo
9
+ ENTRYPOINT ["repoglance"]
10
+ CMD ["."]
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: repoglance
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Instant, gorgeous insight into any code repository — languages, complexity hotspots, TODOs and git activity in one terminal command.
5
- Project-URL: Homepage, https://github.com/SRJ-ai/repolens
6
- Project-URL: Repository, https://github.com/SRJ-ai/repolens
7
- Project-URL: Issues, https://github.com/SRJ-ai/repolens/issues
5
+ Project-URL: Homepage, https://github.com/SRJ-ai/repoglance
6
+ Project-URL: Repository, https://github.com/SRJ-ai/repoglance
7
+ Project-URL: Issues, https://github.com/SRJ-ai/repoglance/issues
8
8
  Author: repoglance contributors
9
9
  License: MIT
10
10
  License-File: LICENSE
@@ -21,7 +21,9 @@ Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Topic :: Software Development :: Quality Assurance
22
22
  Requires-Python: >=3.9
23
23
  Requires-Dist: click>=8.0
24
+ Requires-Dist: lizard>=1.17
24
25
  Requires-Dist: rich>=13.0
26
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
25
27
  Provides-Extra: dev
26
28
  Requires-Dist: pytest-cov; extra == 'dev'
27
29
  Requires-Dist: pytest>=7.0; extra == 'dev'
@@ -37,11 +39,12 @@ Point it at any folder. In under a second you get a beautiful terminal report:
37
39
  language breakdown, complexity hotspots, TODO tracker, biggest files, and git
38
40
  activity. **Zero config. Zero API keys. Zero telemetry.**
39
41
 
40
- [![CI](https://github.com/SRJ-ai/repolens/actions/workflows/ci.yml/badge.svg)](https://github.com/SRJ-ai/repolens/actions/workflows/ci.yml)
41
- [![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)
42
+ [![PyPI](https://img.shields.io/pypi/v/repoglance.svg)](https://pypi.org/project/repoglance/)
43
+ [![Downloads](https://img.shields.io/pypi/dm/repoglance.svg)](https://pypi.org/project/repoglance/)
44
+ [![CI](https://github.com/SRJ-ai/repoglance/actions/workflows/ci.yml/badge.svg)](https://github.com/SRJ-ai/repoglance/actions/workflows/ci.yml)
45
+ [![Python](https://img.shields.io/pypi/pyversions/repoglance.svg)](https://pypi.org/project/repoglance/)
42
46
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
43
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
44
- [![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repolens/main/.repolens-badge.json)](https://github.com/SRJ-ai/repolens)
47
+ [![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repoglance/main/.repoglance-badge.json)](https://github.com/SRJ-ai/repoglance)
45
48
 
46
49
  </div>
47
50
 
@@ -69,9 +72,9 @@ repoglance run against well-known projects (click to view the full report):
69
72
 
70
73
  | Project | Files | Lines of code | Health |
71
74
  |---|--:|--:|:--:|
72
- | [flask](assets/showcase/flask.svg) | 200 | 25,030 | D (64) |
73
- | [httpie](assets/showcase/httpie.svg) | 217 | 19,604 | D (62) |
74
- | [requests](assets/showcase/requests.svg) | 71 | 13,215 | D (69) |
75
+ | [flask](assets/showcase/flask.svg) | 209 | 25,293 | D (67) |
76
+ | [httpie](assets/showcase/httpie.svg) | 236 | 20,114 | D (66) |
77
+ | [requests](assets/showcase/requests.svg) | 89 | 13,785 | C (72) |
75
78
 
76
79
  <div align="center">
77
80
 
@@ -97,12 +100,17 @@ pipx run repoglance .
97
100
  repoglance # analyze current directory
98
101
  repoglance path/to/repo # analyze another repo
99
102
  repoglance --json # machine-readable output for scripts / CI
103
+ repoglance --csv # per-file CSV
104
+ repoglance --sarif # SARIF for GitHub code scanning
100
105
  repoglance --svg report.svg # export a vector report
101
106
  repoglance --html report.html # export a browser report
102
107
  repoglance --badge badge.svg # export an embeddable badge
103
- repoglance --ci --max-complexity 25 # fail CI on hotspots
104
- repoglance --no-git # skip git history
105
- repoglance --ignore dist --ignore fixtures
108
+ repoglance --since origin/main # only files changed since a revision
109
+ repoglance --baseline base.json # snapshot now
110
+ repoglance --compare base.json --fail-on-regression # fail on new complexity
111
+ repoglance --ci --fail-under 70 --max-complexity 25 # gate a build
112
+ repoglance --include "src/**" --exclude "**/*_pb2.py" # glob filters
113
+ repoglance --no-git --jobs 8
106
114
  ```
107
115
 
108
116
  ### JSON output
@@ -118,9 +126,10 @@ repoglance --json | jq '.languages.Python.code'
118
126
  | Section | What you get |
119
127
  |---|---|
120
128
  | **Languages** | Lines of code per language, ranked, with % bars |
121
- | **Complexity hotspots** | Per-function cyclomatic complexity (Python via AST; heuristic for other langs) |
129
+ | **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) |
130
+ | **Maintainability index** | Approximate MI (0–100) from complexity, size and token counts |
122
131
  | **TODO tracker** | Every `TODO` / `FIXME` / `HACK` / `XXX` / `BUG` with file:line |
123
- | **Biggest files** | The files most likely to need splitting |
132
+ | **Biggest files & directories** | Where the mass and the worst complexity live |
124
133
  | **Git activity** | Top authors, most-churned files, active days, project lifespan |
125
134
 
126
135
  Binary files, `node_modules`, `.venv`, build dirs and friends are skipped
@@ -135,14 +144,17 @@ gives you artifacts you can put in a PR or a README.
135
144
  | | repoglance | tokei | scc | cloc |
136
145
  |---|:---:|:---:|:---:|:---:|
137
146
  | Lines-of-code by language | ✅ | ✅ | ✅ | ✅ |
138
- | Complexity hotspots (per function) | ✅ | ❌ | ⚠️ file-level | ❌ |
147
+ | Per-function complexity (15+ langs) | ✅ | ❌ | ⚠️ file-level | ❌ |
148
+ | Maintainability index | ✅ | ❌ | ❌ | ❌ |
139
149
  | TODO / FIXME tracker | ✅ | ❌ | ❌ | ❌ |
140
150
  | Git activity (authors, churn) | ✅ | ❌ | ❌ | ❌ |
141
- | JSON output | ✅ | ✅ | ✅ | |
151
+ | Respects `.gitignore` | ✅ | ✅ | ✅ | |
152
+ | JSON / CSV / **SARIF** output | ✅ | ⚠️ | ⚠️ | ⚠️ |
142
153
  | **HTML / SVG report export** | ✅ | ❌ | ❌ | ❌ |
143
154
  | **Embeddable repo badge** | ✅ | ❌ | ❌ | ❌ |
144
- | **CI gate (`--max-complexity`)** | ✅ | ❌ | ❌ | ❌ |
145
- | Zero install deps beyond one `pip` | ✅ | (binary) | (binary) | (perl) |
155
+ | **Diff mode (`--since`) + baselines** | ✅ | ❌ | ❌ | ❌ |
156
+ | **CI gate + regression ratchet** | ✅ | | | |
157
+ | **Config file** (`[tool.repoglance]`) | ✅ | ✅ | ❌ | ❌ |
146
158
 
147
159
  ## Share it: badges & reports
148
160
 
@@ -196,7 +208,7 @@ jobs:
196
208
  runs-on: ubuntu-latest
197
209
  steps:
198
210
  - uses: actions/checkout@v4
199
- - uses: SRJ-ai/repolens@main
211
+ - uses: SRJ-ai/repoglance@main
200
212
  with:
201
213
  fail-under: "70" # optional health gate
202
214
  max-complexity: "25" # optional complexity gate
@@ -209,8 +221,8 @@ The report also lands in the workflow's **job summary** every run.
209
221
  ```yaml
210
222
  # .pre-commit-config.yaml
211
223
  repos:
212
- - repo: https://github.com/SRJ-ai/repolens
213
- rev: v0.2.0
224
+ - repo: https://github.com/SRJ-ai/repoglance
225
+ rev: v0.2.2
214
226
  hooks:
215
227
  - id: repoglance
216
228
  args: ["--ci", "--fail-under", "70"]
@@ -222,11 +234,11 @@ Commit a shields endpoint file and point a dynamic badge at it — the badge
222
234
  refreshes itself, no service to run:
223
235
 
224
236
  ```bash
225
- repoglance --badge-json .repolens-badge.json # commit this file
237
+ repoglance --badge-json .repoglance-badge.json # commit this file
226
238
  ```
227
239
 
228
240
  ```markdown
229
- ![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repolens/main/.repolens-badge.json)
241
+ ![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repoglance/main/.repoglance-badge.json)
230
242
  ```
231
243
 
232
244
  ### Markdown anywhere
@@ -235,9 +247,30 @@ repoglance --badge-json .repolens-badge.json # commit this file
235
247
  repoglance --md # paste into a PR, wiki, or Slack
236
248
  ```
237
249
 
250
+ ### Configuration file
251
+
252
+ Set defaults once via `.repoglance.toml` or a `[tool.repoglance]` table in
253
+ `pyproject.toml` (CLI flags always win):
254
+
255
+ ```toml
256
+ [tool.repoglance]
257
+ exclude = ["**/*_pb2.py", "vendor/**"]
258
+ max_complexity = 25
259
+ fail_under = 70
260
+ ```
261
+
262
+ ### Docker & GitLab
263
+
264
+ ```bash
265
+ docker run --rm -v "$PWD:/repo" repoglance /repo
266
+ ```
267
+
268
+ A ready-to-copy GitLab CI job lives in
269
+ [`integrations/gitlab-ci.yml`](integrations/gitlab-ci.yml).
270
+
238
271
  ## Design goals
239
272
 
240
- - **Fast** — a single `os.walk`, no external services.
273
+ - **Fast** — a single pass, no external services.
241
274
  - **Honest** — no network, no telemetry, no surprise writes.
242
275
  - **Pretty** — powered by [rich](https://github.com/Textualize/rich).
243
276
  - **Scriptable** — everything the report shows is available as `--json`.
@@ -8,11 +8,12 @@ Point it at any folder. In under a second you get a beautiful terminal report:
8
8
  language breakdown, complexity hotspots, TODO tracker, biggest files, and git
9
9
  activity. **Zero config. Zero API keys. Zero telemetry.**
10
10
 
11
- [![CI](https://github.com/SRJ-ai/repolens/actions/workflows/ci.yml/badge.svg)](https://github.com/SRJ-ai/repolens/actions/workflows/ci.yml)
12
- [![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)
11
+ [![PyPI](https://img.shields.io/pypi/v/repoglance.svg)](https://pypi.org/project/repoglance/)
12
+ [![Downloads](https://img.shields.io/pypi/dm/repoglance.svg)](https://pypi.org/project/repoglance/)
13
+ [![CI](https://github.com/SRJ-ai/repoglance/actions/workflows/ci.yml/badge.svg)](https://github.com/SRJ-ai/repoglance/actions/workflows/ci.yml)
14
+ [![Python](https://img.shields.io/pypi/pyversions/repoglance.svg)](https://pypi.org/project/repoglance/)
13
15
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
14
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
15
- [![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repolens/main/.repolens-badge.json)](https://github.com/SRJ-ai/repolens)
16
+ [![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repoglance/main/.repoglance-badge.json)](https://github.com/SRJ-ai/repoglance)
16
17
 
17
18
  </div>
18
19
 
@@ -40,9 +41,9 @@ repoglance run against well-known projects (click to view the full report):
40
41
 
41
42
  | Project | Files | Lines of code | Health |
42
43
  |---|--:|--:|:--:|
43
- | [flask](assets/showcase/flask.svg) | 200 | 25,030 | D (64) |
44
- | [httpie](assets/showcase/httpie.svg) | 217 | 19,604 | D (62) |
45
- | [requests](assets/showcase/requests.svg) | 71 | 13,215 | D (69) |
44
+ | [flask](assets/showcase/flask.svg) | 209 | 25,293 | D (67) |
45
+ | [httpie](assets/showcase/httpie.svg) | 236 | 20,114 | D (66) |
46
+ | [requests](assets/showcase/requests.svg) | 89 | 13,785 | C (72) |
46
47
 
47
48
  <div align="center">
48
49
 
@@ -68,12 +69,17 @@ pipx run repoglance .
68
69
  repoglance # analyze current directory
69
70
  repoglance path/to/repo # analyze another repo
70
71
  repoglance --json # machine-readable output for scripts / CI
72
+ repoglance --csv # per-file CSV
73
+ repoglance --sarif # SARIF for GitHub code scanning
71
74
  repoglance --svg report.svg # export a vector report
72
75
  repoglance --html report.html # export a browser report
73
76
  repoglance --badge badge.svg # export an embeddable badge
74
- repoglance --ci --max-complexity 25 # fail CI on hotspots
75
- repoglance --no-git # skip git history
76
- repoglance --ignore dist --ignore fixtures
77
+ repoglance --since origin/main # only files changed since a revision
78
+ repoglance --baseline base.json # snapshot now
79
+ repoglance --compare base.json --fail-on-regression # fail on new complexity
80
+ repoglance --ci --fail-under 70 --max-complexity 25 # gate a build
81
+ repoglance --include "src/**" --exclude "**/*_pb2.py" # glob filters
82
+ repoglance --no-git --jobs 8
77
83
  ```
78
84
 
79
85
  ### JSON output
@@ -89,9 +95,10 @@ repoglance --json | jq '.languages.Python.code'
89
95
  | Section | What you get |
90
96
  |---|---|
91
97
  | **Languages** | Lines of code per language, ranked, with % bars |
92
- | **Complexity hotspots** | Per-function cyclomatic complexity (Python via AST; heuristic for other langs) |
98
+ | **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) |
99
+ | **Maintainability index** | Approximate MI (0–100) from complexity, size and token counts |
93
100
  | **TODO tracker** | Every `TODO` / `FIXME` / `HACK` / `XXX` / `BUG` with file:line |
94
- | **Biggest files** | The files most likely to need splitting |
101
+ | **Biggest files & directories** | Where the mass and the worst complexity live |
95
102
  | **Git activity** | Top authors, most-churned files, active days, project lifespan |
96
103
 
97
104
  Binary files, `node_modules`, `.venv`, build dirs and friends are skipped
@@ -106,14 +113,17 @@ gives you artifacts you can put in a PR or a README.
106
113
  | | repoglance | tokei | scc | cloc |
107
114
  |---|:---:|:---:|:---:|:---:|
108
115
  | Lines-of-code by language | ✅ | ✅ | ✅ | ✅ |
109
- | Complexity hotspots (per function) | ✅ | ❌ | ⚠️ file-level | ❌ |
116
+ | Per-function complexity (15+ langs) | ✅ | ❌ | ⚠️ file-level | ❌ |
117
+ | Maintainability index | ✅ | ❌ | ❌ | ❌ |
110
118
  | TODO / FIXME tracker | ✅ | ❌ | ❌ | ❌ |
111
119
  | Git activity (authors, churn) | ✅ | ❌ | ❌ | ❌ |
112
- | JSON output | ✅ | ✅ | ✅ | |
120
+ | Respects `.gitignore` | ✅ | ✅ | ✅ | |
121
+ | JSON / CSV / **SARIF** output | ✅ | ⚠️ | ⚠️ | ⚠️ |
113
122
  | **HTML / SVG report export** | ✅ | ❌ | ❌ | ❌ |
114
123
  | **Embeddable repo badge** | ✅ | ❌ | ❌ | ❌ |
115
- | **CI gate (`--max-complexity`)** | ✅ | ❌ | ❌ | ❌ |
116
- | Zero install deps beyond one `pip` | ✅ | (binary) | (binary) | (perl) |
124
+ | **Diff mode (`--since`) + baselines** | ✅ | ❌ | ❌ | ❌ |
125
+ | **CI gate + regression ratchet** | ✅ | | | |
126
+ | **Config file** (`[tool.repoglance]`) | ✅ | ✅ | ❌ | ❌ |
117
127
 
118
128
  ## Share it: badges & reports
119
129
 
@@ -167,7 +177,7 @@ jobs:
167
177
  runs-on: ubuntu-latest
168
178
  steps:
169
179
  - uses: actions/checkout@v4
170
- - uses: SRJ-ai/repolens@main
180
+ - uses: SRJ-ai/repoglance@main
171
181
  with:
172
182
  fail-under: "70" # optional health gate
173
183
  max-complexity: "25" # optional complexity gate
@@ -180,8 +190,8 @@ The report also lands in the workflow's **job summary** every run.
180
190
  ```yaml
181
191
  # .pre-commit-config.yaml
182
192
  repos:
183
- - repo: https://github.com/SRJ-ai/repolens
184
- rev: v0.2.0
193
+ - repo: https://github.com/SRJ-ai/repoglance
194
+ rev: v0.2.2
185
195
  hooks:
186
196
  - id: repoglance
187
197
  args: ["--ci", "--fail-under", "70"]
@@ -193,11 +203,11 @@ Commit a shields endpoint file and point a dynamic badge at it — the badge
193
203
  refreshes itself, no service to run:
194
204
 
195
205
  ```bash
196
- repoglance --badge-json .repolens-badge.json # commit this file
206
+ repoglance --badge-json .repoglance-badge.json # commit this file
197
207
  ```
198
208
 
199
209
  ```markdown
200
- ![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repolens/main/.repolens-badge.json)
210
+ ![repoglance](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/SRJ-ai/repoglance/main/.repoglance-badge.json)
201
211
  ```
202
212
 
203
213
  ### Markdown anywhere
@@ -206,9 +216,30 @@ repoglance --badge-json .repolens-badge.json # commit this file
206
216
  repoglance --md # paste into a PR, wiki, or Slack
207
217
  ```
208
218
 
219
+ ### Configuration file
220
+
221
+ Set defaults once via `.repoglance.toml` or a `[tool.repoglance]` table in
222
+ `pyproject.toml` (CLI flags always win):
223
+
224
+ ```toml
225
+ [tool.repoglance]
226
+ exclude = ["**/*_pb2.py", "vendor/**"]
227
+ max_complexity = 25
228
+ fail_under = 70
229
+ ```
230
+
231
+ ### Docker & GitLab
232
+
233
+ ```bash
234
+ docker run --rm -v "$PWD:/repo" repoglance /repo
235
+ ```
236
+
237
+ A ready-to-copy GitLab CI job lives in
238
+ [`integrations/gitlab-ci.yml`](integrations/gitlab-ci.yml).
239
+
209
240
  ## Design goals
210
241
 
211
- - **Fast** — a single `os.walk`, no external services.
242
+ - **Fast** — a single pass, no external services.
212
243
  - **Honest** — no network, no telemetry, no surprise writes.
213
244
  - **Pretty** — powered by [rich](https://github.com/Textualize/rich).
214
245
  - **Scriptable** — everything the report shows is available as `--json`.
@@ -5,7 +5,7 @@ via GitHub Actions using PyPI's **trusted publisher** (OIDC) — there is no API
5
5
  token stored anywhere.
6
6
 
7
7
  > The PyPI distribution is **`repoglance`**; the GitHub repository is
8
- > **`SRJ-ai/repolens`**. Keep that distinction in mind below.
8
+ > **`SRJ-ai/repoglance`**. Keep that distinction in mind below.
9
9
 
10
10
  ## One-time PyPI setup
11
11
 
@@ -13,7 +13,7 @@ token stored anywhere.
13
13
  2. Fill in:
14
14
  - **PyPI project name:** `repoglance`
15
15
  - **Owner:** `SRJ-ai`
16
- - **Repository:** `repolens`
16
+ - **Repository:** `repoglance`
17
17
  - **Workflow name:** `release.yml`
18
18
  - **Environment:** `pypi`
19
19
  3. Save.
@@ -0,0 +1,27 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a vulnerability
4
+
5
+ If you find a security issue in repoglance, please report it privately:
6
+
7
+ - Open a [GitHub security advisory](https://github.com/SRJ-ai/repoglance/security/advisories/new), **or**
8
+ - Email the maintainers with the details.
9
+
10
+ Please do **not** open a public issue for security problems.
11
+
12
+ We aim to acknowledge reports within 3 business days and to ship a fix or
13
+ mitigation as quickly as the severity warrants.
14
+
15
+ ## Scope notes
16
+
17
+ repoglance is a local, read-only analysis tool: it does not make network
18
+ requests, send telemetry, or write outside the paths you explicitly pass for
19
+ report/badge output. It does shell out to `git` for repository metadata. The
20
+ most relevant considerations are therefore:
21
+
22
+ - Handling of untrusted repository contents (file parsing, path handling).
23
+ - The `git` subprocess invocations in `gitinfo.py` and `scanner.py`.
24
+
25
+ ## Supported versions
26
+
27
+ The latest released version on PyPI receives security fixes.
@@ -21,6 +21,14 @@ inputs:
21
21
  description: "Fail the job if any function exceeds this cyclomatic complexity. Empty to disable."
22
22
  required: false
23
23
  default: ""
24
+ sarif:
25
+ description: "Generate SARIF and upload it to GitHub code scanning (requires security-events: write)."
26
+ required: false
27
+ default: "false"
28
+ diff-base:
29
+ description: "Only analyze files changed since this git ref (e.g. origin/main). Empty = whole repo."
30
+ required: false
31
+ default: ""
24
32
  github-token:
25
33
  description: "Token used to post the PR comment."
26
34
  required: false
@@ -41,9 +49,22 @@ runs:
41
49
  - name: Job summary + Markdown report
42
50
  shell: bash
43
51
  run: |
44
- repoglance "${{ inputs.path }}" --md > "$RUNNER_TEMP/repoglance.md"
52
+ since=""
53
+ [ -n "${{ inputs.diff-base }}" ] && since="--since ${{ inputs.diff-base }}"
54
+ repoglance "${{ inputs.path }}" $since --md > "$RUNNER_TEMP/repoglance.md"
45
55
  cat "$RUNNER_TEMP/repoglance.md" >> "$GITHUB_STEP_SUMMARY"
46
56
 
57
+ - name: Generate SARIF
58
+ if: ${{ inputs.sarif == 'true' }}
59
+ shell: bash
60
+ run: repoglance "${{ inputs.path }}" --sarif > "$RUNNER_TEMP/repoglance.sarif"
61
+
62
+ - name: Upload SARIF
63
+ if: ${{ inputs.sarif == 'true' }}
64
+ uses: github/codeql-action/upload-sarif@v3
65
+ with:
66
+ sarif_file: ${{ runner.temp }}/repoglance.sarif
67
+
47
68
  - name: Comment on PR
48
69
  if: ${{ inputs.comment == 'true' && github.event_name == 'pull_request' }}
49
70
  shell: bash