codebase-stats 0.0.1__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.
- codebase_stats-0.0.1/PKG-INFO +376 -0
- codebase_stats-0.0.1/README.md +346 -0
- codebase_stats-0.0.1/codebase_stats/__init__.py +148 -0
- codebase_stats-0.0.1/codebase_stats/core.py +240 -0
- codebase_stats-0.0.1/codebase_stats/coverage.py +295 -0
- codebase_stats-0.0.1/codebase_stats/duration.py +245 -0
- codebase_stats-0.0.1/codebase_stats/lowcov.py +204 -0
- codebase_stats-0.0.1/codebase_stats/metrics.py +393 -0
- codebase_stats-0.0.1/codebase_stats/radon.py +264 -0
- codebase_stats-0.0.1/codebase_stats/reporter.py +283 -0
- codebase_stats-0.0.1/codebase_stats/sizes.py +100 -0
- codebase_stats-0.0.1/codebase_stats/tree.py +144 -0
- codebase_stats-0.0.1/codebase_stats/utils.py +86 -0
- codebase_stats-0.0.1/codebase_stats.egg-info/PKG-INFO +376 -0
- codebase_stats-0.0.1/codebase_stats.egg-info/SOURCES.txt +30 -0
- codebase_stats-0.0.1/codebase_stats.egg-info/dependency_links.txt +1 -0
- codebase_stats-0.0.1/codebase_stats.egg-info/entry_points.txt +2 -0
- codebase_stats-0.0.1/codebase_stats.egg-info/requires.txt +11 -0
- codebase_stats-0.0.1/codebase_stats.egg-info/top_level.txt +1 -0
- codebase_stats-0.0.1/pyproject.toml +121 -0
- codebase_stats-0.0.1/setup.cfg +4 -0
- codebase_stats-0.0.1/tests/test_core.py +258 -0
- codebase_stats-0.0.1/tests/test_coverage.py +132 -0
- codebase_stats-0.0.1/tests/test_coverage_gaps.py +545 -0
- codebase_stats-0.0.1/tests/test_duration.py +264 -0
- codebase_stats-0.0.1/tests/test_integration.py +207 -0
- codebase_stats-0.0.1/tests/test_lowcov.py +262 -0
- codebase_stats-0.0.1/tests/test_metrics.py +156 -0
- codebase_stats-0.0.1/tests/test_metrics_mocked.py +651 -0
- codebase_stats-0.0.1/tests/test_sizes.py +110 -0
- codebase_stats-0.0.1/tests/test_tree.py +59 -0
- codebase_stats-0.0.1/tests/test_utils.py +157 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codebase-stats
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Comprehensive codebase analysis library with coverage, metrics, and test duration analysis
|
|
5
|
+
Author-email: Your Name <your.email@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: coverage,metrics,analysis,testing,code-quality
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: radon>=6.0.0
|
|
21
|
+
Requires-Dist: pytest-cov>=4.0
|
|
22
|
+
Requires-Dist: pytest-json-report>=1.5.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-mock>=3.0; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff>=0.3.0; extra == "dev"
|
|
27
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
28
|
+
Requires-Dist: bandit>=1.7.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pip-audit>=2.6.0; extra == "dev"
|
|
30
|
+
|
|
31
|
+
# Codebase Stats
|
|
32
|
+
|
|
33
|
+
[](https://github.com/brunolnetto/codebase-stats/actions)
|
|
34
|
+
[](https://codecov.io/gh/brunolnetto/codebase-stats)
|
|
35
|
+
[](https://www.python.org/downloads/)
|
|
36
|
+
[](LICENSE)
|
|
37
|
+
|
|
38
|
+
**Production-ready code quality metrics analysis library for Python projects.** Comprehensive analysis of coverage, complexity, maintainability, and code structure with automated reporting and quality gates.
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Using uv (recommended)
|
|
46
|
+
uv pip install codebase-stats
|
|
47
|
+
|
|
48
|
+
# Or with pip
|
|
49
|
+
pip install codebase-stats
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Basic Usage
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from codebase_stats import CodebaseStatsReporter
|
|
56
|
+
|
|
57
|
+
# Generate comprehensive metrics report
|
|
58
|
+
reporter = CodebaseStatsReporter(
|
|
59
|
+
coverage_file='coverage.json',
|
|
60
|
+
report_file='report.json',
|
|
61
|
+
radon_root='src',
|
|
62
|
+
fs_root='src',
|
|
63
|
+
tree_root='src'
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Save report to file
|
|
67
|
+
reporter.save_report('metrics_report.txt', include_coverage=True, include_complexity=True)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Command Line Interface
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Full analysis with all metrics
|
|
74
|
+
python cli.py coverage.json --radon-root src --fs-root src
|
|
75
|
+
|
|
76
|
+
# Show specific sections
|
|
77
|
+
python cli.py coverage.json --show coverage complexity mi
|
|
78
|
+
|
|
79
|
+
# List low-coverage files
|
|
80
|
+
python cli.py coverage.json --show list --threshold 80 --top 20
|
|
81
|
+
|
|
82
|
+
# Help
|
|
83
|
+
python cli.py --help
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Features
|
|
87
|
+
|
|
88
|
+
### 📊 Coverage Analysis
|
|
89
|
+
- **Statement & Branch Coverage**: Full coverage metrics from pytest-cov
|
|
90
|
+
- **Coverage Distribution**: Histogram visualization with percentiles (Q1, Q2, Q3, p90, p95, p99)
|
|
91
|
+
- **Low-Coverage Detection**: Identify files below thresholds with automatic prioritization
|
|
92
|
+
- **Pragma Tracking**: Track `# pragma: no cover` usage for documentation
|
|
93
|
+
|
|
94
|
+
### 🔍 Code Complexity
|
|
95
|
+
- **Cyclomatic Complexity (CC)**: Radon integration for function complexity analysis
|
|
96
|
+
- Grade A: 1-5 (ideal)
|
|
97
|
+
- Grade B: 6-10 (acceptable)
|
|
98
|
+
- Grade C+: 11+ (refactor recommended)
|
|
99
|
+
- **Maintainability Index (MI)**: Code readability/maintainability scoring (0-100)
|
|
100
|
+
- **Halstead Metrics**: Bug estimation and code volume analysis
|
|
101
|
+
- **Comment Ratios**: Documentation density analysis
|
|
102
|
+
|
|
103
|
+
### 📈 Code Metrics
|
|
104
|
+
- **File Size Distribution**: Line count per file with outlier detection
|
|
105
|
+
- **Directory Structure Analysis**: Module organization and hierarchy
|
|
106
|
+
- **Test Duration Distribution**: Identify slow tests
|
|
107
|
+
- **Quality Gates**: Automated threshold validation
|
|
108
|
+
|
|
109
|
+
### 📋 Reporting
|
|
110
|
+
- **Histogram Visualization**: ASCII histograms with customizable bins and scaling
|
|
111
|
+
- **Blame Sections**: Highlight problematic files (Q3 + 1.5×IQR threshold)
|
|
112
|
+
- **Percentile Analysis**: Q1, median, Q3, p90, p95, p99
|
|
113
|
+
- **Structured Output**: Markdown, text, or programmatic JSON
|
|
114
|
+
|
|
115
|
+
## Documentation
|
|
116
|
+
|
|
117
|
+
- **[Architecture Documentation](docs/ARCHITECTURE.md)** - System design, data flows, and component details
|
|
118
|
+
- **[Development Roadmap](development/ROADMAP.md)** - Release planning and feature roadmap
|
|
119
|
+
- **[Architecture Decision Records](development/adr)** - Design decisions and rationales
|
|
120
|
+
- **[Governance & Quality Gates](GOVERNANCE.md)** - Development workflow and CI/CD policies
|
|
121
|
+
|
|
122
|
+
## API Reference
|
|
123
|
+
|
|
124
|
+
### Core Classes
|
|
125
|
+
|
|
126
|
+
#### `CodebaseStatsReporter`
|
|
127
|
+
Main interface for generating comprehensive metrics reports.
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from codebase_stats import CodebaseStatsReporter
|
|
131
|
+
|
|
132
|
+
reporter = CodebaseStatsReporter(
|
|
133
|
+
coverage_file: str, # Path to coverage.json
|
|
134
|
+
report_file: str = None, # Path to pytest report.json (optional)
|
|
135
|
+
radon_root: str = None, # Root for CC/MI/comment analysis
|
|
136
|
+
fs_root: str = None, # Root for file size analysis
|
|
137
|
+
tree_root: str = None # Root for structure analysis
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Methods
|
|
141
|
+
reporter.save_report(filename, include_coverage=True, include_complexity=True)
|
|
142
|
+
reporter.get_stats() -> dict # Get raw metrics dictionary
|
|
143
|
+
report_text = str(reporter) # Generate text report
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Data Structure
|
|
147
|
+
|
|
148
|
+
#### Coverage Stats Dictionary
|
|
149
|
+
```python
|
|
150
|
+
stats = {
|
|
151
|
+
"coverages_sorted": [float], # All file coverage %
|
|
152
|
+
"proj_pct": float, # Project-wide coverage %
|
|
153
|
+
"proj_total": int, # Total lines
|
|
154
|
+
"proj_covered": int, # Covered lines
|
|
155
|
+
"file_stats": [
|
|
156
|
+
{
|
|
157
|
+
"pct": float, # File coverage %
|
|
158
|
+
"path": str, # File path
|
|
159
|
+
"missing_count": int, # Missing line count
|
|
160
|
+
"missing_lines": [int], # Missing line numbers
|
|
161
|
+
"cc_avg": float, # Avg cyclomatic complexity
|
|
162
|
+
"mi": float, # Maintainability index
|
|
163
|
+
"comment_ratio": float, # Comment/SLOC ratio
|
|
164
|
+
"hal_bugs": float, # Halstead bug estimate
|
|
165
|
+
"size_lines": int, # File line count
|
|
166
|
+
...
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Module APIs
|
|
173
|
+
|
|
174
|
+
#### `coverage.py` - Coverage Analysis
|
|
175
|
+
```python
|
|
176
|
+
from codebase_stats.coverage import load_coverage, precompute_coverage_stats
|
|
177
|
+
|
|
178
|
+
stats = load_coverage('coverage.json')
|
|
179
|
+
stats = precompute_coverage_stats(stats, radon_root='src')
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### `metrics.py` - Complexity Metrics
|
|
183
|
+
```python
|
|
184
|
+
from codebase_stats.metrics import get_cyclomatic_complexity, get_maintainability, get_comments_ratio
|
|
185
|
+
|
|
186
|
+
cc = get_cyclomatic_complexity('file.py')
|
|
187
|
+
mi = get_maintainability('file.py')
|
|
188
|
+
ratio = get_comments_ratio('file.py')
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### `radon.py` - Radon Integration
|
|
192
|
+
```python
|
|
193
|
+
from codebase_stats.radon import get_cc_list, get_mi_list, get_metrics
|
|
194
|
+
|
|
195
|
+
cc_data = get_cc_list('src')
|
|
196
|
+
mi_data = get_mi_list('src')
|
|
197
|
+
hal_data = get_metrics('src')
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### `reporter.py` - Report Generation
|
|
201
|
+
```python
|
|
202
|
+
from codebase_stats.reporter import CodebaseStatsReporter
|
|
203
|
+
|
|
204
|
+
reporter = CodebaseStatsReporter(...)
|
|
205
|
+
reporter.save_report('output.txt') # Save formatted report
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### `utils.py` - Utilities
|
|
209
|
+
```python
|
|
210
|
+
from codebase_stats.utils import ascii_histogram, percentile, format_value
|
|
211
|
+
|
|
212
|
+
hist_str = ascii_histogram(data, bins=10, width=80)
|
|
213
|
+
p95 = percentile(data, 0.95)
|
|
214
|
+
formatted = format_value(value, decimals=2)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Quality Gates
|
|
218
|
+
|
|
219
|
+
All code must meet these thresholds:
|
|
220
|
+
|
|
221
|
+
| Metric | Threshold | Rationale |
|
|
222
|
+
|--------|-----------|-----------|
|
|
223
|
+
| **Coverage** | 100% | All source code must be tested |
|
|
224
|
+
| **Cyclomatic Complexity** | ≤10 average | Grade B maintainability |
|
|
225
|
+
| **Maintainability Index** | ≥50 | Grade A minimum |
|
|
226
|
+
| **File Size** | ≤400 lines | Modules remain manageable |
|
|
227
|
+
|
|
228
|
+
## Development Workflow
|
|
229
|
+
|
|
230
|
+
### Setup
|
|
231
|
+
```bash
|
|
232
|
+
# Clone repository
|
|
233
|
+
git clone https://github.com/brunolnetto/codebase-stats.git
|
|
234
|
+
cd codebase-stats
|
|
235
|
+
|
|
236
|
+
# Install with dev dependencies
|
|
237
|
+
uv venv
|
|
238
|
+
uv pip install -e ".[dev]"
|
|
239
|
+
|
|
240
|
+
# Activate environment
|
|
241
|
+
source .venv/bin/activate
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Testing
|
|
245
|
+
```bash
|
|
246
|
+
# Run all tests
|
|
247
|
+
pytest
|
|
248
|
+
|
|
249
|
+
# With coverage
|
|
250
|
+
pytest --cov=codebase_stats --cov-report=term-plus
|
|
251
|
+
|
|
252
|
+
# Specific test file
|
|
253
|
+
pytest tests/test_coverage.py -v
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Code Quality
|
|
257
|
+
```bash
|
|
258
|
+
# Linting
|
|
259
|
+
ruff check codebase_stats/ tests/
|
|
260
|
+
|
|
261
|
+
# Format check
|
|
262
|
+
ruff format --check codebase_stats/ tests/
|
|
263
|
+
|
|
264
|
+
# Type checking
|
|
265
|
+
mypy codebase_stats/
|
|
266
|
+
|
|
267
|
+
# All quality checks
|
|
268
|
+
make quality
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Commits & PRs
|
|
272
|
+
|
|
273
|
+
This project uses **GitFlow** workflow with **conventional commits**:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Feature branches
|
|
277
|
+
git checkout -b feat/feature-name
|
|
278
|
+
# Fix branches
|
|
279
|
+
git checkout -b fix/issue-name
|
|
280
|
+
# Chore/documentation
|
|
281
|
+
git checkout -b chore/update-name
|
|
282
|
+
|
|
283
|
+
# Commit format: <type>(<scope>): <description>
|
|
284
|
+
git commit -m "feat(coverage): add pragma tracking"
|
|
285
|
+
git commit -m "fix(radon): handle empty files gracefully"
|
|
286
|
+
git commit -m "docs(readme): add API reference"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
See [Development Policy](GOVERNANCE.md) for full workflow details.
|
|
290
|
+
|
|
291
|
+
## Architecture Highlights
|
|
292
|
+
|
|
293
|
+
**Data Flow:**
|
|
294
|
+
```
|
|
295
|
+
Raw Input (coverage.json, report.json)
|
|
296
|
+
↓
|
|
297
|
+
load_coverage() → Enrich with Radon metrics
|
|
298
|
+
↓
|
|
299
|
+
precompute_coverage_stats() → Compute distributions
|
|
300
|
+
↓
|
|
301
|
+
Display Functions → Histograms, tables, blame sections
|
|
302
|
+
↓
|
|
303
|
+
Reporter → Formatted text/markdown output
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Key Design Patterns:**
|
|
307
|
+
- **Single Responsibility**: Each module handles one analysis type
|
|
308
|
+
- **Composition**: Reporter combines multiple analysis modules
|
|
309
|
+
- **Lazy Evaluation**: Radon metrics computed on-demand
|
|
310
|
+
- **Immutable Data**: Stats dicts treated as read-only
|
|
311
|
+
- **Histogram Abstraction**: Consistent visualization across metrics
|
|
312
|
+
|
|
313
|
+
See [Architecture Documentation](docs/ARCHITECTURE.md) for detailed system design.
|
|
314
|
+
|
|
315
|
+
## Examples
|
|
316
|
+
|
|
317
|
+
### Generate Full Metrics Report
|
|
318
|
+
```bash
|
|
319
|
+
# After running tests
|
|
320
|
+
pytest --cov=src --cov-report=json
|
|
321
|
+
|
|
322
|
+
# Generate and save report
|
|
323
|
+
python cli.py coverage.json \
|
|
324
|
+
--radon-root src \
|
|
325
|
+
--fs-root src \
|
|
326
|
+
--tree-root src \
|
|
327
|
+
--report metrics_report.txt
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Analyze Coverage Gaps
|
|
331
|
+
```bash
|
|
332
|
+
python cli.py coverage.json --show coverage gaps
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Monitor Complexity Trends
|
|
336
|
+
```python
|
|
337
|
+
from codebase_stats import CodebaseStatsReporter
|
|
338
|
+
|
|
339
|
+
def check_complexity_trend():
|
|
340
|
+
reporter = CodebaseStatsReporter('coverage.json', radon_root='src')
|
|
341
|
+
stats = reporter.get_stats()
|
|
342
|
+
|
|
343
|
+
cc_values = [f['cc_avg'] for f in stats['file_stats']]
|
|
344
|
+
avg_cc = sum(cc_values) / len(cc_values)
|
|
345
|
+
|
|
346
|
+
if avg_cc > 10:
|
|
347
|
+
print(f"⚠️ Complexity increasing: {avg_cc:.2f}")
|
|
348
|
+
else:
|
|
349
|
+
print(f"✅ Complexity healthy: {avg_cc:.2f}")
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Contributing
|
|
353
|
+
|
|
354
|
+
1. See [Development Roadmap](development/ROADMAP.md) for planned work
|
|
355
|
+
2. Submit PRs against `develop` branch (GitFlow)
|
|
356
|
+
3. All PRs require passing quality gates and 100% test coverage
|
|
357
|
+
4. Follow [Governance](GOVERNANCE.md) for workflow details
|
|
358
|
+
|
|
359
|
+
## License
|
|
360
|
+
|
|
361
|
+
MIT License - see LICENSE file for details
|
|
362
|
+
|
|
363
|
+
## Metrics Definitions
|
|
364
|
+
|
|
365
|
+
| Metric | Range | Interpretation |
|
|
366
|
+
|--------|-------|-----------------|
|
|
367
|
+
| **Coverage** | 0-100% | Percentage of code lines executed by tests |
|
|
368
|
+
| **CC** | 1-50+ | Function branching complexity; A≤5, B≤10, C≤15, D≤20, E/F>20 |
|
|
369
|
+
| **MI** | 0-100 | Code readability/maintainability; A≥20, B≥10, C≥0 |
|
|
370
|
+
| **Comment Ratio** | 0-100% | Percentage of code that is comments/docstrings |
|
|
371
|
+
| **Halstead Bugs** | 0-N | Estimated number of bugs; lower is better |
|
|
372
|
+
| **File Size** | Lines | Module size; target ≤400 for maintainability |
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
**Status**: Production-ready · **Latest Release**: 1.0.0 · **Python**: 3.12+
|