diff --git a/.gitignore b/.gitignore index 55de3ba557e24..562d1b4c5a6dd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,11 @@ github_search*.jsonl schemastore .venv* scratch.py +perf.data +perf.data.old +flamegraph.svg +# Additional target directories that don't invalidate the main compile cache when changing linker settings +/target* ### # Rust.gitignore diff --git a/crates/ruff_cli/src/args.rs b/crates/ruff_cli/src/args.rs index 09662c827281a..eb3efc09a5c11 100644 --- a/crates/ruff_cli/src/args.rs +++ b/crates/ruff_cli/src/args.rs @@ -68,7 +68,7 @@ pub enum Command { }, } -#[derive(Debug, clap::Args)] +#[derive(Clone, Debug, clap::Args)] #[allow(clippy::struct_excessive_bools, clippy::module_name_repetitions)] pub struct CheckArgs { /// List of files or directories to check. diff --git a/crates/ruff_cli/src/lib.rs b/crates/ruff_cli/src/lib.rs index a9b53365fb795..4307f742907e1 100644 --- a/crates/ruff_cli/src/lib.rs +++ b/crates/ruff_cli/src/lib.rs @@ -159,7 +159,7 @@ fn format(files: &[PathBuf]) -> Result { Ok(ExitStatus::Success) } -fn check(args: CheckArgs, log_level: LogLevel) -> Result { +pub fn check(args: CheckArgs, log_level: LogLevel) -> Result { let (cli, overrides) = args.partition(); // Construct the "default" settings. These are used when no `pyproject.toml` diff --git a/crates/ruff_dev/src/main.rs b/crates/ruff_dev/src/main.rs index c8beed5fb194c..dbdfb4546693a 100644 --- a/crates/ruff_dev/src/main.rs +++ b/crates/ruff_dev/src/main.rs @@ -4,6 +4,8 @@ use anyhow::Result; use clap::{Parser, Subcommand}; +use ruff::logging::{set_up_logging, LogLevel}; +use ruff_cli::check; mod generate_all; mod generate_cli_help; @@ -27,6 +29,7 @@ struct Args { } #[derive(Subcommand)] +#[allow(clippy::large_enum_variant)] enum Command { /// Run all code and documentation generation steps. GenerateAll(generate_all::Args), @@ -48,6 +51,16 @@ enum Command { PrintTokens(print_tokens::Args), /// Run round-trip source code generation on a given Python file. RoundTrip(round_trip::Args), + /// Run a ruff command n times for profiling/benchmarking + Repeat { + #[clap(flatten)] + args: ruff_cli::args::CheckArgs, + #[clap(flatten)] + log_level_args: ruff_cli::args::LogLevelArgs, + /// Run this many times + #[clap(long, short = 'n')] + repeat: usize, + }, } fn main() -> Result<()> { @@ -64,6 +77,17 @@ fn main() -> Result<()> { Command::PrintCST(args) => print_cst::main(args)?, Command::PrintTokens(args) => print_tokens::main(args)?, Command::RoundTrip(args) => round_trip::main(args)?, + Command::Repeat { + args, + repeat, + log_level_args, + } => { + let log_level = LogLevel::from(log_level_args); + set_up_logging(&log_level)?; + for _ in 0..*repeat { + check(args.clone(), log_level)?; + } + } } Ok(()) }