1use anyhow::Result;
2use clap::CommandFactory;
3use clap::{error::ErrorKind::ArgumentConflict, Parser};
4use env_logger::Env;
5use log::Level;
6
7use crate::audit;
8use crate::basic_measure::measure;
9use crate::config::bump_epoch;
10use crate::git::git_interop::check_git_version;
11use crate::git::git_interop::{list_commits_with_measurements, prune, pull, push};
12use crate::measurement_storage::{add, remove_measurements_from_commits};
13use crate::reporting::report;
14use crate::stats::ReductionFunc;
15use git_perf_cli_types::{Cli, Commands};
16
17pub fn handle_calls() -> Result<()> {
18 let cli = Cli::parse();
19 let logger_level = match cli.verbose {
20 0 => Level::Warn,
21 1 => Level::Info,
22 2 => Level::Debug,
23 _ => Level::Trace,
24 };
25 env_logger::Builder::from_env(Env::default().default_filter_or(logger_level.as_str())).init();
26
27 check_git_version()?;
28
29 match cli.command {
30 Commands::Measure {
31 repetitions,
32 command,
33 measurement,
34 } => measure(
35 &measurement.name,
36 repetitions,
37 &command,
38 &measurement.key_value,
39 ),
40 Commands::Add { value, measurement } => {
41 add(&measurement.name, value, &measurement.key_value)
42 }
43 Commands::Push { remote } => push(None, remote.as_deref()),
44 Commands::Pull {} => pull(None),
45 Commands::Report {
46 output,
47 separate_by,
48 report_history,
49 measurement,
50 key_value,
51 aggregate_by,
52 } => report(
53 output,
54 separate_by,
55 report_history.max_count,
56 &measurement,
57 &key_value,
58 aggregate_by.map(ReductionFunc::from),
59 ),
60 Commands::Audit {
61 measurement,
62 report_history,
63 selectors,
64 min_measurements,
65 aggregate_by,
66 sigma,
67 dispersion_method,
68 } => {
69 if report_history.max_count < min_measurements.into() {
70 Cli::command().error(ArgumentConflict, format!("The minimal number of measurements ({}) cannot be more than the maximum number of measurements ({})", min_measurements, report_history.max_count)).exit()
71 }
72
73 let final_dispersion_method =
74 determine_dispersion_method(dispersion_method, &measurement);
75
76 audit::audit_multiple(
77 &measurement,
78 report_history.max_count,
79 min_measurements,
80 &selectors,
81 ReductionFunc::from(aggregate_by),
82 sigma,
83 final_dispersion_method,
84 )
85 }
86 Commands::BumpEpoch { measurement } => bump_epoch(&measurement),
87 Commands::Prune {} => prune(),
88 Commands::Remove {
89 older_than,
90 no_prune,
91 } => remove_measurements_from_commits(older_than, !no_prune),
92 Commands::ListCommits {} => {
93 let commits = list_commits_with_measurements()?;
94 for commit in commits {
95 println!("{}", commit);
96 }
97 Ok(())
98 }
99 }
100}
101
102fn determine_dispersion_method(
107 cli_method: Option<git_perf_cli_types::DispersionMethod>,
108 measurement: &[String],
109) -> crate::stats::DispersionMethod {
110 if let Some(cli_method) = cli_method {
111 crate::stats::DispersionMethod::from(cli_method)
113 } else {
114 if measurement.is_empty() {
116 crate::stats::DispersionMethod::StandardDeviation
117 } else {
118 let config_method = crate::config::audit_dispersion_method(&measurement[0]);
120 crate::stats::DispersionMethod::from(config_method)
121 }
122 }
123}