Coder Social home page Coder Social logo

dynlint's Introduction

Dynlint

A tool for running Rust lints from dynamic libraries

cargo install cargo-dynlint dynlint-link

Dynlint is a Rust linting tool, similar to Clippy. But whereas Clippy runs a predetermined, static set of lints, Dynlint runs lints from user-specified, dynamic libraries. Thus, Dynlint allows developers to maintain their own personal lint collections.

Contents

Documentation is also available on how Dynlint works.

Quick start

Running Dynlint

The next three steps install Dynlint and run all of this repository's general-purpose, example lints on a workspace:

  1. Install cargo-dynlint and dynlint-link:

    cargo install cargo-dynlint dynlint-link
  2. Add the following to the workspace's Cargo.toml file:

    [workspace.metadata.dynlint]
    libraries = [
        { git = "https://github.com/khulnasoft-lab/dynlint", pattern = "examples/general/*" },
    ]
  3. Run cargo-dynlint:

    cargo dynlint --all --workspace

In the above example, the libraries are found via workspace metadata, which is the recommended way. For additional ways of finding libraries, see How Dynlint works.

Writing lints

You can start writing your own Dynlint library by running cargo dynlint new new_lint_name. Doing so will produce a loadable library right out of the box. You can verify this as follows:

cargo dynlint new new_lint_name
cd new_lint_name
cargo build
DYNLINT_LIBRARY_PATH=$PWD/target/debug cargo dynlint list --lib new_lint_name

All you have to do is implement the LateLintPass trait and accommodate the symbols asking to be filled in.

Helpful resources for writing lints appear below.

Features

Workspace metadata

A workspace can name the libraries it should be linted with in its Cargo.toml file. Specifically, a workspace's manifest can contain a TOML list under workspace.metadata.dynlint.libraries. Each list entry must have the form of a Cargo git or path dependency, with the following differences:

  • There is no leading package name, i.e., no package =.
  • path entries can contain glob patterns, e.g., *.
  • Any entry can contain a pattern field whose value is a glob pattern. The pattern field indicates the subdirectories that contain Dynlint libraries.

Dynlint downloads and builds each entry, similar to how Cargo downloads and builds a dependency. The resulting target/release directories are searched for files with names of the form that Dynlint recognizes (see Library requirements under How Dynlint works).

As an example, if you include the following in your workspace's Cargo.toml file and run cargo dynlint --all --workspace, Dynlint will run on your workspace all of this repository's example general-purpose lints, as well as the example restriction lint try_io_result.

[workspace.metadata.dynlint]
libraries = [
    { git = "https://github.com/khulnasoft-lab/dynlint", pattern = "examples/general/*" },
    { git = "https://github.com/khulnasoft-lab/dynlint", pattern = "examples/restriction/try_io_result" },
]

Configurable libraries

Libraries can be configured by including a dynlint.toml file in a linted workspace's root directory. The file should encode a toml table whose keys are library names. A library determines how its value in the table (if any) is interpreted.

As an example, a dynlint.toml file with the following contents sets the non_local_effect_before_error_return library's work_limit configuration to 1_000_000:

[non_local_effect_before_error_return]
work_limit = 1_000_000

For instructions on creating a configurable library, see the dynlint_linting documentation.

Conditional compilation

For each library that Dynlint uses to check a crate, Dynlint passes the following to the Rust compiler:

--cfg=dynlint_lib="LIBRARY_NAME"

You can use this feature to allow a lint when Dynlint is used, but also avoid an "unknown lint" warning when Dynlint is not used. Specifically, you can do the following:

#[cfg_attr(dynlint_lib = "LIBRARY_NAME", allow(LINT_NAME))]

Note that LIBRARY_NAME and LINT_NAME may be the same. For an example involving non_thread_safe_call_in_test, see dynlint/src/lib.rs in this repository.

Also note that the just described approach does not work for pre-expansion lints. The only known workaround for pre-expansion lints is allow the compiler's built-in unknown_lints lint. Specifically, you can do the following:

#[allow(unknown_lints)]
#[allow(PRE_EXPANSION_LINT_NAME)]

For an example involving env_cargo_path, see internal/src/examples.rs in this repository.

VS Code integration

Dynlint results can be viewed in VS Code using rust-analyzer. To do so, add the following to your VS Code settings.json file:

    "rust-analyzer.checkOnSave.overrideCommand": [
        "cargo",
        "dynlint",
        "--all",
        "--workspace",
        "--",
        "--all-targets",
        "--message-format=json"
    ]

If you want to use rust-analyzer inside a lint library, you need to add the following to your VS Code settings.json file:

    "rust-analyzer.rustc.source": "discover",

And add the following to the library's Cargo.toml file:

[package.metadata.rust-analyzer]
rustc_private = true

Utilities

The following utilities can be helpful for writing Dynlint libraries:

  • dynlint-link is a wrapper around Rust's default linker (cc) that creates a copy of your library with a filename that Dynlint recognizes.
  • dynlint_library! is a macro that automatically defines the dynlint_version function and adds the extern crate rustc_driver declaration.
  • ui_test is a function that can be used to test Dynlint libraries. It provides convenient access to the compiletest_rs package.
  • clippy_utils is a collection of utilities to make writing lints easier. It is generously made public by the Rust Clippy Developers. Note that, like rustc, clippy_utils provides no stability guarantees for its APIs.

Resources

Helpful resources for writing lints include the following:

MSRV policy

A bump of Dynlint's MSRV will be accompanied by a bump of at least Dynlint's minor version.

Put another way, we strive to preserve Dynlint's MSRV when releasing bug fixes, and to change it only when releasing new features.

dynlint's People

Contributors

gitworkflows avatar actions-user avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.