Skip to content

Commit eceffe7

Browse files
authored
Deprecate ruff <path> ruff --explain, ruff --clean and ruff --generate-shell-completion (#10169)
1 parent c73c497 commit eceffe7

File tree

6 files changed

+46
-39
lines changed

6 files changed

+46
-39
lines changed

crates/ruff/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ pub fn run(
128128
command,
129129
log_level_args,
130130
}: Args,
131+
deprecated_alias_warning: Option<&'static str>,
131132
) -> Result<ExitStatus> {
132133
{
133134
let default_panic_hook = std::panic::take_hook();
@@ -158,6 +159,10 @@ pub fn run(
158159
let log_level = LogLevel::from(&log_level_args);
159160
set_up_logging(&log_level)?;
160161

162+
if let Some(deprecated_alias_warning) = deprecated_alias_warning {
163+
warn_user!("{}", deprecated_alias_warning);
164+
}
165+
161166
match command {
162167
Command::Version { output_format } => {
163168
commands::version::version(output_format)?;

crates/ruff/src/main.rs

+29-22
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,42 @@ pub fn main() -> ExitCode {
2727
let mut args =
2828
argfile::expand_args_from(args, argfile::parse_fromfile, argfile::PREFIX).unwrap();
2929

30-
// Clap doesn't support default subcommands but we want to run `check` by
31-
// default for convenience and backwards-compatibility, so we just
32-
// preprocess the arguments accordingly before passing them to Clap.
33-
if let Some(arg) = args.get(1) {
34-
if arg
35-
.to_str()
36-
.is_some_and(|arg| !Command::has_subcommand(rewrite_legacy_subcommand(arg)))
30+
// We can't use `warn_user` here because logging isn't set up at this point
31+
// and we also don't know if the user runs ruff with quiet.
32+
// Keep the message and pass it to `run` that is responsible for emitting the warning.
33+
let deprecated_alias_warning = match args.get(1).and_then(|arg| arg.to_str()) {
34+
// Deprecated aliases that are handled by clap
35+
Some("--explain") => {
36+
Some("`ruff --explain <RULE>` is deprecated. Use `ruff rule <RULE>` instead.")
37+
}
38+
Some("--clean") => {
39+
Some("`ruff --clean` is deprecated. Use `ruff clean` instead.")
40+
}
41+
Some("--generate-shell-completion") => {
42+
Some("`ruff --generate-shell-completion <SHELL>` is deprecated. Use `ruff generate-shell-completion <SHELL>` instead.")
43+
}
44+
// Deprecated `ruff` alias to `ruff check`
45+
// Clap doesn't support default subcommands but we want to run `check` by
46+
// default for convenience and backwards-compatibility, so we just
47+
// preprocess the arguments accordingly before passing them to Clap.
48+
Some(arg) if !Command::has_subcommand(arg)
3749
&& arg != "-h"
3850
&& arg != "--help"
3951
&& arg != "-V"
4052
&& arg != "--version"
41-
&& arg != "help"
42-
{
43-
args.insert(1, "check".into());
44-
}
45-
}
53+
&& arg != "help" => {
54+
55+
{
56+
args.insert(1, "check".into());
57+
Some("`ruff <path>` is deprecated. Use `ruff check <path>` instead.")
58+
}
59+
},
60+
_ => None
61+
};
4662

4763
let args = Args::parse_from(args);
4864

49-
match run(args) {
65+
match run(args, deprecated_alias_warning) {
5066
Ok(code) => code.into(),
5167
Err(err) => {
5268
#[allow(clippy::print_stderr)]
@@ -65,12 +81,3 @@ pub fn main() -> ExitCode {
6581
}
6682
}
6783
}
68-
69-
fn rewrite_legacy_subcommand(cmd: &str) -> &str {
70-
match cmd {
71-
"--explain" => "rule",
72-
"--clean" => "clean",
73-
"--generate-shell-completion" => "generate-shell-completion",
74-
cmd => cmd,
75-
}
76-
}

crates/ruff/tests/deprecation.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ const STDIN: &str = "l = 1";
1212
fn ruff_check(show_source: Option<bool>, output_format: Option<String>) -> Command {
1313
let mut cmd = Command::new(get_cargo_bin(BIN_NAME));
1414
let output_format = output_format.unwrap_or(format!("{}", SerializationFormat::default(false)));
15-
cmd.arg("--output-format");
16-
cmd.arg(output_format);
17-
cmd.arg("--no-cache");
15+
cmd.arg("check")
16+
.arg("--output-format")
17+
.arg(output_format)
18+
.arg("--no-cache");
1819
match show_source {
1920
Some(true) => {
2021
cmd.arg("--show-source");

crates/ruff/tests/integration_test.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ impl<'a> RuffCheck<'a> {
7171
/// Generate a [`Command`] for the `ruff check` command.
7272
fn build(self) -> Command {
7373
let mut cmd = ruff_cmd();
74+
cmd.arg("check");
7475
if let Some(output_format) = self.output_format {
7576
cmd.args(["--output-format", output_format]);
7677
}
@@ -805,13 +806,13 @@ fn full_output_format() {
805806
}
806807

807808
#[test]
808-
fn explain_status_codes_f401() {
809-
assert_cmd_snapshot!(ruff_cmd().args(["--explain", "F401"]));
809+
fn rule_f401() {
810+
assert_cmd_snapshot!(ruff_cmd().args(["rule", "F401"]));
810811
}
811812

812813
#[test]
813-
fn explain_status_codes_ruf404() {
814-
assert_cmd_snapshot!(ruff_cmd().args(["--explain", "RUF404"]), @r###"
814+
fn rule_invalid_rule_name() {
815+
assert_cmd_snapshot!(ruff_cmd().args(["rule", "RUF404"]), @r###"
815816
success: false
816817
exit_code: 2
817818
----- stdout -----
@@ -1348,7 +1349,7 @@ fn unreadable_pyproject_toml() -> Result<()> {
13481349

13491350
// Don't `--isolated` since the configuration discovery is where the error happens
13501351
let args = Args::parse_from(["", "check", "--no-cache", tempdir.path().to_str().unwrap()]);
1351-
let err = run(args).err().context("Unexpected success")?;
1352+
let err = run(args, None).err().context("Unexpected success")?;
13521353
assert_eq!(
13531354
err.chain()
13541355
.map(std::string::ToString::to_string)

crates/ruff/tests/lint.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
1212
use tempfile::TempDir;
1313

1414
const BIN_NAME: &str = "ruff";
15-
const STDIN_BASE_OPTIONS: &[&str] = &["--no-cache", "--output-format", "concise"];
15+
const STDIN_BASE_OPTIONS: &[&str] = &["check", "--no-cache", "--output-format", "concise"];
1616

1717
fn tempdir_filter(tempdir: &TempDir) -> String {
1818
format!(r"{}\\?/?", escape(tempdir.path().to_str().unwrap()))
@@ -246,7 +246,6 @@ OTHER = "OTHER"
246246
}, {
247247
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
248248
.current_dir(tempdir.path())
249-
.arg("check")
250249
.args(STDIN_BASE_OPTIONS)
251250
.args(["--config", &ruff_toml.file_name().unwrap().to_string_lossy()])
252251
// Explicitly pass test.py, should be linted regardless of it being excluded by lint.exclude
@@ -293,7 +292,6 @@ inline-quotes = "single"
293292
}, {
294293
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
295294
.current_dir(tempdir.path())
296-
.arg("check")
297295
.args(STDIN_BASE_OPTIONS)
298296
.args(["--config", &ruff_toml.file_name().unwrap().to_string_lossy()])
299297
.args(["--stdin-filename", "generated.py"])
@@ -386,7 +384,6 @@ inline-quotes = "single"
386384
}, {
387385
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
388386
.current_dir(tempdir.path())
389-
.arg("check")
390387
.args(STDIN_BASE_OPTIONS)
391388
.args(["--config", &ruff_toml.file_name().unwrap().to_string_lossy()])
392389
.args(["--stdin-filename", "generated.py"])
@@ -435,7 +432,6 @@ inline-quotes = "single"
435432
}, {
436433
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
437434
.current_dir(tempdir.path())
438-
.arg("check")
439435
.args(STDIN_BASE_OPTIONS)
440436
.args(["--config", &ruff_toml.file_name().unwrap().to_string_lossy()])
441437
.args(["--stdin-filename", "generated.py"])
@@ -495,7 +491,6 @@ ignore = ["D203", "D212"]
495491
}, {
496492
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
497493
.current_dir(sub_dir)
498-
.arg("check")
499494
.args(STDIN_BASE_OPTIONS)
500495
, @r###"
501496
success: true
@@ -921,7 +916,6 @@ include = ["*.ipy"]
921916
}, {
922917
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
923918
.current_dir(tempdir.path())
924-
.arg("check")
925919
.args(STDIN_BASE_OPTIONS)
926920
.args(["--config", &ruff_toml.file_name().unwrap().to_string_lossy()])
927921
.args(["--extension", "ipy:ipynb"])

crates/ruff/tests/snapshots/integration_test__explain_status_codes_f401.snap renamed to crates/ruff/tests/snapshots/integration_test__rule_f401.snap

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ source: crates/ruff/tests/integration_test.rs
33
info:
44
program: ruff
55
args:
6-
- "--explain"
6+
- rule
77
- F401
88
---
99
success: true
@@ -68,4 +68,3 @@ else:
6868
- [Typing documentation: interface conventions](https://typing.readthedocs.io/en/latest/source/libraries.html#library-interface-public-and-private-symbols)
6969

7070
----- stderr -----
71-

0 commit comments

Comments
 (0)