diff --git a/README.md b/README.md index bcdc7b9e78..d7655e3d5e 100644 --- a/README.md +++ b/README.md @@ -347,15 +347,14 @@ an equivalent schema (though the `[tool.ruff]` hierarchy can be omitted). For ex `pyproject.toml` described above would be represented via the following `ruff.toml`: ```toml -# Enable Pyflakes and pycodestyle rules. -select = ["E", "F"] +# Enable flake8-bugbear (`B`) rules. +select = ["E", "F", "B"] # Never enforce `E501` (line length violations). ignore = ["E501"] -# Always autofix, but never try to fix `F401` (unused imports). -fix = true -unfixable = ["F401"] +# Avoid trying to fix flake8-bugbear (`B`) violations. +unfixable = ["B"] # Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`. [per-file-ignores] @@ -365,15 +364,18 @@ unfixable = ["F401"] For a full list of configurable options, see the [API reference](#reference). -Some common configuration settings can be provided via the command-line: +### Command-line interface + +Some configuration settings can be provided via the command-line, such as those related to +rule enablement and disablement, file discovery, logging level, and more: ```shell -ruff path/to/code/ --select F401 --select F403 +ruff path/to/code/ --select F401 --select F403 --quiet ``` -See `ruff --help` for more: +See `ruff help` for more on Ruff's top-level commands: - + ``` Ruff: An extremely fast Python linter. @@ -396,7 +398,78 @@ Log levels: For help with a specific command, see: `ruff help `. ``` - + + +Or `ruff help check` for more on the linting command: + + +``` +Run Ruff on the given files or directories + +Usage: ruff check [OPTIONS] [FILES]... + +Arguments: + [FILES]... List of files or directories to check + +Options: + --fix Attempt to automatically fix lint violations + --show-source Show violations with source code + --diff Avoid writing any fixed files back; instead, output a diff for each changed file to stdout + -w, --watch Run in watch mode by re-running whenever files change + --fix-only Fix any fixable lint violations, but don't report on leftover violations. Implies `--fix` + --format Output serialization format for violations [env: RUFF_FORMAT=] [possible values: text, json, junit, grouped, github, gitlab, pylint] + --config Path to the `pyproject.toml` or `ruff.toml` file to use for configuration + --statistics Show counts for every rule with at least one violation + --add-noqa Enable automatic additions of `noqa` directives to failing lines + --show-files See the files Ruff will be run against with the current settings + --show-settings See the settings Ruff will use to lint a given Python file + -h, --help Print help + +Rule selection: + --select + Comma-separated list of rule codes to enable (or ALL, to enable all rules) + --ignore + Comma-separated list of rule codes to disable + --extend-select + Like --select, but adds additional rule codes on top of the selected ones + --extend-ignore + Like --ignore, but adds additional rule codes on top of the ignored ones + --per-file-ignores + List of mappings from file pattern to code to exclude + --fixable + List of rule codes to treat as eligible for autofix. Only applicable when autofix itself is enabled (e.g., via `--fix`) + --unfixable + List of rule codes to treat as ineligible for autofix. Only applicable when autofix itself is enabled (e.g., via `--fix`) + +File selection: + --exclude List of paths, used to omit files and/or directories from analysis + --extend-exclude Like --exclude, but adds additional files and directories on top of those already excluded + --respect-gitignore Respect file exclusions via `.gitignore` and other standard ignore files + --force-exclude Enforce exclusions, even for paths passed to Ruff directly on the command-line + +Rule configuration: + --target-version + The minimum Python version that should be supported + --line-length + Set the line-length for length-associated rules and automatic formatting + --dummy-variable-rgx + Regular expression matching the name of dummy variables + +Miscellaneous: + -n, --no-cache + Disable cache reads + --isolated + Ignore all configuration files + --cache-dir + Path to the cache directory [env: RUFF_CACHE_DIR=] + --stdin-filename + The name of the file when passing it through stdin + -e, --exit-zero + Exit with status code "0", even upon detecting lint violations + --update-check + Enable or disable automatic update checks +``` + ### `pyproject.toml` discovery diff --git a/ruff_cli/src/lib.rs b/ruff_cli/src/lib.rs index bded7a5bf1..b434f6fbd0 100644 --- a/ruff_cli/src/lib.rs +++ b/ruff_cli/src/lib.rs @@ -1,5 +1,5 @@ //! This library only exists to enable the Ruff internal tooling (`ruff_dev`) -//! to automatically update the `ruff --help` output in the `README.md`. +//! to automatically update the `ruff help` output in the `README.md`. //! //! For the actual Ruff library, see [`ruff`]. #![forbid(unsafe_code)] @@ -10,7 +10,26 @@ mod args; use clap::CommandFactory; -/// Returns the output of `ruff --help`. -pub fn help() -> String { +/// Returns the output of `ruff help`. +pub fn command_help() -> String { args::Args::command().render_help().to_string() } + +/// Returns the output of `ruff help check`. +pub fn subcommand_help() -> String { + let output = args::Args::command() + .find_subcommand_mut("check") + .expect("`check` subcommand not found") + .render_help() + .to_string(); + + // Replace the header, to fix Clap's omission of "ruff" on the "Usage: check" line. + let header = + "Run Ruff on the given files or directories (default)\n\nUsage: check [OPTIONS] [FILES]..."; + let replacement = + "Run Ruff on the given files or directories\n\nUsage: ruff check [OPTIONS] [FILES]..."; + let output = output + .strip_prefix(header) + .expect("`output` does not start expected header"); + format!("{replacement}{output}") +} diff --git a/ruff_dev/Cargo.toml b/ruff_dev/Cargo.toml index c3cfdc5ab2..e5e77f0a2e 100644 --- a/ruff_dev/Cargo.toml +++ b/ruff_dev/Cargo.toml @@ -15,7 +15,7 @@ rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/ rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "4f38cb68e4a97aeea9eb19673803a0bd5f655383" } rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "4f38cb68e4a97aeea9eb19673803a0bd5f655383" } schemars = { version = "0.8.11" } -serde_json = {version="1.0.91"} +serde_json = { version = "1.0.91" } strum = { version = "0.24.1", features = ["strum_macros"] } strum_macros = { version = "0.24.3" } textwrap = { version = "0.16.0" } diff --git a/ruff_dev/src/generate_cli_help.rs b/ruff_dev/src/generate_cli_help.rs index a88ba32827..d137eb47c5 100644 --- a/ruff_dev/src/generate_cli_help.rs +++ b/ruff_dev/src/generate_cli_help.rs @@ -1,11 +1,14 @@ //! Generate CLI help. -use anyhow::Result; - use crate::utils::replace_readme_section; +use anyhow::Result; +use std::str; -const HELP_BEGIN_PRAGMA: &str = ""; -const HELP_END_PRAGMA: &str = ""; +const COMMAND_HELP_BEGIN_PRAGMA: &str = ""; +const COMMAND_HELP_END_PRAGMA: &str = ""; + +const SUBCOMMAND_HELP_BEGIN_PRAGMA: &str = ""; +const SUBCOMMAND_HELP_END_PRAGMA: &str = ""; #[derive(clap::Args)] pub struct Args { @@ -19,15 +22,25 @@ fn trim_lines(s: &str) -> String { } pub fn main(args: &Args) -> Result<()> { - let output = trim_lines(ruff_cli::help().trim()); + // Generate `ruff help`. + let command_help = trim_lines(ruff_cli::command_help().trim()); + + // Generate `ruff help check`. + let subcommand_help = trim_lines(ruff_cli::subcommand_help().trim()); if args.dry_run { - print!("{output}"); + print!("{command_help}"); + print!("{subcommand_help}"); } else { replace_readme_section( - &format!("```\n{output}\n```\n"), - HELP_BEGIN_PRAGMA, - HELP_END_PRAGMA, + &format!("```\n{command_help}\n```\n"), + COMMAND_HELP_BEGIN_PRAGMA, + COMMAND_HELP_END_PRAGMA, + )?; + replace_readme_section( + &format!("```\n{subcommand_help}\n```\n"), + SUBCOMMAND_HELP_BEGIN_PRAGMA, + SUBCOMMAND_HELP_END_PRAGMA, )?; }