/ maint / test-all-crates
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()