Configuration¶
Pymetrica reads optional threshold and exclusion settings from
[tool.pymetrica] in pyproject.toml.
Where Configuration Comes From¶
CLI commands resolve configuration from the directory being analyzed. Discovery
starts at DIR_PATH and walks through its parents until the Git repository root.
The nearest pyproject.toml containing [tool.pymetrica] wins. A
pyproject.toml without that section is skipped while the search continues.
When no .git marker is present, discovery can continue to the filesystem root.
This supports monorepos: a package can use its own configuration while another
package falls back to a shared repository-level configuration. If no matching
section is found, the loader leaves the in-process Config unchanged. In a
fresh CLI process, those values are the built-in defaults.
For example:
text
repository/
pyproject.toml
packages/
billing/
pyproject.toml
pymetrica run-all packages/billing uses the billing configuration when it
contains [tool.pymetrica]; otherwise discovery continues to the repository
configuration.
Supported Settings¶
Example:
toml
[tool.pymetrica]
aloc_fail_threshold = 30
cc_fail_threshold = 10
hv_fail_threshold = 30
po_all_fail_threshold = 10
po_targeted_fail_threshold = 2
mc_fail_threshold = 25
exclude = ["generated/*", "vendor/*"]
top_findings = 5
Thresholds are positive by default. Set a threshold to 0 when you want to
disable failure gating for that metric. exclude defaults to an empty list,
and top_findings defaults to 5.
| Setting | Default | Compared against | Used by |
|---|---|---|---|
aloc_fail_threshold |
30 |
aloc_percentage greater than the threshold |
aloc, run-all |
cc_fail_threshold |
7 |
lloc_per_cc lower than the threshold |
cc, run-all |
hv_fail_threshold |
30 |
hv_per_lloc greater than the threshold |
hv, run-all |
po_all_fail_threshold |
10 |
all_primitives_percent greater than the threshold |
po, run-all |
po_targeted_fail_threshold |
2 |
targeted_primitives_percent greater than the threshold |
po, run-all |
mc_fail_threshold |
25 |
maintainability_cost greater than the threshold |
mc, run-all |
exclude |
[] |
Relative file paths matched with fnmatch |
run-all, base-stats, aloc, cc, hv, po, mc, li |
top_findings |
5 |
Number of worst files shown in threshold failure messages; 0 disables the lists |
aloc, cc, hv, po, mc, run-all |
Exclude Patterns¶
exclude is evaluated during parsing and skips matching Python files before
metrics are produced.
Important details:
- patterns are matched against each analyzed file path relative to the resolved analysis root
- paths are normalized to forward slashes before matching
- matching uses Python's
fnmatch, so entries such asgenerated/*orlegacy/test_*.pyare valid - layer discovery and folder counts happen separately, so an excluded directory
can still appear as an empty layer or in
folders_number
For example, if pymetrica run-all . resolves the codebase root to src/,
then exclude = ["generated/*"] matches files such as
src/generated/models.py because the relative path being checked is
generated/models.py.
Exit-Code Behavior¶
run-all¶
Threshold exit statuses are enforced by the BASIC_HOOK report backend. The
default BASIC_TERMINAL backend prints values and exits with 0.
run-all -rt BASIC_HOOK combines failures into a single exit code:
1for ALOC2for CC4for HV8for Maintainability Cost16for Primitive Obsession
If more than one threshold fails, the exit code is the sum of the matching values. For example:
5means ALOC and HV failed.24means Primitive Obsession and Maintainability Cost failed.
Instability is always computed, but it is not threshold-gated.
Single-Metric Commands¶
With BASIC_HOOK, single-metric commands exit with their metric-specific code
when their own positive threshold fails:
aloc:1cc:2hv:4mc:8po:16
The li command does not currently support a threshold setting.
Report Type¶
Pymetrica currently ships with three report backends:
text
BASIC_TERMINAL
BASIC_HOOK
JSON
These values are accepted by the -rt / --report-type option on the
reporting commands. BASIC_TERMINAL exits with 0. BASIC_HOOK is used by the
published pre-commit hooks, reports only failed metrics by default, and returns
the threshold-based exit status. JSON returns machine-readable output and
exits with 0; its threshold_exit_status field contains the status that
threshold enforcement would return.
See CLI Reference for the JSON payload and the difference between short and long reports.
Audit Mode¶
-a / --audit is a CLI flag, not a pyproject.toml setting. It requests top
findings and metric guidance regardless of threshold values. It is available on
run-all, aloc, cc, hv, po, and mc. It is not exposed by status,
base-stats, or li.
Audit mode affects report content:
- with
BASIC_TERMINAL, audit mode includes top findings and guidance for threshold-capable metrics regardless of whether they failed - with
BASIC_HOOK, audit mode includes the same findings and guidance even for metrics that pass their thresholds - with
JSON, audit mode includes the same guidance in thefailuresfield
Audit mode does not change hook exit status. BASIC_HOOK exit codes are still
computed from actual threshold failures, while JSON continues to exit with
0.
CI Usage¶
A common pattern is to configure thresholds in the repository and run the full analysis in CI:
bash
pymetrica run-all -rt BASIC_HOOK .
If you only want to gate one metric, use the corresponding single-metric command instead:
bash
pymetrica mc -rt BASIC_HOOK .
Pre-commit Hooks¶
Pymetrica also publishes ready-to-use pre-commit hooks for run-all and the
threshold-capable single-metric commands:
yaml
repos:
- repo: https://github.com/JuanJFarina/pymetrica
rev: v1.6.0
hooks:
- id: pymetrica
- id: pymetrica-mc
- id: pymetrica-po
Available hook IDs today:
pymetricapymetrica-alocpymetrica-ccpymetrica-hvpymetrica-popymetrica-mc
These hooks analyze the repository root (.) and ignore the filename list that
pre-commit normally passes to hooks. Thresholds and exclusions still come
from the repository's own pyproject.toml.
Python API Configuration¶
CLI commands load configuration automatically. Direct library usage must load the target configuration explicitly before parsing:
```python from pymetrica.codebase_parser import parse_codebase from pymetrica.utils.settings import update_config_from_pyproject
project_path = "path/to/project" update_config_from_pyproject(project_path) codebase = parse_codebase(project_path) ```
Without that call, parse_codebase() uses the current in-process Config
values, which are the built-in defaults in a fresh process.
Practical Notes¶
- Threshold evaluation uses the metrics as Pymetrica reports them today. For
example, CC gating is based on
lloc_per_cc, not the rawcc_number, and it fails whenlloc_per_ccis below the configured threshold. PYMETRICA_LOG_LEVELcan be set toDEBUG,INFO,WARNING, orERROR. Invalid or missing values fall back toWARNING.- Analysis commands default
DIR_PATHto the current directory, but an explicit target can be analyzed from anywhere. Configuration discovery starts from that target rather than the shell's working directory. - Exclusion patterns are evaluated relative to the resolved analysis root. When
pymetrica run-all .auto-detectssrc/,app/, or a matching package directory, patterns are relative to that detected folder.