custom_lint
Tools for building custom lint rules.
Tutorial
You can read the latest blog post or watch the advanced use case with custom_lint video
About
Lint rules are a powerful way to improve the maintainability of a project. The more, the merrier! But while Dart offers a wide variety of lint rules by default, it cannot reasonably include every possible lint. For example, Dart does not include lints related to third-party packages.
Custom_lint fixes that by allowing package authors to write custom lint rules.
Custom_lint is similar to analyzer_plugin, but goes deeper by trying to provide a better developer experience.
That includes:
- A command-line to obtain the list of lints in your CI without having to write a command line yourself.
- A simplified project setup.
No need to deal with the
analyzer
server or error handling. Custom_lint takes care of that for you, so that you can focus on writing lints. - Support for hot-restart. Updating the source code of a linter plugin will dynamically restart it, without having to restart your IDE/analyzer server
- Built-in support for
// ignore:
and// ignore_for_file:
. - Support for
print(...)
and exceptions. If your plugin somehow throws or print debug messages, custom_lint will generate a log file with the messages/errors.
Usage
Using custom_lint is split in two parts:
- how to define a custom_lint package
- how users can install our package in their application to see our newly defined lints
Creating a custom lint package
To create a custom lint, you will need two things:
-
updating your
pubspec.yaml
to includecustom_lint_builder
as a dependency:# pubspec.yaml name: my_custom_lint_package environment: sdk: '>=2.16.0 <3.0.0' dependencies: # we will use analyzer for inspecting Dart files analyzer: # custom_lint_builder will give us tools for writing lints custom_lint_builder:
-
create a
bin/custom_lint.dart
file in your project with the following:// This is the entrypoint of our custom linter void main(List<String> args, SendPort sendPort) { startPlugin(sendPort, _ExampleLinter()); } // This class is the one that will analyze Dart files and return lints class _ExampleLinter extends PluginBase { @override Stream<Lint> getLints(ResolvedUnitResult resolvedUnitResult) async* { // A basic lint that shows at the top of the file. yield Lint( code: 'my_custom_lint_code', message: 'This is the description of our custom lint', // Where your lint will appear within the Dart file. // The following code will make appear at the top of the file (offset 0), // and be 10 characters long. location: resolvedUnitResult.lintLocationFromOffset(0, length: 10), ); } }
That’s it for defining a custom lint package!
Let’s use it in an application now.
Using our custom lint package in an application
For users to run custom_lint packages, there are a few steps:
-
The application must contain an
analysis_options.yaml
with the following:analyzer: plugins: - custom_lint
-
The application also needs to add
custom_lint
and our package(s) as dev dependency in their application:# The pubspec.yaml of an application using our lints name: example_app environment: sdk: '>=2.16.0 <3.0.0' dev_dependencies: custom_lint: my_custom_lint_package:
That’s all!
After running pub get
(and possibly restarting their IDE), users should now
see our custom lints in their Dart files:
Obtaining the list of lints in the CI
Unfortunately, running dart analyze
does not pick up our newly defined lints.
We need a separate command for this.
To do that, users of our custom lint package can run inside the application the following:
$ dart run custom_lint
lib/main.dart:0:0 • This is the description of our custom lint • my_custom_lint_code
If you are working on a Flutter project, run flutter pub run custom_lint
instead.
Built and maintained by Invertase.