diff --git a/src/cli.rs b/src/cli.rs index 9d69d87bfb..af81b54ec0 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -120,7 +120,7 @@ pub struct Cli { pub autoformat: bool, /// The name of the file when passing it through stdin. #[arg(long)] - pub stdin_filename: Option, + pub stdin_filename: Option, /// Explain a rule. #[arg(long)] pub explain: Option, @@ -203,7 +203,7 @@ pub struct Arguments { pub show_files: bool, pub show_settings: bool, pub silent: bool, - pub stdin_filename: Option, + pub stdin_filename: Option, pub verbose: bool, pub watch: bool, } diff --git a/src/main.rs b/src/main.rs index 22d92f7ac8..ebb7f3707e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,18 +35,27 @@ use path_absolutize::path_dedot; /// Resolve the relevant settings strategy and defaults for the current /// invocation. -fn resolve(config: Option, overrides: &Overrides) -> Result { +fn resolve( + config: Option<&Path>, + overrides: &Overrides, + stdin_filename: Option<&Path>, +) -> Result { if let Some(pyproject) = config { // First priority: the user specified a `pyproject.toml` file. Use that // `pyproject.toml` for _all_ configuration, and resolve paths relative to the // current working directory. (This matches ESLint's behavior.) - let settings = resolve_settings(&pyproject, &Relativity::Cwd, Some(overrides))?; + let settings = resolve_settings(pyproject, &Relativity::Cwd, Some(overrides))?; Ok(PyprojectDiscovery::Fixed(settings)) - } else if let Some(pyproject) = pyproject::find_pyproject_toml(path_dedot::CWD.as_path())? { - // Second priority: find a `pyproject.toml` file in the current working path, - // and resolve all paths relative to that directory. (With - // `Strategy::Hierarchical`, we'll end up finding the "closest" `pyproject.toml` - // file for every Python file later on, so these act as the "default" settings.) + } else if let Some(pyproject) = pyproject::find_pyproject_toml( + stdin_filename + .as_ref() + .unwrap_or(&path_dedot::CWD.as_path()), + )? { + // Second priority: find a `pyproject.toml` file in either an ancestor of + // `stdin_filename` (if set) or the current working path all paths relative to + // that directory. (With `Strategy::Hierarchical`, we'll end up finding + // the "closest" `pyproject.toml` file for every Python file later on, + // so these act as the "default" settings.) let settings = resolve_settings(&pyproject, &Relativity::Parent, Some(overrides))?; Ok(PyprojectDiscovery::Hierarchical(settings)) } else if let Some(pyproject) = pyproject::find_user_pyproject_toml() { @@ -85,7 +94,11 @@ fn inner_main() -> Result { // Construct the "default" settings. These are used when no `pyproject.toml` // files are present, or files are injected from outside of the hierarchy. - let pyproject_strategy = resolve(cli.config, &overrides)?; + let pyproject_strategy = resolve( + cli.config.as_deref(), + &overrides, + cli.stdin_filename.as_deref(), + )?; // Extract options that are included in `Settings`, but only apply at the top // level. @@ -207,9 +220,8 @@ fn inner_main() -> Result { // Generate lint violations. let diagnostics = if is_stdin { - let filename = cli.stdin_filename.unwrap_or_else(|| "-".to_string()); - let path = Path::new(&filename); - commands::run_stdin(&pyproject_strategy, path, autofix)? + let path = cli.stdin_filename.unwrap_or_else(|| PathBuf::from("-")); + commands::run_stdin(&pyproject_strategy, &path, autofix)? } else { commands::run( &cli.files,