<#23433 Add `lint` / `check` tools for plugin `@ru...
# github-notifications
q
#23433 Add `lint` / `check` tools for plugin `@rule` definitions Issue created by zach-overflow Problem There are several unique constraints and expectations for
@rule
definitions which are entirely left for the rule author to enforce, such as: 1. Ensuring the `rule`'s input / output types are immutable. 2. Ensuring the attributes of an object return from the
rule
are calculated deterministically (for example, sorting a
tuple
constructed from a
set
before assigning said tuple to an output object's attribute). 3. Ensuring the
rule
does not produce any side effects. All of these constraints make sense, but increase the mental load for plugin development. Obviously, we cannot detect all possible kinds of violations of these
@rule
constraints through static code analysis; however, I believe a large number of common mistakes are detectable through static code analysis. Proposed Solution Add a builtin linter and/or type checker specifically for validation of
@rule
definitions through static analysis, which a user could invoke through something like: pants lint check path/to/plugin/source_root:: A non-exhaustive list of some issues which this toolset could hypothetically catch and prevent through static analysis: 1. Catches the use of any non-frozen dataclasses as inputs and/or outputs. 2. Catches some cases where output instance attribute construction is potentially non-deterministic, for example, the following could potentially be caught: @rule def my_rule(..., ...) -> MyFrozenDataClass: ... # should be changed to
tuple(sorted(unordered_item_set))
return MyFrozenDataClass(items=tuple(unordered_item_set)) 3. Catches
print
statements, and any other very obvious side effect-producing statements in a
rule
body. 4. Catches any obvious attempts to access the file system through unsafe calls like
open
or
pathlib.Path.read_text(...)
. Alternatives Considered I'm not sure if there is a clear alternative, other than hand-writing some of these checks as a suite of unit tests (which I've already done to some small extent for our org's internal development). One potential alternative would be to contribute these checks as a new set of `ruff` rules; however, that seems more burdensome for both pantsbuild and ruff maintainers than simply maintaining this tooling within the pantsbuild repo itself. pantsbuild/pants