66
77Subcommands:
88 verify-groups Check all workspace crates are assigned to test groups
9- verify-features Check all crate features are declared in ci-features.yml
10- verify-no-std Check no-std capable crates have no-std configuration
11- get-crates Get crates for a specific test group
12- run-features Run feature matrix tests
9+ run-group Run tests for all crates in a group
1310 run-no-std Run no-std build checks
1411"""
1512
@@ -44,11 +41,6 @@ def github_error(msg: str):
4441 print (f"::error::{ msg } " )
4542
4643
47- def github_warning (msg : str ):
48- """Print GitHub Actions warning annotation."""
49- print (f"::warning::{ msg } " )
50-
51-
5244def github_notice (msg : str ):
5345 """Print GitHub Actions notice annotation."""
5446 print (f"::notice::{ msg } " )
@@ -89,136 +81,14 @@ def verify_groups(args):
8981 return 0
9082
9183
92- def verify_features (args ):
93- """Verify ci-features.yml skip lists only contain valid features."""
94- metadata = get_workspace_metadata ()
95- features_config = load_yaml (args .features_file ) or {}
96-
97- # Build map of crate -> features from cargo metadata
98- crate_features = {}
99- for pkg in metadata ["packages" ]:
100- crate_features [pkg ["name" ]] = set (pkg .get ("features" , {}).keys ())
101-
102- invalid = []
103-
104- for crate_name , crate_config in features_config .items ():
105- if crate_name not in crate_features :
106- github_warning (f"Crate { crate_name } in ci-features.yml not found in workspace" )
107- continue
108-
109- cargo_features = crate_features [crate_name ]
110- skip_list = crate_config .get ("skip" , []) or []
111-
112- for feature in skip_list :
113- if feature not in cargo_features :
114- invalid .append (f" { crate_name } : '{ feature } ' not in Cargo.toml" )
115-
116- if invalid :
117- github_error ("Invalid features in ci-features.yml skip lists:" )
118- for i in invalid :
119- print (i )
120- return 1
121-
122- print ("ci-features.yml is valid" )
123- return 0
124-
125-
126- def verify_no_std (args ):
127- """Check for no-std capable crates without no-std config (warning only)."""
128- metadata = get_workspace_metadata ()
129- features_config = load_yaml (args .features_file ) or {}
130-
131- for pkg in metadata ["packages" ]:
132- crate_name = pkg ["name" ]
133- features = set (pkg .get ("features" , {}).keys ())
134-
135- # Check if crate might support no-std
136- supports_no_std = bool (features & {"no-std" , "alloc" })
137- if not supports_no_std :
138- continue
139-
140- crate_config = features_config .get (crate_name , {})
141- has_no_std = crate_config .get ("no-std" ) is not None
142-
143- if not has_no_std :
144- github_notice (f"{ crate_name } has no-std features but no 'no-std:' config" )
145-
146- print ("no-std configuration check complete" )
147- return 0
148-
149-
150- def get_crates (args ):
151- """Get crates for a specific test group."""
152- config = load_yaml (args .groups_file )
153- groups = config .get ("groups" , {})
154-
155- if args .group not in groups :
156- github_error (f"Unknown group: { args .group } " )
157- return 1
158-
159- crates = groups [args .group ] or []
160- print (" " .join (crates ))
161- return 0
162-
163-
164- def run_features (args ):
165- """Run feature matrix tests.
166-
167- Auto-detects features from Cargo.toml and tests all except those in 'skip'.
168- """
169- metadata = get_workspace_metadata ()
170- features_config = load_yaml (args .features_file ) or {}
171-
172- failed = []
173-
174- for pkg in metadata ["packages" ]:
175- crate_name = pkg ["name" ]
176- cargo_features = set (pkg .get ("features" , {}).keys ())
177-
178- if not cargo_features :
179- continue
180-
181- # Get skip list for this crate
182- crate_config = features_config .get (crate_name , {})
183- skip_list = set (crate_config .get ("skip" , []) or [])
184-
185- # Test all features except skipped ones
186- features_to_test = sorted (cargo_features - skip_list )
187-
188- if not features_to_test :
189- continue
190-
191- for feature in features_to_test :
192- github_group_start (f"{ crate_name } ({ feature } )" )
193-
194- cmd = ["cargo" , "test" , "-p" , crate_name , "--features" , feature ]
195- result = subprocess .run (cmd )
196-
197- github_group_end ()
198-
199- if result .returncode != 0 :
200- failed .append (f"{ crate_name } ({ feature } )" )
201- github_error (f"Feature test failed: { crate_name } --features { feature } " )
202-
203- if failed :
204- print ("\n " + "=" * 40 )
205- print ("FAILED FEATURE TESTS:" )
206- for f in failed :
207- print (f" - { f } " )
208- print ("=" * 40 )
209- return 1
210-
211- return 0
212-
213-
21484def run_no_std (args ):
215- """Run no-std build checks from ci-features .yml.
85+ """Run no-std build checks from ci-no-std .yml.
21686
21787 Format: crate_name: [list of configs]
21888 Each config runs: cargo check -p crate --no-default-features --features <config>
21989 Special: 'bare' means just --no-default-features (no features)
22090 """
221- config = load_yaml (args .features_file ) or {}
91+ config = load_yaml (args .no_std_file ) or {}
22292
22393 failed = []
22494
@@ -271,105 +141,6 @@ def run_no_std(args):
271141 return 0
272142
273143
274- def list_crates_with_features (args ):
275- """List crates that have testable features (for matrix generation)."""
276- metadata = get_workspace_metadata ()
277- features_config = load_yaml (args .features_file ) or {}
278-
279- crates_with_features = []
280-
281- for pkg in metadata ["packages" ]:
282- crate_name = pkg ["name" ]
283- cargo_features = set (pkg .get ("features" , {}).keys ())
284-
285- if not cargo_features :
286- continue
287-
288- crate_config = features_config .get (crate_name , {})
289- skip_list = set (crate_config .get ("skip" , []) or [])
290- features_to_test = cargo_features - skip_list
291-
292- if features_to_test :
293- crates_with_features .append (crate_name )
294-
295- # Output as JSON for GitHub Actions matrix
296- import json
297- print (json .dumps (sorted (crates_with_features )))
298- return 0
299-
300-
301- def run_crate_features (args ):
302- """Run feature tests for a single crate."""
303- metadata = get_workspace_metadata ()
304- features_config = load_yaml (args .features_file ) or {}
305-
306- # Find the crate
307- pkg = None
308- for p in metadata ["packages" ]:
309- if p ["name" ] == args .crate :
310- pkg = p
311- break
312-
313- if not pkg :
314- github_error (f"Crate not found: { args .crate } " )
315- return 1
316-
317- cargo_features = set (pkg .get ("features" , {}).keys ())
318- if not cargo_features :
319- print (f"No features to test for { args .crate } " )
320- return 0
321-
322- crate_config = features_config .get (args .crate , {})
323- skip_list = set (crate_config .get ("skip" , []) or [])
324- features_to_test = sorted (cargo_features - skip_list )
325-
326- if not features_to_test :
327- print (f"All features skipped for { args .crate } " )
328- return 0
329-
330- failed = []
331-
332- for feature in features_to_test :
333- github_group_start (f"{ args .crate } ({ feature } )" )
334-
335- cmd = ["cargo" , "test" , "-p" , args .crate , "--features" , feature ]
336- result = subprocess .run (cmd )
337-
338- github_group_end ()
339-
340- if result .returncode != 0 :
341- failed .append (feature )
342- github_error (f"Feature test failed: { args .crate } --features { feature } " )
343-
344- if failed :
345- print ("\n " + "=" * 40 )
346- print (f"FAILED FEATURES for { args .crate } :" )
347- for f in failed :
348- print (f" - { f } " )
349- print ("=" * 40 )
350- return 1
351-
352- return 0
353-
354-
355- def run_feature_checks (args ):
356- """Run both feature matrix tests and no-std checks."""
357- print ("=" * 50 )
358- print ("Running feature matrix tests..." )
359- print ("=" * 50 )
360- features_result = run_features (args )
361-
362- print ()
363- print ("=" * 50 )
364- print ("Running no-std checks..." )
365- print ("=" * 50 )
366- no_std_result = run_no_std (args )
367-
368- if features_result != 0 or no_std_result != 0 :
369- return 1
370- return 0
371-
372-
373144def run_group_tests (args ):
374145 """Run tests for all crates in a group."""
375146 config = load_yaml (args .groups_file )
@@ -424,29 +195,16 @@ def main():
424195 help = "Path to ci-groups.yml" ,
425196 )
426197 parser .add_argument (
427- "--features -file" ,
198+ "--no-std -file" ,
428199 type = Path ,
429- default = Path (".github/ci-features .yml" ),
430- help = "Path to ci-features .yml" ,
200+ default = Path (".github/ci-no-std .yml" ),
201+ help = "Path to ci-no-std .yml" ,
431202 )
432203
433204 subparsers = parser .add_subparsers (dest = "command" , required = True )
434205
435206 subparsers .add_parser ("verify-groups" , help = "Verify all crates assigned to groups" )
436- subparsers .add_parser ("verify-features" , help = "Verify all features declared" )
437- subparsers .add_parser ("verify-no-std" , help = "Verify no-std coverage" )
438-
439- get_crates_parser = subparsers .add_parser ("get-crates" , help = "Get crates for group" )
440- get_crates_parser .add_argument ("group" , help = "Group name" )
441-
442- subparsers .add_parser ("run-features" , help = "Run feature matrix tests" )
443207 subparsers .add_parser ("run-no-std" , help = "Run no-std checks" )
444- subparsers .add_parser ("run-feature-checks" , help = "Run both feature tests and no-std checks" )
445-
446- crate_features_parser = subparsers .add_parser ("run-crate-features" , help = "Run feature tests for a single crate" )
447- crate_features_parser .add_argument ("crate" , help = "Crate name" )
448-
449- subparsers .add_parser ("list-crates-with-features" , help = "List crates that have features to test" )
450208
451209 run_group_parser = subparsers .add_parser ("run-group" , help = "Run tests for a group" )
452210 run_group_parser .add_argument ("group" , help = "Group name" )
@@ -456,14 +214,7 @@ def main():
456214
457215 commands = {
458216 "verify-groups" : verify_groups ,
459- "verify-features" : verify_features ,
460- "verify-no-std" : verify_no_std ,
461- "get-crates" : get_crates ,
462- "run-features" : run_features ,
463217 "run-no-std" : run_no_std ,
464- "run-feature-checks" : run_feature_checks ,
465- "run-crate-features" : run_crate_features ,
466- "list-crates-with-features" : list_crates_with_features ,
467218 "run-group" : run_group_tests ,
468219 }
469220
0 commit comments