Skip to main content

Calculate Metrics

Reports code metrics.

info

You need to configure metrics entry in the analysis_options.yaml before running this command.

To execute the command, run:

$ dcm calculate-metrics lib # or dcm cm lib

Full command description:

Usage: dcm calculate-metrics [arguments] <directories>
-h, --help Print this usage information.


-r, --reporter="console" (--output-format) Analysis output format.
[console (default), html, json, codeclimate, gitlab, checkstyle, sonar]
-o, --output-dir="OUTPUT" Write HTML output to OUTPUT.
(defaults to "metrics")
--open Automatically open generated HTML report.
--flat Show only a flat list of files (HTML report only).
--output-to="path/to/file" Path to the file with the analysis output.
--report-all Report all metric results (default is to report only high or very high metric levels).


-c, --print-config Print resolved config.


--root-folder="./" Root folder.
(defaults to the current directory)
-s, --sdk-path="directory-path" Dart SDK directory path.
If the project has a `.fvm/flutter_sdk` symlink, it will be used if the SDK is not found.
-e, --exclude="{**/*.g.dart,**/*.freezed.dart}" Files to exclude (in Glob syntax).
(defaults to "{**/*.g.dart,**/*.freezed.dart}")
--root-exclude Files to exclude, relative to the root folder (in Glob syntax).


--[no-]congratulate Show output even when there are no issues.


--verbose Show verbose logs.


--ci-key The license key to run on CI server. Can be provided via DCM_CI_KEY env variable.
--email The email used to purchase the license. Can be provided via DCM_EMAIL env variable.


--no-analytics Disable sending anonymous usage statistics.


--fatal-level="unset" Treat found equal or higher metric level as fatal (unset by default).
[near, high, very-high]

Understanding Metric Thresholds

To understand how metric thresholds work (and the available violation levels), refer to this page.

Reporting All Metric Values

By default only the HTML reporter shows all metric values (below and above) the configured thresholds.

To enable the same output for other reporters, pass the --report-all CLI flag.

Output Example

Console (default)

Use --reporter=console to get output in console format.

Console

HTML

Use --reporter=html to get output in HTML format.

info

To generate a report only for files, use the "--flat" CLI option.

HTML Report Overview

HTML

HTML Single File Report

HTML

PDF Report

To generate a PDF file from the HTML report page, use the browser ctrl+P/cmd+P menu and save the page as PDF.

JSON

Use --reporter=json to get output as a single JSON object containing metadata and the list of metric violations.

Format specification

The root object fields are

  • formatVersion - an integer representing the format version (will be incremented each time the serialization format changes)
  • timestamp - a creation time of the report in YYYY-MM-DD HH:MM:SS format
  • metricResults - an array of objects
  • summary - an array of objects
{
"formatVersion": 10,
"timestamp": "2021-04-11 14:44:42",
"metricResults": [
{
...
},
{
...
},
{
...
}
],
"summary": [
{
...
},
{
...
}
]
}

The result object fields are

  • path - a relative path to the target file
  • issues - an array of metric issues
{
"path": "lib/src/metrics/metric_computation_result.dart",
"issues": {
...
}
}

The issue object fields are

  • id - metric id
  • message - the associated message
  • location - the location associated with the issue
  • effortInMinutes - an estimated effort to fix the issue (in minutes)
  • level - a level of the value computed by the metric
  • value - an actual value computed by the metric
  • unitType - a human readable unit type (optional)
  • declarationName - the name of the declaration (optional)
  • recommendation - a message with information about how the user can improve the value (optional)
{
"id": "cyclomatic-complexity",
"message": "This method has a cyclomatic complexity of 4, which exceeds the maximum of 3 allowed.",
"location": {
...
},
"effortInMinutes": 15,
"level": "high",
"value": 4,
"declarationName": "name"
}

The location object fields are

  • startColumn - the start column of the entity
  • startLine - the start line of the entity
  • endColumn - the end column of the entity
  • endLine - the end line of the entity
  • startOffset - the offset of the entity
{
"endColumn": 2,
"endLine": 90,
"startColumn": 1,
"startLine": 48,
"startOffset": 1638
}

The summary-record object fields are

  • title - a message with information about the record
  • value - an actual value of this record (can be an array or a single value)
  • violations - the number of violations of a metric associated with this record
{
"title": "Scanned folders",
"value": 13
},
{
"title": "Scanned files",
"value": 30
},
{
"title": "Scanned classes",
"value": 71
},
{
"title": "CYCLO",
"value": 207,
"violations": 0
}
Old format specification (prior to DCM 1.26.0)

The root object fields are

  • formatVersion - an integer representing the format version (will be incremented each time the serialization format changes)
  • timestamp - a creation time of the report in YYYY-MM-DD HH:MM:SS format
  • records - an array of objects
  • summary - an array of objects
{
"formatVersion": 2,
"timestamp": "2021-04-11 14:44:42",
"records": [
{
...
},
{
...
},
{
...
}
],
"summary": [
{
...
},
{
...
}
]
}

The record object fields are

  • path - a relative path to the target file
  • fileMetrics - an array with target file metrics
  • classes - a map with class name as the key and class report as the value
  • functions - a map with function name as the key and function report as the value
{
"path": "lib/src/metrics/metric_computation_result.dart",
"classes": {
...
},
"functions": {
...
},
"fileMetrics": {
...
}
}

