Contributing to Jarl
Tools
Jarl is written in Rust, so you must install the Rust toolchain.
Jarl relies on Insta to run snapshot tests. You can install it with:
cargo install cargo-instaBasic structure of the repository
The folder crates contains several sub-crates. At the time of writing (October 2025), there are three:
jarlcontains the structure of the command-line tool with which users interact. This is where we can add or modify arguments to be passed to the CLI.jarl-corecontains the “meat” of the linter. It is where the R code is parsed and checked, and where the rules are defined. This is probably the crate you will have to modify.jarl-lspcontains the code to integrate the linter with the Language Server Protocol, which allows editors such as VS Code or Positron to highlight diagnostics and provide “Quick Fix” buttons for example.
Adding or modifying a rule
In this section, all paths refer to files in crates/jarl-core.
List of existing rules
src/lints/mod.rs contains the existing list of rules. Each rule must have a name, belong to one or several categories (PERF, READ, etc.), a FixStatus indicating whether it has a fix and, if so, whether this fix is safe or unsafe, and an optional minimum required R version.
Lint definition
src/lints contains the definition of the rules, along with their associated documentation and tests. It has one subfolder per rule and two mandatory files: <rule_name>.rs (which contains the definition and documentation) and mod.rs (which contains the tests).
If there are snapshot tests for this rule, then a subfolder snapshots will also be created. For example, the folder for the rule any_duplicated looks like this:
src/lints/any_duplicated/
├── any_duplicated.rs
├── mod.rs
└── snapshots
└── jarl__lints__any_duplicated__tests__fix_output.snapAdding a new rule
Adding a new rule requires four main steps:
- Add the new rule to the list in
src/lints/mod.rs. In the same file, also addpub(crate) mod <rulename>; - Add a subfolder with the rule name in
src/lints. Add the documentation and the code for the rule. - Add tests in
src/lints/<rulename>/mod.rs - Add the rule in the
src/analyzefolder. This depends on the initial node in the AST. For instance, for the ruleequals_na, we check the presence of code such asx == NA. Since the top node for this expression is aR_BINARY_EXPRESSION, this rule is ran insrc/analyze/binary_expression.rs.
Useful commands
cargo run --bin jarl -- check demos/foo.R(or any other paths to check). The--in the middle is required to use the CLI in development mode (i.e. without installing it withcargo install)cargo testto run all tests, including snapshot tests.cargo insta testandcargo insta review(if necessary) for snapshot tests only.cargo install --path crates/jarl --profile=release(or--profile=dev) to have a system-wide install and test the crate in other R projects.
Integration tests
When you add a new rule, it is usually sufficient to add tests in the directory of this rule only, e.g. in crates/jarl-core/src/lints/any_duplicated.
However, in some cases you may affect the way users interact with Jarl as a whole, for instance by adding new command line arguments or arguments that can be set in jarl.toml. For those changes, it is important to check that the general behavior of Jarl is correct (check what happens when there are no R files, how TOML and CLI arguments interact, etc.).
Tests for this are stored in crates/jarl-cli/tests/integration. It is likely that you will need to edit one of the files instead of creating a new one. For example, adding an extra argument in crates/jarl-core/toml.rs would require adding tests in crates/jarl-cli/tests/integration/toml.rs.