Analyze Widgets
Reports the quality and usage of your widgets.
Shows the number widgets / blocs / context.read / context.watch being used, the number of widgets using a particular widget, similar widgets and a widget quality score (based on code metrics).
To execute the command, run:
$ dcm analyze-widgets lib # or dcm aw lib
This command uses metrics configuration from the analysis_options.yaml
file and uses the following configuration as a fallback configuration:
cyclomatic-complexity: 20
halstead-volume: 300
maintainability-index: 50
maximum-nesting-level: 5
number-of-parameters: 6
source-lines-of-code: 50
Full command description:
Usage: dcm analyze-widgets [arguments] <directories>
-h, --help Print this usage information.
--show-similarity Include similar widgets into the report.
--threshold Set a minimum threshold after which widgets are considered similar.
(defaults to "0.2")
-r, --reporter=<console> Analysis output format.
[console (default), html, json, codeclimate, gitlab, checkstyle]
-a, --absolute-path Use absolute path for console reporter output.
-o, --output-directory=<OUTPUT> Write HTML output to OUTPUT.
(defaults to "widgets_report")
--open Automatically open generated HTML report
--json-path=<path/to/file.json> Path to the JSON file with the analysis output.
--report-all Report all widgets (default is to report only medium or low quality widgets, works only for the console reporter).
-c, --print-config Print resolved config.
--root-folder=<./> Root folder.
(defaults to the current directory)
--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.
--exclude=<{**/*.g.dart,**/*.freezed.dart}> File paths in Glob syntax to be exclude.
(defaults to "{**/*.g.dart,**/*.freezed.dart}")
--no-congratulate Don't 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=<low> Treat given or lower quality level as fatal.
[low, medium]
Detecting similar widgets (disabled by default)
To include similar widgets into the report, pass --show-similarity
CLI flag.
Similarity report includes:
- name of the similar widget
- source code of the similar widget with highlighted subtree matches
- similarity percentage of the build method widget tree
- list of the matching widgets subtree
By default, a pair of widgets is considered similar if their subtrees match more than 20%.
You can customize this threshold via the --threshold
CLI option.
Report example
Highlighted subtree example
Output example
Console
Use --reporter=console
to enable this format.
HTML
Use --reporter=html
to enable this format.
HTML report overview
HTML single file report
JSON
The reporter prints a single JSON object containing meta information and the violations grouped by a file. Use --reporter=json
to enable this format.
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 formatrecords
- an array of objectssummary
- 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 filewidgets
- an array with target file widgets
{
"path": "lib/src/widgets/some_widget_file.dart",
"widgets": {
...
},
}
The summary-record object fields are
title
- a message with information about the recordvalue
- an actual value of this record (is a single value)
{
"title": "Scanned folders",
"value": 50,
}
The widget object fields are
blocs
- an array of used blocs (strings)codeSpan
- a source code span of the target entityfromRead
- an array of classes from context.read (strings)fromWatch
- an array of classes from context.watch (strings)interfaces
- an array of used interfaces (strings)level
- widget quality levelmethodMetrics
an array of method metricsmixins
- an array of used mixins (strings)name
- widget namescore
- quality scoresimilarWidgets
- an array of similar widgetstopLevelMetrics
- an array of top level metricstype
- widget typeusedBy
- an array of used widgets (strings)usedWidgets
- an array of used widgets
{
"blocs": [],
"codeSpan": {
...
},
"fromRead": ["SomeClass"],
"fromWatch": ["AnotherClass"],
"interfaces": [],
"level": "High",
"methodMetrics": [
...
],
"mixins": [],
"name": "MyWidget",
"score": 0.83,
"topLevelMetrics": [
...
],
"usedBy": ["SomeWidget", "AnotherWidget"],
"usedWidgets": [
...
]
}
The code span object fields are
start
- a start location of an entityend
- an end location of an entitytext
- 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 sourceline
- a zero-based line of the location in the sourcecolumn
- a zero-based column of the location in the source
{
"offset": 156,
"line": 7,
"column": 1
}
The method metrics object fields are
codeSpan
- a source code span associated with the methodlevel
- method quality levelmetrics
- an array of top level metricsname
- method namescore
- method quality score
{
"codeSpan": {
...
},
"level": "Medium",
"metrics": [
...
],
"name": "build",
"score": 0.80
}
The top level metrics object fields are
isInverted
- whether the level value should be inverted (High
means bad)level
- metric quality levelname
- method namevalue
- method quality score
{
"isInverted": false,
"level": "Medium",
"name": "cyclomatic-complexity",
"value": 20
}
The similar widgets object fields are
widget
- the name of the similar widgetsimilarity
- similarity score
{
"widget": "AnotherWidget",
"similarity": 0.6
}
The used widget object fields are
path
- absolute path to widgetreferences
- number of referencestype
- widget type (local, external, flutter)
{
"path": "/path/to/used/widget.dart",
"references": 5,
"type": "local"
}
GitLab and Code Climate
GitLab and Code Climate formats are also supported. Refer to the analyze commands docs to set up them.
Checkstyle
Use --reporter=checkstyle
to enable this format.
<?xml version="1.0"?>
<checkstyle version="10.0">
<file name="../abstract_class.dart">
<error line="0" severity="warning" message="someWidget quality score is 20% (low quality)" source="widget-quality-report"/>
</file>
<file name="../class_with_factory_constructors.dart">
<error line="0" severity="warning" message="anotherWidget quality score is 20% (low quality)" source="widget-quality-report"/>
</file>
</checkstyle>