Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make --config and --isolated global flags #10150

Merged
merged 19 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
98 changes: 40 additions & 58 deletions crates/ruff/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ pub struct Args {
pub command: Command,
#[clap(flatten)]
AlexWaygood marked this conversation as resolved.
Show resolved Hide resolved
pub log_level_args: LogLevelArgs,
/// Either a path to a TOML configuration file (`pyproject.toml` or `ruff.toml`),
/// or a TOML `<KEY> = <VALUE>` pair
/// (such as you might find in a `ruff.toml` configuration file)
/// overriding a specific configuration option.
/// Overrides of individual settings using this option always take precedence
/// over all configuration files, including configuration files that were also
/// specified using `--config`.
#[arg(
long,
action = clap::ArgAction::Append,
value_name = "CONFIG_OPTION",
value_parser = ConfigArgumentParser,
global = true,
MichaReiser marked this conversation as resolved.
Show resolved Hide resolved
)]
pub config: Vec<SingleConfigArgument>,
/// Ignore all configuration files.
//
// Note: We can't mark this as conflicting with `--config` here
// as `--config` can be used for specifying configuration overrides
// as well as configuration files.
// Specifying a configuration file conflicts with `--isolated`;
// specifying a configuration override does not.
// If a user specifies `ruff check --isolated --config=ruff.toml`,
// we emit an error later on, after the initial parsing by clap.
#[arg(long, help_heading = "Miscellaneous", global = true)]
pub isolated: bool,
}
AlexWaygood marked this conversation as resolved.
Show resolved Hide resolved

#[allow(clippy::large_enum_variant)]
Expand Down Expand Up @@ -161,20 +187,6 @@ pub struct CheckCommand {
preview: bool,
#[clap(long, overrides_with("preview"), hide = true)]
no_preview: bool,
/// Either a path to a TOML configuration file (`pyproject.toml` or `ruff.toml`),
/// or a TOML `<KEY> = <VALUE>` pair
/// (such as you might find in a `ruff.toml` configuration file)
/// overriding a specific configuration option.
/// Overrides of individual settings using this option always take precedence
/// over all configuration files, including configuration files that were also
/// specified using `--config`.
#[arg(
long,
action = clap::ArgAction::Append,
value_name = "CONFIG_OPTION",
value_parser = ConfigArgumentParser,
)]
pub config: Vec<SingleConfigArgument>,
/// Comma-separated list of rule codes to enable (or ALL, to enable all rules).
#[arg(
long,
Expand Down Expand Up @@ -306,17 +318,6 @@ pub struct CheckCommand {
/// Disable cache reads.
#[arg(short, long, env = "RUFF_NO_CACHE", help_heading = "Miscellaneous")]
pub no_cache: bool,
/// Ignore all configuration files.
//
// Note: We can't mark this as conflicting with `--config` here
// as `--config` can be used for specifying configuration overrides
// as well as configuration files.
// Specifying a configuration file conflicts with `--isolated`;
// specifying a configuration override does not.
// If a user specifies `ruff check --isolated --config=ruff.toml`,
// we emit an error later on, after the initial parsing by clap.
#[arg(long, help_heading = "Miscellaneous")]
pub isolated: bool,
/// Path to the cache directory.
#[arg(long, env = "RUFF_CACHE_DIR", help_heading = "Miscellaneous")]
pub cache_dir: Option<PathBuf>,
Expand Down Expand Up @@ -408,20 +409,6 @@ pub struct FormatCommand {
/// difference between the current file and how the formatted file would look like.
#[arg(long)]
pub diff: bool,
/// Either a path to a TOML configuration file (`pyproject.toml` or `ruff.toml`),
/// or a TOML `<KEY> = <VALUE>` pair
/// (such as you might find in a `ruff.toml` configuration file)
/// overriding a specific configuration option.
/// Overrides of individual settings using this option always take precedence
/// over all configuration files, including configuration files that were also
/// specified using `--config`.
#[arg(
long,
action = clap::ArgAction::Append,
value_name = "CONFIG_OPTION",
value_parser = ConfigArgumentParser,
)]
pub config: Vec<SingleConfigArgument>,