The summary-record object fields are

  • title - a message with information about the record
  • value - an actual value of this record (can be an array or a single value)
  • violations - a value of a violations count of a metric associated with this record
{
"title": "Average Cyclomatic Number per line of code",
"value": 0.3447098976109215,
"violations": 5
}

The report object fields are

  • codeSpan - a source code span of the target entity
  • metrics - an array with target entity metrics
{
"codeSpan": {
...
},
"metrics": [
...
]
}

The code span object fields are

  • start - a start location of an entity
  • end - an end location of an entity
  • text - a source code text of an entity
{
"start": {
...
},
"end": {
...
},
"text": "entity source code"
}

The location object fields are

  • offset - a zero-based offset of the location in the source
  • line - a zero-based line of the location in the source
  • column - a zero-based column of the location in the source
{
"offset": 156,
"line": 7,
"column": 1
}

The metric value object fields are

  • metricsId - an id of the computed metric
  • value - an actual value computed by the metric
  • unitType - a human readable unit type (optional)
  • level - a level of the value computed by the metric
  • comment - a message with information about the value
  • recommendation - a message with information about how the user can improve the value (optional)
  • context - an additional information associated with the value that helps understand how the metric was computed
{
"metricsId": "number-of-methods",
"value": 14,
"unitType": "methods",
"level": "warning",
"comment": "This class has 14 methods, which exceeds the maximum of 10 allowed.",
"recommendation": "Consider breaking this class up into smaller parts.",
"context": [
...
]
}

The context message object fields are

  • message - an message to be displayed to the user
  • codeSpan - a source code span associated with or referenced by the message
{
"message": "getter complexityEntities increase metric value",
"codeSpan": {
...
}
}

GitLab

Use --reporter=gitlab to get output in a GitLab-compatible format. To learn how to integrate DCM with GitLab, refer to this guide.

Code Climate

Use --reporter=codeclimate to get output in Code Climate format.

Output example
{"type":"issue","check_name":"widgets-nesting-level","description":"Build method has widgets nesting level of 7, which exceeds the maximum of 6 allowed.","categories":["Complexity"],"location":{"path":"lib/src/selectors/color_well.dart","positions":{"begin":{"column":3,"line":106},"end":{"column":4,"line":153}}},"severity":"info","fingerprint":"af5c0190fa59005295c7b3c6feb05547"}
{"type":"issue","check_name":"maximum-nesting-level","description":"This method has a nesting level of 2, which exceeds the maximum of 1 allowed.","categories":["Complexity"],"location":{"path":"lib/src/selectors/graphical_time_picker_painter.dart","positions":{"begin":{"column":3,"line":129},"end":{"column":4,"line":159}}},"severity":"info","fingerprint":"8b7d6bf9360ef83fe9657312127e2693"}

Checkstyle

Use --reporter=checkstyle to get output in Checkstyle format.

Output example
<?xml version="1.0"?>
<checkstyle version="10.0">
<file name="../abstract_class.dart">
<error line="0" message="metric comment" severity="warning" source="file-metric-id"/>
<error line="0" severity="error" message="metric comment" source="id"/>
</file>
<file name="../class_with_factory_constructors.dart">
<error line="0" severity="warning" message="metric comment" source="id"/>
</file>
</checkstyle>
note

Checkstyle format is supported by Bitbucket. To learn how to integrate DCM with Bitbucket, refer to this guide.

Sonar

Use --reporter=sonar to get output in SonarQube's generic format for external issues.

Output example
{
"rules": [
{
"cleanCodeAttribute": "CLEAR",
"description": "To learn more, visit the documentation https://dcm.dev/docs/metrics/function/cyclomatic-complexity",
"engineId": "dcm",
"id": "cyclomatic-complexity",
"impacts": [
{
"severity": "MEDIUM",
"softwareQuality": "MAINTAINABILITY"
}
],
"name": "cyclomatic-complexity"
},
{
"cleanCodeAttribute": "CLEAR",
"description": "To learn more, visit the documentation https://dcm.dev/docs/metrics/function/maximum-nesting-level",
"engineId": "dcm",
"id": "maximum-nesting-level",
"impacts": [
{
"severity": "MEDIUM",
"softwareQuality": "MAINTAINABILITY"
}
],
"name": "maximum-nesting-level"
},
],
"issues": [
{
"primaryLocation": {
"filePath": "lib/src/sheets/macos_sheet.dart",
"message": "This method has a cyclomatic complexity of 4, which exceeds the maximum of 2 allowed.",
"textRange": {
"endColumn": 4,
"endLine": 101,
"startColumn": 3,
"startLine": 52
}
},
"ruleId": "cyclomatic-complexity"
},
{
"effortMinutes": 10,
"primaryLocation": {
"filePath": "lib/src/sheets/macos_sheet.dart",
"message": "This method has a nesting level of 2, which exceeds the maximum of 1 allowed.",
"textRange": {
"endColumn": 4,
"endLine": 210,
"startColumn": 3,
"startLine": 182
}
},
"ruleId": "maximum-nesting-level"
},
],
}