feat: update scripts to new rules structure (#2078)

- optional `prefix` argument for `add_plugin.py`
- rules directory instead of `rules.rs`
- pathlib syntax
- fix test case where code was added instead of name

Example:
```
python scripts/add_plugin.py --url https://pypi.org/project/example/1.0.0/ example --prefix EXA
python scripts/add_rule.py --name SecondRule --code EXA002 --linter example
python scripts/add_rule.py --name FirstRule --code EXA001 --linter example
python scripts/add_rule.py --name ThirdRule --code EXA003 --linter example
 ```

Note that it breaks compatibility with 'old style' plugins (generation works fine, but namespaces need to be changed):
```
python scripts/add_rule.py --name DoTheThing --code PLC999 --linter pylint
```
This commit is contained in:
Simon Brugman 2023-01-22 01:19:58 +01:00 committed by GitHub
parent 325faa8e18
commit 28f05aa6e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 57 deletions

View file

@ -6,6 +6,7 @@ Example usage:
python scripts/add_plugin.py \
flake8-pie \
--url https://pypi.org/project/flake8-pie/0.16.0/
--prefix PIE
"""
import argparse
@ -14,19 +15,18 @@ import os
from _utils import ROOT_DIR, dir_name, get_indent, pascal_case
def main(*, plugin: str, url: str) -> None:
def main(*, plugin: str, url: str, prefix_code: str) -> None:
# Create the test fixture folder.
os.makedirs(
ROOT_DIR / "resources/test/fixtures" / dir_name(plugin),
exist_ok=True,
)
# Create the Rust module.
rust_module = ROOT_DIR / "src/rules" / dir_name(plugin)
os.makedirs(rust_module, exist_ok=True)
with open(rust_module / "rules.rs", "w+") as fp:
fp.write("use crate::checkers::ast::Checker;\n")
with open(rust_module / "mod.rs", "w+") as fp:
# Create the Plugin rules module.
plugin_dir = ROOT_DIR / "src/rules" / dir_name(plugin)
plugin_dir.mkdir(exist_ok=True)
with (plugin_dir / "mod.rs").open("w+") as fp:
fp.write(f"//! Rules from [{plugin}]({url}).\n")
fp.write("pub(crate) mod rules;\n")
fp.write("\n")
@ -59,14 +59,24 @@ mod tests {
% dir_name(plugin)
)
# Create a subdirectory for rules and create a `mod.rs` placeholder
rules_dir = plugin_dir / "rules"
rules_dir.mkdir(exist_ok=True)
with (rules_dir / "mod.rs").open("w+") as fp:
fp.write("\n\n")
# Create the snapshots subdirectory
(plugin_dir / "snapshots").mkdir(exist_ok=True)
# Add the plugin to `rules/mod.rs`.
with open(ROOT_DIR / "src/rules/mod.rs", "a") as fp:
with (ROOT_DIR / "src/rules/mod.rs").open("a") as fp:
fp.write(f"pub mod {dir_name(plugin)};")
# Add the relevant sections to `src/registry.rs`.
content = (ROOT_DIR / "src/registry.rs").read_text()
with open(ROOT_DIR / "src/registry.rs", "w") as fp:
with (ROOT_DIR / "src/registry.rs").open("w") as fp:
for line in content.splitlines():
indent = get_indent(line)
@ -75,33 +85,19 @@ mod tests {
fp.write("\n")
elif line.strip() == '#[prefix = "RUF"]':
fp.write(f'{indent}#[prefix = "TODO"]\n')
fp.write(f'{indent}#[prefix = "{prefix_code}"]\n')
fp.write(f"{indent}{pascal_case(plugin)},")
fp.write("\n")
elif line.strip() == "Linter::Ruff => Prefixes::Single(RuleSelector::RUF),":
prefix = 'todo!("Fill-in prefix after generating codes")'
fp.write(
f"{indent}Linter::{pascal_case(plugin)} => Prefixes::Single({prefix}),"
f"{indent}Linter::{pascal_case(plugin)} => Prefixes::Single(RuleSelector::{prefix_code}),"
)
fp.write("\n")
fp.write(line)
fp.write("\n")
# Add the relevant section to `src/violations.rs`.
content = (ROOT_DIR / "src/violations.rs").read_text()
with open(ROOT_DIR / "src/violations.rs", "w") as fp:
for line in content.splitlines():
if line.strip() == "// Ruff":
indent = get_indent(line)
fp.write(f"{indent}// {plugin}")
fp.write("\n")
fp.write(line)
fp.write("\n")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
@ -122,6 +118,13 @@ if __name__ == "__main__":
type=str,
help="The URL of the latest release in PyPI.",
)
parser.add_argument(
"--prefix",
required=False,
default="TODO",
type=str,
help="Prefix code for the plugin. Leave empty to manually fill.",
)
args = parser.parse_args()
main(plugin=args.plugin, url=args.url)
main(plugin=args.plugin, url=args.url, prefix_code=args.prefix)