diff --git a/crates/ruff/tests/integration_test.rs b/crates/ruff/tests/integration_test.rs index 81490045657706..380974918f70e4 100644 --- a/crates/ruff/tests/integration_test.rs +++ b/crates/ruff/tests/integration_test.rs @@ -629,6 +629,42 @@ fn stdin_override_parser_py() { "); } +#[test] +fn stdin_override_parser_py_config() -> Result<()> { + let tempdir = TempDir::new()?; + let pyproject_toml = tempdir.path().join("pyproject.toml"); + fs::write( + &pyproject_toml, + r#" +[tool.ruff] +extension = {ipynb="python"} +"#, + )?; + let mut cmd = RuffCheck::default() + .config(&pyproject_toml) + .args(["--stdin-filename", "F401.ipynb"]) + .build(); + assert_cmd_snapshot!(cmd + .pass_stdin("import os\n"), @" + success: false + exit_code: 1 + ----- stdout ----- + F401 [*] `os` imported but unused + --> F401.ipynb:1:8 + | + 1 | import os + | ^^ + | + help: Remove unused import: `os` + + Found 1 error. + [*] 1 fixable with the `--fix` option. + + ----- stderr ----- + "); + Ok(()) +} + #[test] fn stdin_fix_when_not_fixable_should_still_print_contents() { let mut cmd = RuffCheck::default().args(["--fix"]).build(); diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index 5c204b3a0078ce..59c9be0efe760e 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -564,10 +564,7 @@ impl Configuration { }) .collect() }), - // `--extension` is a hidden command-line argument that isn't supported in configuration - // files at present. - extension: None, - + extension: options.extension.map(ExtensionMapping::from), lint: LintConfiguration::from_options(lint, project_root)?, format: FormatConfiguration::from_options( options.format.unwrap_or_default(), diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index 07011ad66026c4..78e35073a1d043 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -32,7 +32,7 @@ use ruff_linter::rules::{ pycodestyle, pydoclint, pydocstyle, pyflakes, pylint, pyupgrade, ruff, }; use ruff_linter::settings::types::{ - IdentifierPattern, OutputFormat, PythonVersion, RequiredVersion, + IdentifierPattern, Language, OutputFormat, PythonVersion, RequiredVersion, }; use ruff_linter::{RuleSelector, warn_user_once}; use ruff_macros::{CombineOptions, OptionsMetadata}; @@ -282,6 +282,20 @@ pub struct Options { )] pub respect_gitignore: Option, + /// A mapping of custom file extensions to known file types (overridden + /// by the `--extension` command-line flag). + /// + /// Supported file types include `python`, `pyi`, `ipynb`, and `markdown`. + #[option( + default = "{}", + value_type = "dict[str, Language]", + example = r#" + # Add a custom file extension mapped to Python + extension = {rpy="python"} + "# + )] + pub extension: Option>, + // Generic python options /// A list of builtins to treat as defined references, in addition to the /// system builtins. diff --git a/ruff.schema.json b/ruff.schema.json index 1de42c71a9ba7e..8d95d780644f4b 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -177,6 +177,16 @@ "$ref": "#/definitions/RuleSelector" } }, + "extension": { + "description": "A mapping of custom file extensions to known file types (overridden\nby the `--extension` command-line flag).\n\nSupported file types include `python`, `pyi`, `ipynb`, and `markdown`.", + "type": [ + "object", + "null" + ], + "additionalProperties": { + "$ref": "#/definitions/Language" + } + }, "external": { "description": "A list of rule codes or prefixes that are unsupported by Ruff, but should be\npreserved when (e.g.) validating `# noqa` directives. Useful for\nretaining `# noqa` directives that cover plugins not yet implemented\nby Ruff.", "type": [ @@ -1976,6 +1986,15 @@ }, "additionalProperties": false }, + "Language": { + "type": "string", + "enum": [ + "python", + "pyi", + "ipynb", + "markdown" + ] + }, "LineEnding": { "oneOf": [ {