use anyhow::Result;
use clap::CommandFactory;
use clap::{error::ErrorKind::ArgumentConflict, Parser};
use env_logger::Env;
use log::Level;
use crate::audit;
use crate::basic_measure::measure;
use crate::config::bump_epoch;
use crate::config_cmd;
use crate::git::git_interop::check_git_version;
use crate::git::git_interop::{list_commits_with_measurements, prune, pull, push};
use crate::import::{handle_import, ImportOptions};
use crate::measurement_storage::{add_to_commit as add, remove_measurements_from_commits};
use crate::reporting::report;
use crate::reset;
use crate::size;
use crate::stats::ReductionFunc;
use crate::status;
use git_perf_cli_types::{Cli, Commands};
pub fn handle_calls() -> Result<()> {
let cli = Cli::parse();
let logger_level = match cli.verbose {
0 => Level::Warn,
1 => Level::Info,
2 => Level::Debug,
_ => Level::Trace,
};
env_logger::Builder::from_env(Env::default().default_filter_or(logger_level.as_str())).init();
check_git_version()?;
match cli.command {
Commands::Measure {
repetitions,
measurement,
commit,
command,
} => {
let commit = commit.as_deref().unwrap_or("HEAD");
measure(
commit,
&measurement.name,
repetitions,
&command,
&measurement.key_value,
)
}
Commands::Add {
value,
measurement,
commit,
} => {
let commit = commit.as_deref().unwrap_or("HEAD");
add(commit, &measurement.name, value, &measurement.key_value)
}
Commands::Import {
format,
file,
commit,
prefix,
metadata,
filter,
dry_run,
verbose,
} => {
let commit = commit.as_deref().unwrap_or("HEAD").to_string();
handle_import(ImportOptions {
commit,
format,
file,
prefix,
metadata,
filter,
dry_run,
verbose,
})
}
Commands::Push { remote } => push(None, remote.as_deref()),
Commands::Pull {} => pull(None),
Commands::Report {
commit,
output,
separate_by,
report_history,
measurement,
key_value,
aggregate_by,
filter,
template,
custom_css,
title,
show_epochs,
show_changes,
} => {
let commit = commit.as_deref().unwrap_or("HEAD");
let combined_patterns =
crate::filter::combine_measurements_and_filters(&measurement, &filter);
let template_config = crate::reporting::ReportTemplateConfig {
template_path: template,
custom_css_path: custom_css,
title,
};
report(
commit,
output,
separate_by,
report_history.max_count,
&key_value,
aggregate_by.map(ReductionFunc::from),
&combined_patterns,
template_config,
show_epochs,
show_changes,
)
}
Commands::Audit {
commit,
measurement,
report_history,
selectors,
separate_by,
min_measurements,
aggregate_by,
sigma,
dispersion_method,
filter,
no_change_point_warning,
} => {
let commit = commit.as_deref().unwrap_or("HEAD");
if measurement.is_empty() && filter.is_empty() {
Cli::command()
.error(
clap::error::ErrorKind::MissingRequiredArgument,
"At least one of --measurement or --filter must be provided",
)
.exit()
}
if let Some(min_count) = min_measurements {
if report_history.max_count < min_count.into() {
Cli::command().error(ArgumentConflict, format!("The minimal number of measurements ({}) cannot be more than the maximum number of measurements ({})", min_count, report_history.max_count)).exit()
}
}
let combined_patterns =
crate::filter::combine_measurements_and_filters(&measurement, &filter);
audit::audit_multiple(
commit,
report_history.max_count,
min_measurements,
&selectors,
aggregate_by.map(ReductionFunc::from),
sigma,
dispersion_method.map(crate::stats::DispersionMethod::from),
&combined_patterns,
&separate_by,
no_change_point_warning,
)
}
Commands::BumpEpoch { measurements } => {
for measurement in measurements {
bump_epoch(&measurement)?;
}
Ok(())
}
Commands::Prune {} => prune(),
Commands::Status { detailed } => status::show_status(detailed),
Commands::Reset { dry_run, force } => reset::reset_measurements(dry_run, force),
Commands::Remove {
older_than,
no_prune,
dry_run,
} => remove_measurements_from_commits(older_than, !no_prune, dry_run),
Commands::ListCommits {} => {
let commits = list_commits_with_measurements()?;
for commit in commits {
println!("{}", commit);
}
Ok(())
}
Commands::Size {
detailed,
format,
disk_size,
include_objects,
} => size::calculate_measurement_size(detailed, format, disk_size, include_objects),
Commands::Config {
list,
detailed,
format,
validate,
measurement,
} => {
if list {
config_cmd::list_config(detailed, format, validate, measurement)
} else {
anyhow::bail!("config command requires --list flag (try: git perf config --list)");
}
}
}
}