test-all-crates
1 #!/usr/bin/env python3 2 3 # This differs from matrix-check in the following ways: 4 # - it only tests one combination of features, as specified on the command line 5 # - it doesn't have crate-specific hacks (or any knowledge of our workspace contents) 6 # (but it does read some ad-hoc parseable comments from Cargo.toml's). 7 # - it runs `cargo test` 8 9 import argparse 10 import subprocess 11 import sys 12 import list_crates 13 14 15 def test_crate(args, c): 16 conditional_options = [] 17 18 for line in open(c.subdir + "/Cargo.toml"): 19 20 # TODO do something more formal here 21 # 22 # We need this because some crates don't compile without a runtime selected. 23 # 24 # Ideally, if the crate doesn't compile without any features selected, 25 # the manifest should have a `minimal` feature we can use, or something. 26 if line.startswith("# @@ test-all-crates ignore"): 27 print( 28 """( 29 (((((((((( skipping %s )))))))))) 30 )""" 31 % c.name, 32 file=sys.stderr, 33 ) 34 return 35 36 conditional_option_directive = "# @@ test-all-crates conditional-option " 37 # One option per line, so it can contain spaces 38 if line.startswith(conditional_option_directive): 39 (key, option) = ( 40 line[len(conditional_option_directive) :].rstrip().split(maxsplit=1) 41 ) 42 if key in args.enable_conditional_options: 43 conditional_options.append(option) 44 continue 45 46 command_sh = 'p=$1; shift; set -x; $CARGO test -p $p "$@"' 47 48 print( 49 """: 50 :::::::::: %s :::::::::: 51 :""" 52 % c.name, 53 file=sys.stderr, 54 ) 55 56 # We run a separate build command for each one, to defeat cargo feature unification. 57 58 command_l = ( 59 [ 60 "sh", 61 "-ec", 62 ': "${CARGO:=cargo --locked}"; ' + command_sh, 63 "x", 64 c.name, 65 ] 66 + args.cargo_option 67 + conditional_options 68 ) 69 70 child = subprocess.run(command_l) 71 72 if child.returncode != 0: 73 print( 74 """failed command %s 75 "return code" %s 76 failed to test crate %s""" 77 % (repr(command_l), child.returncode, c.name), 78 file=sys.stderr, 79 ) 80 sys.exit(1) 81 82 83 def main(): 84 parser = argparse.ArgumentParser(prog="test-all-crates") 85 parser.add_argument("cargo_option", nargs="*") 86 parser.add_argument("--enable-conditional-options", action="append", default=[]) 87 parser.add_argument("--skip-until", action="store", default=None) 88 args = parser.parse_args() 89 90 skip_until = args.skip_until 91 92 for crate in list_crates.list_crates(): 93 if skip_until is not None: 94 if skip_until == crate.name: 95 skip_until = None 96 else: 97 print( 98 "skipping due to --skip-until %s: %s" % (skip_until, crate.name), 99 file=sys.stderr, 100 ) 101 continue 102 103 test_crate(args, crate) 104 105 106 main()