搜尋套件、儲存庫與 APP 分類

custom_lint 封面
套件詳情v0.8.1

custom_lint

Lint 規則是一種強大的方式,可以改善專案的可維護性。自訂 Lint 讓套件作者與開發者能輕鬆撰寫自訂的 lint 規則。

近 30 天下載
74.8萬
喜歡數
264
Pub 分數
130

安裝套件

flutter pub add custom_lint

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

Custom Lint 是一個 Dart 套件,讓開發者與套件作者能在其 Flutter 與 Dart 項目中建立並整合自訂的 lint 规則。它提供了一個結構化的框架來定義程式碼分析規則,有助於強制執行一致的編碼標準並提升程式碼品質。透過擴展內建的 lint 功能,它支援專案的可維護性與團隊範圍的最佳實務。此套件設計為易於使用,並能與現有的開發工作流程無縫整合。

適用情境

  • 強制執行團隊特定的編碼標準
  • 在大型專案中提升程式碼品質
  • 自動化樣式和模式檢查
  • 為套件建立可重複使用的 lint 規則
  • 將自定義驗證整合到CI流程中

主要特色

  • 自定義 lint 规则的簡單定義
  • 同時支援分析器和檢查器整合
  • 可擴展且可重用的規則結構
  • 清晰的文件和範例
  • 與 Flutter 和 Dart 工具無縫整合

適合對象

  • Dart 套件維護者
  • 團隊負責人開發人員
  • 程式碼品質工程師
  • CI/CD 流水線整合者
  • 靜態分析愛好者

使用建議

  • 需要了解 Dart 分析器 API
  • 可能會稍微增加建構時間
  • 需要仔細測試以避免誤報
  • 最好與現有的 linter 工具搭配使用
  • 不適用於執行時間行為強制

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

[!WARNING] This package is no longer under active development. Please see this comment. The official analysis_server_plugin is now the recommended approach for building custom lints.

custom_lint

Tools for building custom lint rules.

License


Chat on Discord

Index

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.
  • Debugger support. Inspect your lints using the Dart debugger and place breakpoints.
  • Supports hot-reload/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:.
  • Built-in testing mechanism using // expect_lint. See Testing your plugins
  • 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 include custom_lint_builder as a dependency:

    # pubspec.yaml
    name: my_custom_lint_package
    environment:
      sdk: ">=3.0.0 <4.0.0"
    
    dependencies:
      # we will use analyzer for inspecting Dart files
      analyzer:
      analyzer_plugin:
      # custom_lint_builder will give us tools for writing lints
      custom_lint_builder:
    
  • create a lib/<my_package_name>.dart file in your project with the following:

    import 'package:analyzer/error/listener.dart';
    import 'package:custom_lint_builder/custom_lint_builder.dart';
    
    // This is the entrypoint of our custom linter
    PluginBase createPlugin() => _ExampleLinter();
    
    /// A plugin class is used to list all the assists/lints defined by a plugin.
    class _ExampleLinter extends PluginBase {
      /// We list all the custom warnings/infos/errors
      @override
      List<LintRule> getLintRules(CustomLintConfigs configs) => [
            MyCustomLintCode(),
          ];
    }
    
    class MyCustomLintCode extends DartLintRule {
      MyCustomLintCode() : super(code: _code);
    
      /// Metadata about the warning that will show-up in the IDE.
      /// This is used for `// ignore: code` and enabling/disabling the lint
      static const _code = LintCode(
        name: 'my_custom_lint_code',
        problemMessage: 'This is the description of our custom lint',
      );
    
      @override
      void run(
        CustomLintResolver resolver,
        ErrorReporter reporter,
        CustomLintContext context,
      ) {
        // Our lint will highlight all variable declarations with our custom warning.
        context.registry.addVariableDeclaration((node) {
          // "node" exposes metadata about the variable declaration. We could
          // check "node" to show the lint only in some conditions.
    
          // This line tells custom_lint to render a warning at the location of "node".
          // And the warning shown will use our `code` variable defined above as description.
          reporter.atNode(node, code);
        });
      }
    }
    

