diff --git a/crates/ruff/tests/analyze_graph.rs b/crates/ruff/tests/analyze_graph.rs index 4d70bf6270..2c300029ea 100644 --- a/crates/ruff/tests/analyze_graph.rs +++ b/crates/ruff/tests/analyze_graph.rs @@ -246,6 +246,59 @@ fn string_detection() -> Result<()> { Ok(()) } +#[test] +fn string_detection_from_config() -> Result<()> { + let tempdir = TempDir::new()?; + + let root = ChildPath::new(tempdir.path()); + + // Configure string import detection with a lower min-dots via ruff.toml + root.child("ruff.toml").write_str(indoc::indoc! {r#" + [analyze] + detect-string-imports = true + string-imports-min-dots = 1 + "#})?; + + root.child("ruff").child("__init__.py").write_str("")?; + root.child("ruff") + .child("a.py") + .write_str(indoc::indoc! {r#" + import ruff.b + "#})?; + root.child("ruff") + .child("b.py") + .write_str(indoc::indoc! {r#" + import importlib + + importlib.import_module("ruff.c") + "#})?; + root.child("ruff").child("c.py").write_str("")?; + + insta::with_settings!({ + filters => INSTA_FILTERS.to_vec(), + }, { + assert_cmd_snapshot!(command().current_dir(&root), @r#" + success: true + exit_code: 0 + ----- stdout ----- + { + "ruff/__init__.py": [], + "ruff/a.py": [ + "ruff/b.py" + ], + "ruff/b.py": [ + "ruff/c.py" + ], + "ruff/c.py": [] + } + + ----- stderr ----- + "#); + }); + + Ok(()) +} + #[test] fn globs() -> Result<()> { let tempdir = TempDir::new()?; diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index d57a170115..54339bd6e7 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -3860,6 +3860,13 @@ pub struct AnalyzeOptions { /// This setting is only relevant when [`detect-string-imports`](#detect-string-imports) is enabled. /// For example, if this is set to `2`, then only strings with at least two dots (e.g., `"path.to.module"`) /// would be considered valid imports. + #[option( + default = "2", + value_type = "usize", + example = r#" + string-imports-min-dots = 2 + "# + )] pub string_imports_min_dots: Option, /// A map from file path to the list of Python or non-Python file paths or globs that should be /// considered dependencies of that file, regardless of whether relevant imports are detected.