/// Disable cache reads.
#[arg(short, long, env = "RUFF_NO_CACHE", help_heading = "Miscellaneous")]
Expand Down Expand Up @@ -462,17 +449,6 @@ pub struct FormatCommand {
/// Set the line-length.
#[arg(long, help_heading = "Format configuration")]
pub line_length: Option<LineLength>,
/// Ignore all configuration files.
//
// Note: We can't mark this as conflicting with `--config` here
// as `--config` can be used for specifying configuration overrides
// as well as configuration files.
// Specifying a configuration file conflicts with `--isolated`;
// specifying a configuration override does not.
// If a user specifies `ruff check --isolated --config=ruff.toml`,
// we emit an error later on, after the initial parsing by clap.
#[arg(long, help_heading = "Miscellaneous")]
pub isolated: bool,
/// The name of the file when passing it through stdin.
#[arg(long, help_heading = "Miscellaneous")]
pub stdin_filename: Option<PathBuf>,
Expand Down Expand Up @@ -643,7 +619,11 @@ impl ConfigurationTransformer for ConfigArguments {
impl CheckCommand {
/// Partition the CLI into command-line arguments and configuration
/// overrides.
pub fn partition(self) -> anyhow::Result<(CheckArguments, ConfigArguments)> {
pub fn partition(
self,
config_flags: Vec<SingleConfigArgument>,
isolated: bool,
) -> anyhow::Result<(CheckArguments, ConfigArguments)> {
let check_arguments = CheckArguments {
add_noqa: self.add_noqa,
diff: self.diff,
Expand All @@ -652,7 +632,6 @@ impl CheckCommand {
exit_zero: self.exit_zero,
files: self.files,
ignore_noqa: self.ignore_noqa,
isolated: self.isolated,
no_cache: self.no_cache,
output_file: self.output_file,
show_files: self.show_files,
Expand Down Expand Up @@ -697,20 +676,24 @@ impl CheckCommand {
};

let config_args =
ConfigArguments::from_cli_arguments(self.config, cli_overrides, self.isolated)?;
ConfigArguments::from_cli_arguments(config_flags, cli_overrides, isolated)?;

Ok((check_arguments, config_args))
}
}

impl FormatCommand {
/// Partition the CLI into command-line arguments and configuration
/// overrides.
pub fn partition(self) -> anyhow::Result<(FormatArguments, ConfigArguments)> {
pub fn partition(
self,
config_flags: Vec<SingleConfigArgument>,
isolated: bool,
) -> anyhow::Result<(FormatArguments, ConfigArguments)> {
let format_arguments = FormatArguments {
check: self.check,
diff: self.diff,
files: self.files,
isolated: self.isolated,
no_cache: self.no_cache,
stdin_filename: self.stdin_filename,
range: self.range,
Expand All @@ -731,7 +714,8 @@ impl FormatCommand {
};

let config_args =
ConfigArguments::from_cli_arguments(self.config, cli_overrides, self.isolated)?;
ConfigArguments::from_cli_arguments(config_flags, cli_overrides, isolated)?;

Ok((format_arguments, config_args))
}
}
Expand Down Expand Up @@ -957,7 +941,6 @@ pub struct CheckArguments {
pub exit_zero: bool,
pub files: Vec<PathBuf>,
pub ignore_noqa: bool,
pub isolated: bool,
pub no_cache: bool,
pub output_file: Option<PathBuf>,
pub show_files: bool,
Expand All @@ -975,7 +958,6 @@ pub struct FormatArguments {
pub no_cache: bool,
pub diff: bool,
pub files: Vec<PathBuf>,
pub isolated: bool,
pub stdin_filename: Option<PathBuf>,
pub range: Option<FormatRange>,
}
Expand Down
7 changes: 2 additions & 5 deletions crates/ruff/src/commands/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,9 @@ pub(crate) fn format(
cli: FormatArguments,
config_arguments: &ConfigArguments,
log_level: LogLevel,
isolated: bool,
) -> Result<ExitStatus> {
let pyproject_config = resolve(
cli.isolated,
config_arguments,
cli.stdin_filename.as_deref(),
)?;
let pyproject_config = resolve(isolated, config_arguments, cli.stdin_filename.as_deref())?;
let mode = FormatMode::from_cli(&cli);
let files = resolve_default_files(cli.files, false);
let (paths, resolver) = python_files_in_path(&files, &pyproject_config, config_arguments)?;
Expand Down
7 changes: 2 additions & 5 deletions crates/ruff/src/commands/format_stdin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@ use crate::ExitStatus;
pub(crate) fn format_stdin(
cli: &FormatArguments,
config_arguments: &ConfigArguments,
isolated: bool,
) -> Result<ExitStatus> {
let pyproject_config = resolve(
cli.isolated,
config_arguments,
cli.stdin_filename.as_deref(),
)?;
let pyproject_config = resolve(isolated, config_arguments, cli.stdin_filename.as_deref())?;

let mut resolver = Resolver::new(&pyproject_config);
warn_incompatible_formatter_settings(&resolver);
Expand Down
39 changes: 24 additions & 15 deletions crates/ruff/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ mod panic;
mod printer;
pub mod resolve;
mod stdin;
mod version;
pub mod version;
AlexWaygood marked this conversation as resolved.
Show resolved Hide resolved

#[derive(Copy, Clone)]
pub enum ExitStatus {
Expand Down Expand Up @@ -127,6 +127,8 @@ pub fn run(
Args {
command,
log_level_args,
config,
isolated,
}: Args,
) -> Result<ExitStatus> {
{
Expand Down Expand Up @@ -198,31 +200,38 @@ pub fn run(
shell.generate(&mut Args::command(), &mut stdout());
Ok(ExitStatus::Success)
}
Command::Check(args) => check(args, log_level),
Command::Format(args) => format(args, log_level),
Command::Check(args) => check(args, log_level, config, isolated),
Command::Format(args) => format(args, log_level, config, isolated),
}
}

fn format(args: FormatCommand, log_level: LogLevel) -> Result<ExitStatus> {
let (cli, config_arguments) = args.partition()?;
fn format(
args: FormatCommand,
log_level: LogLevel,
config_flags: Vec<args::SingleConfigArgument>,
isolated: bool,
) -> Result<ExitStatus> {
let (cli, config_arguments) = args.partition(config_flags, isolated)?;

if is_stdin(&cli.files, cli.stdin_filename.as_deref()) {
commands::format_stdin::format_stdin(&cli, &config_arguments)
commands::format_stdin::format_stdin(&cli, &config_arguments, isolated)
} else {
commands::format::format(cli, &config_arguments, log_level)
commands::format::format(cli, &config_arguments, log_level, isolated)
}
}

pub fn check(args: CheckCommand, log_level: LogLevel) -> Result<ExitStatus> {
let (cli, config_arguments) = args.partition()?;
pub fn check(
args: CheckCommand,
log_level: LogLevel,
config_flags: Vec<args::SingleConfigArgument>,
isolated: bool,
) -> Result<ExitStatus> {
let (cli, config_arguments) = args.partition(config_flags, isolated)?;

// 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_config = resolve::resolve(
cli.isolated,
&config_arguments,
cli.stdin_filename.as_deref(),
)?;
let pyproject_config =
resolve::resolve(isolated, &config_arguments, cli.stdin_filename.as_deref())?;

let mut writer: Box<dyn Write> = match cli.output_file {
Some(path) if !cli.watch => {
Expand Down Expand Up @@ -383,7 +392,7 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result<ExitStatus> {

if matches!(change_kind, ChangeKind::Configuration) {
pyproject_config = resolve::resolve(
cli.isolated,
isolated,
&config_arguments,
cli.stdin_filename.as_deref(),
)?;
Expand Down
5 changes: 5 additions & 0 deletions crates/ruff/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ pub(crate) fn version() -> VersionInfo {
}
}

/// Used for testing the --version command
pub fn version_string() -> String {
format!("{}", version())
}
AlexWaygood marked this conversation as resolved.
Show resolved Hide resolved

AlexWaygood marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(test)]
mod tests {
use insta::{assert_display_snapshot, assert_json_snapshot};
Expand Down