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
fix
patches a bug in the codebase. - feat: a commit of the type
feat
introduces 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
.md
file with the rule documentation todoc/rules
. If the rule supports configuration add badge, if it has auto-fixes add badge -
Create a rule
.dart
file 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> config
parameter 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 withpart
directive. -
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
check
method). -
In the rule class add override to
check
method. 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_metrics
dependency intools\analyzer_plugin\pubspec.yaml
to 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 get
in:dart_code_metrics
working copytools\analyzer_plugin
directory indart_code_metrics
working copy- your project directory
-
For Visual Studio Code on Windows: delete
C:\Users\<your-windows-user-name>\AppData\Local\.dartServer
folder. -
Start / restart your IDE