Dependably.CodeMetrics
0.1.2
dotnet tool install --global Dependably.CodeMetrics --version 0.1.2
dotnet new tool-manifest
dotnet tool install --local Dependably.CodeMetrics --version 0.1.2
#tool dotnet:?package=Dependably.CodeMetrics&version=0.1.2
nuke :add-package Dependably.CodeMetrics --version 0.1.2
codemetrics
Quantitative C# code-quality metrics from one command: cyclomatic and cognitive complexity,
Halstead volume, maintainability index, depth of inheritance, class coupling, LCOM4 cohesion,
and the Robert Martin namespace metrics. Built on Roslyn, so it runs on any repository with no
dotnet restore step. On top of the raw numbers it emits interpreted diagnoses (god class,
fragile base class, unmaintainable hotspot, low cohesion, ...) with a severity you can gate on.
Install
Requires the .NET SDK 8.0 or later.
dotnet tool install --global Dependably.CodeMetrics
This puts the codemetrics command on your PATH.
Usage
codemetrics ./src # human report
codemetrics ./src --format json # JSON on stdout
codemetrics ./src --fail-on severity=high # CI gate: exit 1 if any finding is >= high
<path> is a file, directory, .csproj, or .sln. The human report lists the worst
methods, types, and namespaces by metric, followed by the interpreted diagnoses (god
class, unmaintainable hotspot, low cohesion, ...) and a per-severity summary. Exit code
is 0 (clean), 1 (a finding tripped the --fail-on gate), or 2 (usage error).
Run codemetrics --help for all options (--json, --top, --no-semantic, --exclude,
--config, and the full --fail-on gate).
Configuration (.dependably)
codemetrics reads a shared, suite-wide .dependably JSON file, discovered by walking up from the
analysis target to the repository root (or point at one with --config <file>). It reads the
common section and its own codemetrics section; the tool section overrides common for scalars,
unions the list keys, and merges rules per metric id.
{
"version": 1,
"codemetrics": {
// Per-metric threshold gate. Every metric uses "max" (fail-above) except "mi", which uses
// "min" (fail-below). A severity of "off" disables that metric's gate.
"rules": {
"cyclomatic": ["error", { "max": 25 }],
"cognitive": ["error", { "max": 30 }],
"nesting": ["error", { "max": 5 }],
"lcom4": ["error", { "max": 4 }],
"coupling": ["error", { "max": 20 }],
"mi": ["error", { "min": 20 }]
},
// Gate on interpreted-diagnosis severity (the same ladder --fail-on severity= accepts).
"failOn": { "severity": "high" },
"exclude": ["**/Generated/**", "Migrations"],
// Grandfather specific metric violations so they no longer gate. Selectors are AND-ed;
// codemetrics findings carry path (file glob), symbol (Type or Type.Member), and id (metric).
"exceptions": [
{ "rule": "cyclomatic", "path": "src/Parser/**", "symbol": "Parser.ParseExpression",
"reason": "grandfathered; refactor tracked in #142", "expires": "2027-06-30" }
]
}
}
An exception grandfathers a metric threshold violation, which is a gate input, not one of the
entries in the JSON findings array. Those entries are interpreted diagnoses, a different object,
so no emitted finding is suppressible and every one of them carries "suppressed": false with a
null suppressedBy. That is a known divergence from the shared finding schema, recorded in the §8
divergence table of docs/finding-schema.md in the Dependably spec
repository; closing it needs either
metric violations emitted as findings or an exception-aware severity gate. Do not read a false
here as evidence that an exception failed to apply — check the exit code and the gate instead.
CLI options merge over the file: --fail-on overrides a metric threshold (or severity) and
--exclude extends the globs. .dependably-check is the deprecated alias filename and is still
read (with a stderr warning) during the migration window; the legacy failOn.<metric>: N form is a
deprecated alias for rules: { "<metric>": ["error", { "max": N }] }.
License
Apache-2.0. Part of the Dependably tool suite.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.