repoglance 0.2.2__tar.gz → 0.4.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.
- repoglance-0.4.0/.github/ISSUE_TEMPLATE/bug_report.yml +41 -0
- repoglance-0.4.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- repoglance-0.4.0/.github/ISSUE_TEMPLATE/feature_request.yml +24 -0
- repoglance-0.4.0/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- repoglance-0.4.0/.repoglance-badge.json +1 -0
- repoglance-0.4.0/CHANGELOG.md +84 -0
- repoglance-0.4.0/CODE_OF_CONDUCT.md +35 -0
- repoglance-0.4.0/Dockerfile +10 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/PKG-INFO +58 -15
- {repoglance-0.2.2 → repoglance-0.4.0}/README.md +55 -14
- repoglance-0.4.0/SECURITY.md +27 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/action.yml +22 -1
- {repoglance-0.2.2 → repoglance-0.4.0}/assets/badge.svg +7 -7
- repoglance-0.4.0/assets/demo.svg +391 -0
- repoglance-0.4.0/assets/demo.tape +17 -0
- repoglance-0.4.0/assets/showcase/flask.svg +312 -0
- repoglance-0.4.0/assets/showcase/httpie.svg +351 -0
- repoglance-0.4.0/assets/showcase/requests.svg +326 -0
- repoglance-0.4.0/docs/index.md +35 -0
- repoglance-0.4.0/editors/vscode/README.md +19 -0
- repoglance-0.4.0/editors/vscode/extension.js +63 -0
- repoglance-0.4.0/editors/vscode/package.json +26 -0
- repoglance-0.4.0/integrations/gitlab-ci.yml +13 -0
- repoglance-0.4.0/mkdocs.yml +7 -0
- repoglance-0.4.0/packaging/homebrew/repoglance.rb +34 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/pyproject.toml +3 -1
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/__init__.py +1 -1
- repoglance-0.4.0/src/repoglance/cache.py +59 -0
- repoglance-0.4.0/src/repoglance/cli.py +242 -0
- repoglance-0.4.0/src/repoglance/complexity.py +129 -0
- repoglance-0.4.0/src/repoglance/config.py +55 -0
- repoglance-0.4.0/src/repoglance/dedup.py +70 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/gitinfo.py +20 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/metrics.py +22 -0
- repoglance-0.4.0/src/repoglance/plugins.py +43 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/report.py +173 -3
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/scanner.py +146 -31
- repoglance-0.4.0/src/repoglance/vendored.py +57 -0
- repoglance-0.4.0/tests/test_v030.py +108 -0
- repoglance-0.4.0/tests/test_v040.py +70 -0
- repoglance-0.2.2/.repoglance-badge.json +0 -1
- repoglance-0.2.2/CHANGELOG.md +0 -41
- repoglance-0.2.2/assets/demo.svg +0 -329
- repoglance-0.2.2/assets/showcase/flask.svg +0 -268
- repoglance-0.2.2/assets/showcase/httpie.svg +0 -311
- repoglance-0.2.2/assets/showcase/requests.svg +0 -290
- repoglance-0.2.2/src/repoglance/cli.py +0 -90
- repoglance-0.2.2/src/repoglance/complexity.py +0 -85
- {repoglance-0.2.2 → repoglance-0.4.0}/.github/workflows/ci.yml +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/.github/workflows/release.yml +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/.github/workflows/repoglance.yml +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/.gitignore +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/.pre-commit-hooks.yaml +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/CONTRIBUTING.md +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/LICENSE +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/RELEASING.md +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/__main__.py +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/badge.py +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/src/repoglance/languages.py +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/tests/test_cli.py +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/tests/test_complexity.py +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/tests/test_features.py +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/tests/test_scanner.py +0 -0
- {repoglance-0.2.2 → repoglance-0.4.0}/tests/test_scanner_extra.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,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 -->
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"schemaVersion": 1, "label": "repoglance", "message": "2.7k loc \u2022 Python", "color": "blue"}
|
|
@@ -0,0 +1,84 @@
|
|
|
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.4.0] - 2026-08-01
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **Duplicate-code detection** (`--duplicates`): sliding line-window hashing
|
|
11
|
+
surfaces copy-paste blocks and a duplication percentage.
|
|
12
|
+
- **Vendored/generated detection**: minified bundles, `_pb2.py`, lock files,
|
|
13
|
+
`node_modules`, and files marked `@generated` are excluded by default;
|
|
14
|
+
`--include-vendored` keeps them.
|
|
15
|
+
- **Ownership** (`--owners`): attributes the top complexity hotspots to authors
|
|
16
|
+
via `git blame`.
|
|
17
|
+
- **Incremental cache** (`--cache <file>`): unchanged files are reused across
|
|
18
|
+
runs by mtime + size, speeding up repeated scans.
|
|
19
|
+
- **Plugin API**: third-party packages can register metrics under the
|
|
20
|
+
`repoglance.metrics` entry-point group; results appear under `plugins`.
|
|
21
|
+
- **Watch mode** (`--watch`): re-render the report whenever files change.
|
|
22
|
+
- Homebrew formula template and a minimal VS Code extension (Problems panel).
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- Git subprocesses now decode as UTF-8, fixing crashes on non-Latin-1 blame
|
|
26
|
+
output on Windows.
|
|
27
|
+
|
|
28
|
+
## [0.3.0] - 2026-08-01
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- **Real cyclomatic complexity across 15+ languages** via `lizard` (C/C++, Java,
|
|
32
|
+
C#, JavaScript, TypeScript, Go, Rust, Ruby, PHP, Swift, Kotlin, Python and
|
|
33
|
+
more). Python keeps an AST fallback; a keyword heuristic remains as last
|
|
34
|
+
resort. Complexity for non-Python languages is now trustworthy, not a guess.
|
|
35
|
+
- **Maintainability index** (0–100), approximate Microsoft MI from complexity,
|
|
36
|
+
size and token counts.
|
|
37
|
+
- **Diff mode** `--since <rev>`: analyze only files changed since a git ref —
|
|
38
|
+
ideal for PRs. The Action exposes it via `diff-base`.
|
|
39
|
+
- **Baselines & regression ratchet**: `--baseline` snapshots a report;
|
|
40
|
+
`--compare` shows health/complexity/TODO/LOC deltas; `--fail-on-regression`
|
|
41
|
+
fails only on new or worse complexity.
|
|
42
|
+
- **SARIF output** (`--sarif`) for GitHub code scanning; the Action can upload
|
|
43
|
+
it (`sarif: true`) so hotspots appear inline on the Files changed tab.
|
|
44
|
+
- **CSV output** (`--csv`) and a **per-directory rollup** (report + JSON).
|
|
45
|
+
- **Config file**: `.repoglance.toml` or `[tool.repoglance]` in pyproject.
|
|
46
|
+
- **Glob include/exclude** (`--include` / `--exclude`) beyond directory names.
|
|
47
|
+
- **Parallel scanning** (`--jobs`) via a thread pool.
|
|
48
|
+
- Docker image, GitLab CI template, and mkdocs docs scaffold.
|
|
49
|
+
|
|
50
|
+
## [0.2.2] - 2026-08-01
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- Respect the repository's `.gitignore`: when scanning a git repo, the file
|
|
54
|
+
list comes from `git ls-files` so ignored files are excluded (matches the
|
|
55
|
+
behavior of `tokei`/`scc`). Non-git directories still use a pruned walk.
|
|
56
|
+
- Count C-style `/* ... */` block comments when classifying lines, improving the
|
|
57
|
+
comment ratio (and therefore the health score) for C-family languages.
|
|
58
|
+
- Expanded test suite: CLI end-to-end (`click` runner), `.gitignore` handling,
|
|
59
|
+
block comments, and inline complexity scoring.
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
- Every file is now read exactly once. Complexity is computed during the scan
|
|
63
|
+
from the text already in memory instead of re-reading every file in a second
|
|
64
|
+
pass — roughly halving I/O on large repositories.
|
|
65
|
+
|
|
66
|
+
## [0.2.1] - 2026-08-01
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
- Marketplace listing name set to a globally-unique title.
|
|
70
|
+
|
|
71
|
+
## [0.2.0] - 2026-08-01
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
- Renamed the PyPI package and CLI to **repoglance** (the GitHub repository is
|
|
75
|
+
unchanged). Only line-comment TODO markers are counted, avoiding false
|
|
76
|
+
positives from prose and marker lists.
|
|
77
|
+
|
|
78
|
+
## [0.1.0] - 2026-08-01
|
|
79
|
+
|
|
80
|
+
### Added
|
|
81
|
+
- Initial release: rich terminal report (languages, complexity hotspots, TODO
|
|
82
|
+
tracker, biggest files, git activity), health score, JSON/Markdown/SVG/HTML
|
|
83
|
+
output, self-contained and dynamic badges, CI gate, GitHub Action, and
|
|
84
|
+
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,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: repoglance
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -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,10 +39,11 @@ 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
|
|
|
42
|
+
[](https://pypi.org/project/repoglance/)
|
|
43
|
+
[](https://pypi.org/project/repoglance/)
|
|
40
44
|
[](https://github.com/SRJ-ai/repoglance/actions/workflows/ci.yml)
|
|
41
|
-
[](https://pypi.org/project/repoglance/)
|
|
42
46
|
[](LICENSE)
|
|
43
|
-
[](CONTRIBUTING.md)
|
|
44
47
|
[](https://github.com/SRJ-ai/repoglance)
|
|
45
48
|
|
|
46
49
|
</div>
|
|
@@ -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) |
|
|
73
|
-
| [httpie](assets/showcase/httpie.svg) |
|
|
74
|
-
| [requests](assets/showcase/requests.svg) |
|
|
75
|
+
| [flask](assets/showcase/flask.svg) | 207 | 25,266 | D (67) |
|
|
76
|
+
| [httpie](assets/showcase/httpie.svg) | 234 | 20,023 | D (66) |
|
|
77
|
+
| [requests](assets/showcase/requests.svg) | 88 | 13,709 | C (70) |
|
|
75
78
|
|
|
76
79
|
<div align="center">
|
|
77
80
|
|
|
@@ -97,12 +100,21 @@ 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 --
|
|
104
|
-
repoglance --
|
|
105
|
-
repoglance --
|
|
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 --duplicates # detect copy-paste blocks
|
|
114
|
+
repoglance --owners # attribute hotspots to authors (git blame)
|
|
115
|
+
repoglance --cache .rg.cache # incremental cache for fast repeat runs
|
|
116
|
+
repoglance --watch # live re-render on file changes
|
|
117
|
+
repoglance --no-git --jobs 8
|
|
106
118
|
```
|
|
107
119
|
|
|
108
120
|
### JSON output
|
|
@@ -118,11 +130,18 @@ repoglance --json | jq '.languages.Python.code'
|
|
|
118
130
|
| Section | What you get |
|
|
119
131
|
|---|---|
|
|
120
132
|
| **Languages** | Lines of code per language, ranked, with % bars |
|
|
121
|
-
| **Complexity hotspots** |
|
|
133
|
+
| **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
|
+
| **Maintainability index** | Approximate MI (0–100) from complexity, size and token counts |
|
|
135
|
+
| **Duplicate code** | Copy-paste blocks across files, with a duplication % |
|
|
122
136
|
| **TODO tracker** | Every `TODO` / `FIXME` / `HACK` / `XXX` / `BUG` with file:line |
|
|
123
|
-
| **Biggest files** |
|
|
137
|
+
| **Biggest files & directories** | Where the mass and the worst complexity live |
|
|
138
|
+
| **Ownership** | Which author owns each hotspot (`--owners`, git blame) |
|
|
124
139
|
| **Git activity** | Top authors, most-churned files, active days, project lifespan |
|
|
125
140
|
|
|
141
|
+
Vendored and generated files (minified bundles, `_pb2.py`, `node_modules`, files
|
|
142
|
+
marked `@generated`) are detected and excluded by default — pass
|
|
143
|
+
`--include-vendored` to keep them.
|
|
144
|
+
|
|
126
145
|
Binary files, `node_modules`, `.venv`, build dirs and friends are skipped
|
|
127
146
|
automatically.
|
|
128
147
|
|
|
@@ -135,14 +154,17 @@ gives you artifacts you can put in a PR or a README.
|
|
|
135
154
|
| | repoglance | tokei | scc | cloc |
|
|
136
155
|
|---|:---:|:---:|:---:|:---:|
|
|
137
156
|
| Lines-of-code by language | ✅ | ✅ | ✅ | ✅ |
|
|
138
|
-
|
|
|
157
|
+
| Per-function complexity (15+ langs) | ✅ | ❌ | ⚠️ file-level | ❌ |
|
|
158
|
+
| Maintainability index | ✅ | ❌ | ❌ | ❌ |
|
|
139
159
|
| TODO / FIXME tracker | ✅ | ❌ | ❌ | ❌ |
|
|
140
160
|
| Git activity (authors, churn) | ✅ | ❌ | ❌ | ❌ |
|
|
141
|
-
|
|
|
161
|
+
| Respects `.gitignore` | ✅ | ✅ | ✅ | ❌ |
|
|
162
|
+
| JSON / CSV / **SARIF** output | ✅ | ⚠️ | ⚠️ | ⚠️ |
|
|
142
163
|
| **HTML / SVG report export** | ✅ | ❌ | ❌ | ❌ |
|
|
143
164
|
| **Embeddable repo badge** | ✅ | ❌ | ❌ | ❌ |
|
|
144
|
-
| **
|
|
145
|
-
|
|
|
165
|
+
| **Diff mode (`--since`) + baselines** | ✅ | ❌ | ❌ | ❌ |
|
|
166
|
+
| **CI gate + regression ratchet** | ✅ | ❌ | ❌ | ❌ |
|
|
167
|
+
| **Config file** (`[tool.repoglance]`) | ✅ | ✅ | ❌ | ❌ |
|
|
146
168
|
|
|
147
169
|
## Share it: badges & reports
|
|
148
170
|
|
|
@@ -235,6 +257,27 @@ repoglance --badge-json .repoglance-badge.json # commit this file
|
|
|
235
257
|
repoglance --md # paste into a PR, wiki, or Slack
|
|
236
258
|
```
|
|
237
259
|
|
|
260
|
+
### Configuration file
|
|
261
|
+
|
|
262
|
+
Set defaults once via `.repoglance.toml` or a `[tool.repoglance]` table in
|
|
263
|
+
`pyproject.toml` (CLI flags always win):
|
|
264
|
+
|
|
265
|
+
```toml
|
|
266
|
+
[tool.repoglance]
|
|
267
|
+
exclude = ["**/*_pb2.py", "vendor/**"]
|
|
268
|
+
max_complexity = 25
|
|
269
|
+
fail_under = 70
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Docker & GitLab
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
docker run --rm -v "$PWD:/repo" repoglance /repo
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
A ready-to-copy GitLab CI job lives in
|
|
279
|
+
[`integrations/gitlab-ci.yml`](integrations/gitlab-ci.yml).
|
|
280
|
+
|
|
238
281
|
## Design goals
|
|
239
282
|
|
|
240
283
|
- **Fast** — a single pass, no external services.
|
|
@@ -8,10 +8,11 @@ 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
|
+
[](https://pypi.org/project/repoglance/)
|
|
12
|
+
[](https://pypi.org/project/repoglance/)
|
|
11
13
|
[](https://github.com/SRJ-ai/repoglance/actions/workflows/ci.yml)
|
|
12
|
-
[](https://pypi.org/project/repoglance/)
|
|
13
15
|
[](LICENSE)
|
|
14
|
-
[](CONTRIBUTING.md)
|
|
15
16
|
[](https://github.com/SRJ-ai/repoglance)
|
|
16
17
|
|
|
17
18
|
</div>
|
|
@@ -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) |
|
|
44
|
-
| [httpie](assets/showcase/httpie.svg) |
|
|
45
|
-
| [requests](assets/showcase/requests.svg) |
|
|
44
|
+
| [flask](assets/showcase/flask.svg) | 207 | 25,266 | D (67) |
|
|
45
|
+
| [httpie](assets/showcase/httpie.svg) | 234 | 20,023 | D (66) |
|
|
46
|
+
| [requests](assets/showcase/requests.svg) | 88 | 13,709 | C (70) |
|
|
46
47
|
|
|
47
48
|
<div align="center">
|
|
48
49
|
|
|
@@ -68,12 +69,21 @@ 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 --
|
|
75
|
-
repoglance --
|
|
76
|
-
repoglance --
|
|
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 --duplicates # detect copy-paste blocks
|
|
83
|
+
repoglance --owners # attribute hotspots to authors (git blame)
|
|
84
|
+
repoglance --cache .rg.cache # incremental cache for fast repeat runs
|
|
85
|
+
repoglance --watch # live re-render on file changes
|
|
86
|
+
repoglance --no-git --jobs 8
|
|
77
87
|
```
|
|
78
88
|
|
|
79
89
|
### JSON output
|
|
@@ -89,11 +99,18 @@ repoglance --json | jq '.languages.Python.code'
|
|
|
89
99
|
| Section | What you get |
|
|
90
100
|
|---|---|
|
|
91
101
|
| **Languages** | Lines of code per language, ranked, with % bars |
|
|
92
|
-
| **Complexity hotspots** |
|
|
102
|
+
| **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) |
|
|
103
|
+
| **Maintainability index** | Approximate MI (0–100) from complexity, size and token counts |
|
|
104
|
+
| **Duplicate code** | Copy-paste blocks across files, with a duplication % |
|
|
93
105
|
| **TODO tracker** | Every `TODO` / `FIXME` / `HACK` / `XXX` / `BUG` with file:line |
|
|
94
|
-
| **Biggest files** |
|
|
106
|
+
| **Biggest files & directories** | Where the mass and the worst complexity live |
|
|
107
|
+
| **Ownership** | Which author owns each hotspot (`--owners`, git blame) |
|
|
95
108
|
| **Git activity** | Top authors, most-churned files, active days, project lifespan |
|
|
96
109
|
|
|
110
|
+
Vendored and generated files (minified bundles, `_pb2.py`, `node_modules`, files
|
|
111
|
+
marked `@generated`) are detected and excluded by default — pass
|
|
112
|
+
`--include-vendored` to keep them.
|
|
113
|
+
|
|
97
114
|
Binary files, `node_modules`, `.venv`, build dirs and friends are skipped
|
|
98
115
|
automatically.
|
|
99
116
|
|
|
@@ -106,14 +123,17 @@ gives you artifacts you can put in a PR or a README.
|
|
|
106
123
|
| | repoglance | tokei | scc | cloc |
|
|
107
124
|
|---|:---:|:---:|:---:|:---:|
|
|
108
125
|
| Lines-of-code by language | ✅ | ✅ | ✅ | ✅ |
|
|
109
|
-
|
|
|
126
|
+
| Per-function complexity (15+ langs) | ✅ | ❌ | ⚠️ file-level | ❌ |
|
|
127
|
+
| Maintainability index | ✅ | ❌ | ❌ | ❌ |
|
|
110
128
|
| TODO / FIXME tracker | ✅ | ❌ | ❌ | ❌ |
|
|
111
129
|
| Git activity (authors, churn) | ✅ | ❌ | ❌ | ❌ |
|
|
112
|
-
|
|
|
130
|
+
| Respects `.gitignore` | ✅ | ✅ | ✅ | ❌ |
|
|
131
|
+
| JSON / CSV / **SARIF** output | ✅ | ⚠️ | ⚠️ | ⚠️ |
|
|
113
132
|
| **HTML / SVG report export** | ✅ | ❌ | ❌ | ❌ |
|
|
114
133
|
| **Embeddable repo badge** | ✅ | ❌ | ❌ | ❌ |
|
|
115
|
-
| **
|
|
116
|
-
|
|
|
134
|
+
| **Diff mode (`--since`) + baselines** | ✅ | ❌ | ❌ | ❌ |
|
|
135
|
+
| **CI gate + regression ratchet** | ✅ | ❌ | ❌ | ❌ |
|
|
136
|
+
| **Config file** (`[tool.repoglance]`) | ✅ | ✅ | ❌ | ❌ |
|
|
117
137
|
|
|
118
138
|
## Share it: badges & reports
|
|
119
139
|
|
|
@@ -206,6 +226,27 @@ repoglance --badge-json .repoglance-badge.json # commit this file
|
|
|
206
226
|
repoglance --md # paste into a PR, wiki, or Slack
|
|
207
227
|
```
|
|
208
228
|
|
|
229
|
+
### Configuration file
|
|
230
|
+
|
|
231
|
+
Set defaults once via `.repoglance.toml` or a `[tool.repoglance]` table in
|
|
232
|
+
`pyproject.toml` (CLI flags always win):
|
|
233
|
+
|
|
234
|
+
```toml
|
|
235
|
+
[tool.repoglance]
|
|
236
|
+
exclude = ["**/*_pb2.py", "vendor/**"]
|
|
237
|
+
max_complexity = 25
|
|
238
|
+
fail_under = 70
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Docker & GitLab
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
docker run --rm -v "$PWD:/repo" repoglance /repo
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
A ready-to-copy GitLab CI job lives in
|
|
248
|
+
[`integrations/gitlab-ci.yml`](integrations/gitlab-ci.yml).
|
|
249
|
+
|
|
209
250
|
## Design goals
|
|
210
251
|
|
|
211
252
|
- **Fast** — a single pass, no external services.
|
|
@@ -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
|
-
|
|
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
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="
|
|
2
|
-
<title>repoglance:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="202" height="20" role="img" aria-label="repoglance: 2.3k loc • Python">
|
|
2
|
+
<title>repoglance: 2.3k loc • Python</title>
|
|
3
3
|
<linearGradient id="s" x2="0" y2="100%">
|
|
4
4
|
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
5
5
|
<stop offset="1" stop-opacity=".1"/>
|
|
6
6
|
</linearGradient>
|
|
7
|
-
<clipPath id="r"><rect width="
|
|
7
|
+
<clipPath id="r"><rect width="202" height="20" rx="3" fill="#fff"/></clipPath>
|
|
8
8
|
<g clip-path="url(#r)">
|
|
9
9
|
<rect width="84" height="20" fill="#555"/>
|
|
10
|
-
<rect x="84" width="
|
|
11
|
-
<rect width="
|
|
10
|
+
<rect x="84" width="118" height="20" fill="#3572A5"/>
|
|
11
|
+
<rect width="202" height="20" fill="url(#s)"/>
|
|
12
12
|
</g>
|
|
13
13
|
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="110" text-rendering="geometricPrecision">
|
|
14
14
|
<text aria-hidden="true" x="418" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="635">repoglance</text>
|
|
15
15
|
<text x="418" y="140" transform="scale(.1)" textLength="635">repoglance</text>
|
|
16
|
-
<text aria-hidden="true" x="
|
|
17
|
-
<text x="
|
|
16
|
+
<text aria-hidden="true" x="1425" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="980">2.3k loc • Python</text>
|
|
17
|
+
<text x="1425" y="140" transform="scale(.1)" textLength="980">2.3k loc • Python</text>
|
|
18
18
|
</g>
|
|
19
19
|
</svg>
|