That's it for defining a custom lint package!

If you're looking for a more advanced example, see the example. This example implements:

  • a lint appearing on all variables of a specific type
  • a quick fix for that lint
  • an "assist" for providing refactoring options.

Let's now use it in an application.

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: ">=3.0.0 <4.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:

screenshot of our custom lints in the IDE

Enabling/disabling and configuring lints

By default, custom_lint enables all installed lints.
But chances are you may want to disable one specific lint, or alternatively, disable all lints besides a few.

This configuration is done in your analysis_options.yaml, but in a slightly different manner.

Configurations are placed within a custom_lint object, as followed:

analyzer:
  plugins:
    - custom_lint

custom_lint:
  rules:
    - my_lint_rule: false # disable this rule

As mentioned before, all lints are enabled by default.

custom_lint:
  # Disable all lints by default
  enable_all_lint_rules: false
  rules:
    - my_lint_rule # only enable my_lint_rule

If you want to change this, you can optionally disable all lints by default:

Last but not least, some lint rules may be configurable. When a lint is configurable, you can configure it in the same place with:

custom_lint:
  rules:
    - my_lint_rule:
      some_parameter: "some value"
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 the following inside their terminal:

$ 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.

Using the Dart debugger and enabling hot-reload

By default, custom_lint does enable hot-reload or give you the necessary information to start the debugger. This is because most users don't need those, and only lint authors do.

If you wish to debug lints, you'll have to update your analysis_options.yaml as followed:

analyzer:
  plugins:
    - custom_lint

custom_lint:
  debug: true
  # Optional, will cause custom_lint to log its internal debug information
  verbose: true

Then, to debug plugins in custom_lint, you need to connect to plugins using "attach" mode in your IDE (cmd+shift+p + Debug: attach to Dart process in VSCode).

When using this command, you will need a VM service URI provided by custom_lint.

There are two possible ways to obtain one:

  • if you started your plugin using custom_lint --watch, it should be visible in the console output.
  • if your plugin is started by your IDE, you can open the custom_lint.log file that custom_lint created next to the pubspec.yaml of your analyzed projects.

In both cases, what you're looking for is logs similar to:

The Dart VM service is listening on http://127.0.0.1:60671/9DS43lRMY90=/
The Dart DevTools debugger and profiler is available at: http://127.0.0.1:60671/9DS43lRMY90=/devtools/#/?uri=ws%3A%2F%2F127.0.0.1%3A60671%2F9DS43lRMY90%3D%2Fws

What you'll want is the first URI. In this example, that is http://127.0.0.1:60671/9DS43lRMY90=/. You can then pass this to your IDE, which should now be able to attach to the plugin.

Testing your plugins
Testing lints

Custom_lint comes with an official testing mechanism for asserting that your plugins correctly work.

Testing lints is straightforward: Simply write a file that should contain lints from your plugin (such as the example folder). Then, using a syntax similar to // ignore, write a // expect_lint: code in the line before your lint:

// expect_lint: riverpod_final_provider
var provider = Provider(...);

When doing this, there are two possible cases:

  • The line after the expect_lint correctly contains the expected lint. In that case, the lint is ignored (similarly to if we used // ignore)
  • The next line does not contain the lint. In that case, the expect_lint comment will have an error.

This allows testing your plugins by simply running custom_lint on your test/example folder. Then, if any expected lint is missing, the command will fail. But if your plugin correctly emits the lint, the command will succeed.

Testing quick fixes and assists

Testing quick fixes and assists is also possible with regular tests by combining them with pkg:analyzer to manually execute the assists or fixes. An example can be found in the Riverpod repository.


Built and maintained by Invertase.

所屬分類

依賴

依賴清單 18 項

原始碼儲存庫

使用此套件的專案