@@ -50,7 +50,7 @@ pub fn get_cargo_workspace() -> &'static std::path::Path {
50
50
}
51
51
52
52
#[ derive( clap:: Parser , Debug ) ]
53
- pub struct TestOpts {
53
+ pub struct TestAll {
54
54
/// Run a long test (it's very long)
55
55
#[ clap( short = 'l' , long) ]
56
56
pub long_test : bool ,
@@ -59,7 +59,7 @@ pub struct TestOpts {
59
59
#[ clap( short = 'c' , long) ]
60
60
pub chip : Vec < String > ,
61
61
62
- /// Filter by manufacturer, case sensitive, may be combined with other filters
62
+ /// Filter by manufacturer, may be combined with other filters
63
63
#[ clap(
64
64
short = 'm' ,
65
65
long = "manufacturer" ,
@@ -68,7 +68,7 @@ pub struct TestOpts {
68
68
) ]
69
69
pub mfgr : Option < String > ,
70
70
71
- /// Filter by architecture, case sensitive, may be combined with other filters
71
+ /// Filter by architecture, may be combined with other filters
72
72
#[ clap(
73
73
short = 'a' ,
74
74
long = "architecture" ,
@@ -104,7 +104,97 @@ pub struct TestOpts {
104
104
// TODO: Compile svd2rust?
105
105
}
106
106
107
- impl TestOpts {
107
+ #[ derive( clap:: Parser , Debug ) ]
108
+ // TODO: Replace with https://github.com/clap-rs/clap/issues/2621 when available
109
+ #[ group( id = "svd_source" , required = true ) ]
110
+ pub struct Test {
111
+ /// Enable formatting with `rustfmt`
112
+ #[ arg( short = 'f' , long) ]
113
+ pub format : bool ,
114
+
115
+ #[ arg( long) ]
116
+ /// Enable splitting `lib.rs` with `form`
117
+ pub form_lib : bool ,
118
+
119
+ #[ arg(
120
+ short = 'm' ,
121
+ long = "manufacturer" ,
122
+ ignore_case = true ,
123
+ value_parser = manufacturers( ) ,
124
+ ) ]
125
+ /// Manufacturer
126
+ pub mfgr : Option < String > ,
127
+ #[ arg(
128
+ short = 'a' ,
129
+ long = "architecture" ,
130
+ ignore_case = true ,
131
+ value_parser = architectures( ) ,
132
+ ) ]
133
+ /// Architecture
134
+ pub arch : Option < String > ,
135
+ #[ arg( long, group = "svd_source" , conflicts_with_all = [ "svd_file" ] , requires = "arch" ) ]
136
+ /// URL to SVD file to test
137
+ pub url : Option < String > ,
138
+ #[ arg( long = "svd" , group = "svd_source" ) ]
139
+ /// Path to SVD file to test
140
+ pub svd_file : Option < PathBuf > ,
141
+ #[ arg( long, group = "svd_source" ) ]
142
+ /// Chip to use, use `--url` or `--svd-file` for another way to specify svd
143
+ pub chip : Option < String > ,
144
+
145
+ /// Path to an `svd2rust` binary, relative or absolute.
146
+ /// Defaults to `target/release/svd2rust[.exe]` of this repository
147
+ /// (which must be already built)
148
+ #[ clap( short = 'p' , long = "svd2rust-path" , default_value = default_svd2rust( ) ) ]
149
+ pub current_bin_path : PathBuf ,
150
+ #[ clap( last = true ) ]
151
+ pub command : Option < String > ,
152
+ }
153
+
154
+ impl Test {
155
+ fn run ( & self , opts : & Opts ) -> Result < ( ) , anyhow:: Error > {
156
+ match self {
157
+ Self { url : Some ( url) , .. } => { }
158
+ Self {
159
+ svd_file : Some ( svd_file) ,
160
+ ..
161
+ } => { }
162
+ Self {
163
+ chip : Some ( chip) , ..
164
+ } => { }
165
+ _ => unreachable ! ( "clap should not allow this" ) ,
166
+ }
167
+ let test = if let ( Some ( url) , Some ( arch) ) = ( & self . url , & self . arch ) {
168
+ tests:: TestCase {
169
+ arch : svd2rust:: Target :: parse ( & arch) ?,
170
+ mfgr : tests:: Manufacturer :: Unknown ,
171
+ chip : self
172
+ . chip
173
+ . as_deref ( )
174
+ . or_else ( || url. rsplit ( '/' ) . next ( ) . and_then ( |s| s. strip_suffix ( ".svd" ) ) )
175
+ . ok_or_else ( || {
176
+ anyhow:: anyhow!(
177
+ "could not figure out chip name, specify with `--chip <name>`" ,
178
+ )
179
+ } ) ?
180
+ . to_owned ( ) ,
181
+ svd_url : Some ( url. clone ( ) ) ,
182
+ should_pass : true ,
183
+ run_when : tests:: RunWhen :: default ( ) ,
184
+ }
185
+ } else {
186
+ tests:: tests ( Some ( & opts. test_cases ) ) ?
187
+ . iter ( )
188
+ . find ( |t| self . chip . iter ( ) . any ( |c| WildMatch :: new ( c) . matches ( & t. chip ) ) )
189
+ . ok_or_else ( || anyhow:: anyhow!( "no test found for chip" ) ) ?
190
+ . to_owned ( )
191
+ } ;
192
+ test. test ( opts, & self . current_bin_path , self . command . as_deref ( ) ) ?;
193
+ Ok ( ( ) )
194
+ }
195
+ }
196
+
197
+ impl TestAll {
108
198
fn run ( & self , opt : & Opts ) -> Result < ( ) , anyhow:: Error > {
109
199
let tests = tests:: tests ( Some ( & opt. test_cases ) ) ?
110
200
. iter ( )
@@ -152,7 +242,7 @@ impl TestOpts {
152
242
tests. par_iter ( ) . for_each ( |t| {
153
243
let start = Instant :: now ( ) ;
154
244
155
- match t. test ( opt, self ) {
245
+ match t. test ( opt, & self . current_bin_path , self . command . as_deref ( ) ) {
156
246
Ok ( s) => {
157
247
if let Some ( stderrs) = s {
158
248
let mut buf = String :: new ( ) ;
@@ -217,7 +307,8 @@ impl TestOpts {
217
307
#[ derive( clap:: Subcommand , Debug ) ]
218
308
pub enum Subcommand {
219
309
Diff ( Diffing ) ,
220
- Tests ( TestOpts ) ,
310
+ Tests ( TestAll ) ,
311
+ Test ( Test ) ,
221
312
Ci ( Ci ) ,
222
313
}
223
314
@@ -256,15 +347,17 @@ pub struct Opts {
256
347
impl Opts {
257
348
const fn use_rustfmt ( & self ) -> bool {
258
349
match self . subcommand {
259
- Subcommand :: Tests ( TestOpts { format, .. } )
350
+ Subcommand :: Tests ( TestAll { format, .. } )
351
+ | Subcommand :: Test ( Test { format, .. } )
260
352
| Subcommand :: Diff ( Diffing { format, .. } )
261
353
| Subcommand :: Ci ( Ci { format, .. } ) => format,
262
354
}
263
355
}
264
356
265
357
const fn use_form ( & self ) -> bool {
266
358
match self . subcommand {
267
- Subcommand :: Tests ( TestOpts { form_lib, .. } )
359
+ Subcommand :: Tests ( TestAll { form_lib, .. } )
360
+ | Subcommand :: Test ( Test { form_lib, .. } )
268
361
| Subcommand :: Diff ( Diffing {
269
362
form_split : form_lib,
270
363
..
@@ -278,13 +371,10 @@ impl Opts {
278
371
fn default_test_cases ( ) -> std:: ffi:: OsString {
279
372
std:: env:: var_os ( "CARGO_MANIFEST_DIR" ) . map_or_else (
280
373
|| std:: ffi:: OsString :: from ( "tests.yml" . to_owned ( ) ) ,
281
- |mut e| {
282
- e. extend ( [ std:: ffi:: OsStr :: new ( "/tests.yml" ) ] ) ;
283
- std:: path:: PathBuf :: from ( e)
284
- . strip_prefix ( std:: env:: current_dir ( ) . unwrap ( ) )
285
- . unwrap ( )
286
- . to_owned ( )
287
- . into_os_string ( )
374
+ |path| {
375
+ let path = std:: path:: PathBuf :: from ( path) ;
376
+ let path = path. join ( "tests.yml" ) ;
377
+ path. to_owned ( ) . into_os_string ( )
288
378
} ,
289
379
)
290
380
}
@@ -414,6 +504,13 @@ fn main() -> Result<(), anyhow::Error> {
414
504
}
415
505
Subcommand :: Diff ( diff) => diff. run ( & opt) . with_context ( || "failed to run diff" ) ,
416
506
Subcommand :: Ci ( ci) => ci. run ( & opt) . with_context ( || "failed to run ci" ) ,
507
+ Subcommand :: Test ( test) => {
508
+ anyhow:: ensure!(
509
+ test. current_bin_path. exists( ) ,
510
+ "svd2rust binary does not exist"
511
+ ) ;
512
+ test. run ( & opt) . with_context ( || "failed to run test" )
513
+ }
417
514
}
418
515
}
419
516
0 commit comments