Our team uses Conventional Commits when coding and creating PRs. This standard makes it easy for our team to review and identify commits in our repo quickly.
PR titles should follow the format below:
<type>(optional scope): <description>- fix: a commit of the type
fixpatches a bug in the codebase. - feat: a commit of the type
featintroduces a new feature to the codebase. - types other than
fix:andfeat:are allowed, for example @commitlint/config-conventional (based on the the Angular convention) recommendsbuild:,chore:,ci:,docs:,style:,refactor:,perf:,test:, and others.
To create a new rule:
-
Choose a rule name according to our naming guide or take it from existing issue for the rule.
-
Add an
.mdfile with the rule documentation todoc/rules. If the rule supports configuration addbadge, if it has auto-fixes add
badge
-
Create a rule
.dartfile underlib/src/analyzers/lint_analyzer/rules/rules_list. -
Create a class that extends an abstract rule class depending on your rule type. Available classes:
FlutterRule,CommonRule,IntlRule,AngularRule. Add a public field with rule id, documentation url.The class constructor should take
Map<String, Object> configparameter which represents config that is passed to the rule from theanalysis_options.yaml. Example:BinaryExpressionOperandOrderRule([ Map<String, Object> config = const {}, ]) : super( id: ruleId, documentation: Uri.parse(_documentationUrl), severity: readSeverity(config, Severity.style), );
-
Add a visitor class which extends any of the base visitors. Usually you will need
RecursiveAstVisitor. All visitors are listed there. Visitor should be added to a separate file and imported withpartdirective. -
Add methods overrides to the visitor class for nodes that you want to check (ex.
visitBinaryExpression,visitBlock). -
Collect all data needed for the rule (we usually use a private field for data storage and public getter to access it from the
checkmethod). -
In the rule class add override to
checkmethod. Create a visitor instance and visit all compilation unit children with it.Convert data to
Issue's and return them from the method. Example:@override Iterable<Issue> check(Source source) { final visitor = _Visitor(); source.compilationUnit.visitChildren(visitor); return visitor.binaryExpressions .map((lit) => createIssue( this, nodeLocation(lit, source), _warningMessage, Replacement( comment: _correctionComment, replacement: '${lit.rightOperand} ${lit.operator} ${lit.leftOperand}', ), )) .toList(growable: false); }
-
Add the rule to the
lib/src/analyzers/lint_analyzer/rules/rules_factory.dart. Example:final _implementedRules = <String, Rule Function(Map<String, Object>)>{ ... BinaryExpressionOperandOrderRule.ruleId: (config) => BinaryExpressionOperandOrderRule(config: config), ... }
-
Add the rule tests under
test/analyzers/lint_analyzer/rules/rules_list/. Prefer to split test examples to a correct/incorrect groups.
The plugin works in multiple IDEs and is implemented as analysis server plugin. To work on and test IDE/analysis server integration features and issues you will need to load the plugin into analysis server.
To set this up:
-
Clone the repository into
<absolute-path>directory. -
Change the plugin starter
dart_code_metricsdependency intools\analyzer_plugin\pubspec.yamlto a path dependency:name: dart_code_metrics_plugin_loader description: This pubspec determines the version of the analyzer plugin to load. version: 4.6.0 environment: sdk: '>=2.12.0 <3.0.0' dependencies: dart_code_metrics: path: <absolute-path>
-
Do the same in your project(s) you wish to work on
dart-code-metrics: reference it from absolute path. -
Run
dart pub getin:dart_code_metricsworking copytools\analyzer_plugindirectory indart_code_metricsworking copy- your project directory
-
For Visual Studio Code on Windows: delete
C:\Users\<your-windows-user-name>\AppData\Local\.dartServerfolder. -
Start / restart your IDE