Skip to main content
Teams

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
info

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

Similarity report example

Highlighted subtree example

Highlighted subtree example

Output example

Console

Use --reporter=console to enable this format.

Console

HTML

Use --reporter=html to enable this format.

HTML report overview

HTML

HTML single file report

HTML

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 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
  • widgets - 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 record
  • value - 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 entity
  • fromRead - 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 level
  • methodMetrics an array of method metrics
  • mixins - an array of used mixins (strings)
  • name - widget name
  • score - quality score
  • similarWidgets - an array of similar widgets
  • topLevelMetrics - an array of top level metrics
  • type - widget type
  • usedBy - 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 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 method metrics object fields are

  • codeSpan - a source code span associated with the method
  • level - method quality level
  • metrics - an array of top level metrics
  • name - method name
  • score - 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 level
  • name - method name
  • value - method quality score
{
"isInverted": false,
"level": "Medium",
"name": "cyclomatic-complexity",
"value": 20
}

The similar widgets object fields are

  • widget - the name of the similar widget
  • similarity - similarity score
{
"widget": "AnotherWidget",
"similarity": 0.6
}

The used widget object fields are

  • path - absolute path to widget
  • references - number of references
  • type - 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>