1- use crate :: { measurement_mode:: MeasurementMode , prelude:: * , run:: run_benches} ;
1+ use crate :: {
2+ measurement_mode:: { BuildMode , MeasurementMode } ,
3+ prelude:: * ,
4+ run:: run_benches,
5+ } ;
26use cargo_metadata:: MetadataCommand ;
3- use clap:: { Args , Parser , Subcommand } ;
7+ use clap:: { ArgAction , Args , Parser , Subcommand } ;
48use std:: { ffi:: OsString , process:: exit} ;
59
610use crate :: build:: { build_benches, BuildConfig } ;
@@ -12,17 +16,107 @@ struct Cli {
1216 #[ arg( short, long, global = true ) ]
1317 quiet : bool ,
1418
15- /// The measurement tool to use for measuring performance.
16- /// Automatically set to `walltime` on macro runners
17- #[ arg( short, long, global = true , env = "CODSPEED_RUNNER_MODE" ) ]
18- measurement_mode : Option < MeasurementMode > ,
19-
2019 #[ command( subcommand) ]
2120 command : Commands ,
2221}
2322
23+ impl Cli {
24+ pub fn run ( self ) -> Result < ( ) > {
25+ let metadata = MetadataCommand :: new ( ) . exec ( ) ?;
26+ match self . command {
27+ Commands :: Build {
28+ package_filters,
29+ bench_target_filters,
30+ features,
31+ all_features,
32+ jobs,
33+ no_default_features,
34+ profile,
35+ locked,
36+ offline,
37+ frozen,
38+ measurement_mode,
39+ } => {
40+ let passthrough_flags = {
41+ let mut passthrough_flags = Vec :: new ( ) ;
42+ if all_features {
43+ passthrough_flags. push ( "--all-features" . to_string ( ) ) ;
44+ }
45+ if no_default_features {
46+ passthrough_flags. push ( "--no-default-features" . to_string ( ) ) ;
47+ }
48+ if locked {
49+ passthrough_flags. push ( "--locked" . to_string ( ) ) ;
50+ }
51+ if offline {
52+ passthrough_flags. push ( "--offline" . to_string ( ) ) ;
53+ }
54+ if frozen {
55+ passthrough_flags. push ( "--frozen" . to_string ( ) ) ;
56+ }
57+ if let Some ( jobs) = jobs {
58+ passthrough_flags. push ( format ! ( "--jobs={jobs}" ) ) ;
59+ }
60+ passthrough_flags
61+ } ;
62+ let features =
63+ features. map ( |f| f. split ( [ ' ' , ',' ] ) . map ( |s| s. to_string ( ) ) . collect_vec ( ) ) ;
64+
65+ let modes = measurement_mode. iter ( ) . map ( |m| m. to_string ( ) ) . join ( ", " ) ;
66+ eprintln ! (
67+ "[cargo-codspeed] Measurement mode{}: {modes}\n " ,
68+ if measurement_mode. len( ) > 1 { "s" } else { "" }
69+ ) ;
70+
71+ let build_modes: Vec < BuildMode > = measurement_mode
72+ . into_iter ( )
73+ . map ( BuildMode :: from)
74+ . unique ( )
75+ . collect ( ) ;
76+ let build_modes = if build_modes. is_empty ( ) {
77+ vec ! [ BuildMode :: default ( ) ]
78+ } else {
79+ build_modes
80+ } ;
81+
82+ for build_mode in build_modes {
83+ build_benches (
84+ & metadata,
85+ BuildConfig {
86+ package_filters : package_filters. clone ( ) ,
87+ bench_target_filters : bench_target_filters. clone ( ) ,
88+ features : features. clone ( ) ,
89+ profile : profile. clone ( ) ,
90+ quiet : self . quiet ,
91+ build_mode,
92+ passthrough_flags : passthrough_flags. clone ( ) ,
93+ } ,
94+ ) ?;
95+ }
96+ Ok ( ( ) )
97+ }
98+ Commands :: Run {
99+ benchname,
100+ package_filters,
101+ bench_target_filters,
102+ measurement_mode,
103+ } => {
104+ let mode = measurement_mode. unwrap_or_default ( ) ;
105+ eprintln ! ( "[cargo-codspeed] Measurement mode: {mode:?}\n " ) ;
106+ run_benches (
107+ & metadata,
108+ benchname,
109+ package_filters,
110+ bench_target_filters,
111+ mode,
112+ )
113+ }
114+ }
115+ }
116+ }
117+
24118const PACKAGE_HELP : & str = "Package Selection" ;
25- #[ derive( Args ) ]
119+ #[ derive( Args , Clone ) ]
26120pub ( crate ) struct PackageFilters {
27121 /// Select all packages in the workspace
28122 #[ arg( long, help_heading = PACKAGE_HELP ) ]
@@ -35,7 +129,7 @@ pub(crate) struct PackageFilters {
35129 pub ( crate ) package : Vec < String > ,
36130}
37131
38- #[ derive( Args ) ]
132+ #[ derive( Args , Clone ) ]
39133pub ( crate ) struct BenchTargetFilters {
40134 /// Select only the specified benchmark target (all benchmark targets by default)
41135 #[ arg( long, help_heading = TARGET_HELP ) ]
@@ -89,6 +183,18 @@ enum Commands {
89183
90184 #[ command( flatten) ]
91185 bench_target_filters : BenchTargetFilters ,
186+
187+ /// The measurement tool(s) to use for measuring performance.
188+ /// Can be specified multiple times or comma-separated.
189+ #[ arg(
190+ short = 'm' ,
191+ long = "measurement-mode" ,
192+ value_delimiter = ',' ,
193+ action = ArgAction :: Append ,
194+ help_heading = COMPILATION_HELP ,
195+ env = "CODSPEED_RUNNER_MODE"
196+ ) ]
197+ measurement_mode : Vec < MeasurementMode > ,
92198 } ,
93199 /// Run the previously built benchmarks
94200 Run {
@@ -100,80 +206,17 @@ enum Commands {
100206
101207 #[ command( flatten) ]
102208 bench_target_filters : BenchTargetFilters ,
209+
210+ /// The measurement tool to use for measuring performance.
211+ /// Automatically set to `walltime` on macro runners
212+ #[ arg( short = 'm' , long = "measurement-mode" , env = "CODSPEED_RUNNER_MODE" ) ]
213+ measurement_mode : Option < MeasurementMode > ,
103214 } ,
104215}
105216
106217pub fn run ( args : impl Iterator < Item = OsString > ) -> Result < ( ) > {
107- let metadata = MetadataCommand :: new ( ) . exec ( ) ?;
108218 let cli = Cli :: try_parse_from ( args) ?;
109-
110- let measurement_mode = cli. measurement_mode . unwrap_or_default ( ) ;
111- eprintln ! ( "[cargo-codspeed] Measurement mode: {measurement_mode:?}\n " ) ;
112-
113- let res = match cli. command {
114- Commands :: Build {
115- package_filters,
116- bench_target_filters,
117- features,
118- all_features,
119- jobs,
120- no_default_features,
121- profile,
122- locked,
123- offline,
124- frozen,
125- } => {
126- let passthrough_flags = {
127- let mut passthrough_flags = Vec :: new ( ) ;
128- if all_features {
129- passthrough_flags. push ( "--all-features" . to_string ( ) ) ;
130- }
131- if no_default_features {
132- passthrough_flags. push ( "--no-default-features" . to_string ( ) ) ;
133- }
134- if locked {
135- passthrough_flags. push ( "--locked" . to_string ( ) ) ;
136- }
137- if offline {
138- passthrough_flags. push ( "--offline" . to_string ( ) ) ;
139- }
140- if frozen {
141- passthrough_flags. push ( "--frozen" . to_string ( ) ) ;
142- }
143- if let Some ( jobs) = jobs {
144- passthrough_flags. push ( format ! ( "--jobs={jobs}" ) ) ;
145- }
146- passthrough_flags
147- } ;
148- let features =
149- features. map ( |f| f. split ( [ ' ' , ',' ] ) . map ( |s| s. to_string ( ) ) . collect_vec ( ) ) ;
150- build_benches (
151- & metadata,
152- BuildConfig {
153- package_filters,
154- bench_target_filters,
155- features,
156- profile,
157- quiet : cli. quiet ,
158- measurement_mode,
159- passthrough_flags,
160- } ,
161- )
162- }
163- Commands :: Run {
164- benchname,
165- package_filters,
166- bench_target_filters,
167- } => run_benches (
168- & metadata,
169- benchname,
170- package_filters,
171- bench_target_filters,
172- measurement_mode,
173- ) ,
174- } ;
175-
176- if let Err ( e) = res {
219+ if let Err ( e) = cli. run ( ) {
177220 eprintln ! ( "Error: {e}" ) ;
178221 exit ( 1 ) ;
179222 }
0 commit comments