Skip to main content

Integrating DCM Into an Existing Project

One of the most challenging parts of adopting a linter is integrating it into an existing codebase. That's especially true for old projects or projects developed by large teams as the number of warnings may be overwhelming.

This guide describes several techniques and DCM features that can significantly simplify the integration process for your team.

Getting Preview of Current Rule Issues​

To quickly asses the number of issues before integrating the tool, use the preview command.

Console example

By default, dcm init preview runs all available rules.

To change this behavior, pass --severity, --rule-types and --only-fixable options. For example, to get only for Flutter and Bloc rule violations with warning and style severities, pass --severity=warning,style --rule-types=flutter,bloc.

dcm init preview --severity=warning,style --rule-types=flutter,bloc

For more information on "dcm init preview", refer to the Preview documentation.

Enabling a Preset​

Given that DCM currently provides more than 300 rules for various mistakes, style issues and packages, it can be challenging to choose the right set of rules without spending hours going through the whole list.

That's where presets can help. Presets are lists of rules curated by us and updated with each release.

To quickly start with a recommended set of rules, add the following configuration to your analysis_option.yaml file:

analysis_options.yaml
dart_code_metrics:
extends:
- recommended

The recommended preset focuses more on the potential bugs, rather than style issues and once you are ready to add more rules, simply update your configuration:

analysis_options.yaml
dart_code_metrics:
extends:
- recommended
rules:
- members-ordering
- avoid-watch-outside-build
- avoid-passing-bloc-to-bloc

For more information on other presets (or how to create custom presets), refer to the Presets documentation.

Fixing Existing Problems​

Once you've chosen a list of rules, it is time to address the existing issues.

While some of the rules cannot be fixed automatically, some rules come with quick-fixes, that can help you address the issues faster. For example, if you enable the avoid-redundant-async rule and apply a quick-fix, it will remove an async keyword marked as redundant.

For rules that does not provide a quick-fix the main reason behind is that it is impossible to say unequivocally how the problem should be fixed. For example, for avoid-passing-async-when-sync-expected you might want to mark the function sync or pass another function or change the type of the parameter. Another common reason why a rule does not provide a quick-fix is when a fix is too complex and can break your code.

Using Quick-Fixes​

To address rule issues one by one, use IDE quick fixes.

VS Code Quick Fixes

Using "dcm fix"​

While quick-fixes can help you address issues faster, they are limited to a particular file. To help you fix all issues in your project at once, DCM provides a command called dcm fix.

dcm fix lib

Calling this command will address all issues for the enabled rules in a non-conflicting way, meaning that each subsequent fix is not blocked by a previous one even if the code was changed significantly.

dcm fix also helps removing unused code highlighted by dcm check-unused-code. To do so, pass the --type=unused-code option to the command invocation.

dcm fix --type=unused-code lib

For more information on "dcm fix", refer to the Fix documentation.

Using "Fix On Save" in the IDE​

To quickly fix all fixable issues within a particular file, use the "DCM: Fix All Auto-fixable Problems" IDE command or a shortcut ⌘ + Shift + S.

To apply fixes on save, modify the settings.json to the following:

.vscode/settings.json
{
"editor.codeActionsOnSave": {
"source.fixAll": "explicit", // This line enables "fix on save" for the Dart analyzer
"source.dcm.fixAll": "explicit"
}
}

Ignoring Existing Problems​

If you have too many issues and/or don't have time to address them all at once, several techniques can help you with the integration:

Using the Configuration​

Aside from the rule-specific configuration, each rule accepts a common configuration option (exclude and include among them). Those options can be used to scope a rule to a set of specific folders or files.

For any rule to skip a folder(s) (or a set of files), set the exclude configuration option for that rule:

analysis_options.yaml
dart_code_metrics:
rules:
- newline-before-return:
exclude:
- test/**
info

To exclude a folder for all the rules, use the global configuration option called rules-exclude.

If instead you need the rule to apply to a specific folder only (e.g. the test) folder, set the include configuration option:

analysis_options.yaml
dart_code_metrics:
rules:
- newline-before-return:
include:
- test/**

For more information on the rules configuration, refer to the Configuring Rules documentation.

Enabling Baseline​

While excluding folders and files can work in some cases, the main problem with this approach is that it also affects new issues.

To ignore only existing issues, DCM provides a feature called "Baseline". In short, it generates a file with all existing violations and those violations will not be reported by the tool (unless the related code is changed).

dcm init baseline lib

Here is an example of a baseline file:

dcm_baseline.json
{
"date": "2023-04-06 11:21:12.433111Z",
"paths": {
"lib/src/fixes/models/fix_producer.dart": {
"prefer-match-file-name": [
"2dca28e191c53faa330a518d0af4ffc5"
]
},
"lib/src/fixes/correct_source_visitor.dart": {
"no-empty-block": [
"99914b932bd37a50b983c5e7c90ae93b",
"99914b932bd37a50b983c5e7c90ae93b"
],
"prefer-correct-identifier-length": [
"865c0c0b4ab0e063e5caa3387c1a8741",
"865c0c0b4ab0e063e5caa3387c1a8741"
]
}
}
}

The file contains all issues groped by the rule and file, where the issues occurred. This structure allows you to manually remove a particular file or rule violations to address them separately, reducing the number of ignored issues.

For more information on "dcm init baseline", refer to the Baseline documentation.

Disabling a Rule​

If scoping the rules or adding them to the baseline does not work for you, consider temporarily disabling a rule:

analysis_options.yaml
dart_code_metrics:
rules:
- newline-before-return: false
# Or
# - newline-before-return

Synchronizing Your Team​

Integrating a linter is not only about the issues but also about how to ensure everyone works with the same version and in the same environment.

Synchronizing DCM Version​

To ensure that all team members using VS Code have the necessary extensions installed, configure the "Workspace recommended extensions":

  1. Create or update the .vscode/extensions.json file in your project directory.

  2. Add the following configuration:

    {
    "recommendations": ["publisher.dcm"]
    }

Refer to the Workspace recommended extensions documentation for more details.

Ensuring Consistent Executable Versions Across the Team​

To ensure that all team members use the same version of the DCM executable, configure the version constraints in your project's dcm_global.yaml file:

  1. Open or create the dcm_global.yaml file in your project root.

  2. Set the version constraint:

    dcm:
    version: '>=1.15.0 <2.0.0'

For more information on global configuration options, refer to the global configuration documentation.