#!/usr/bin/python3 """Vendor PyCA cryptography's Rust crates """ import argparse import glob import os import re import tarfile import tempfile import shutil import subprocess import sys VENDOR_DIR = "vendor" CARGO_TOML = "src/rust/Cargo.toml" RE_VERSION = re.compile("Version:\s*(.*)") parser = argparse.ArgumentParser(description="Vendor Rust packages") parser.add_argument( "--spec", default="python-cryptography.spec", help="cryptography source tar bundle" ) def cargo(cmd, manifest): args = ["cargo", cmd, f"--manifest-path={manifest}"] return subprocess.check_call( args, stdout=subprocess.DEVNULL, stderr=sys.stderr, env={} ) def main(): args = parser.parse_args() spec = args.spec # change cwd to work in bundle directory here = os.path.dirname(os.path.abspath(spec)) os.chdir(here) # extract version number from bundle name with open(spec) as f: for line in f: mo = RE_VERSION.search(line) if mo is not None: version = mo.group(1) break else: raise ValueError(f"Cannot find version in {spec}") bundle_file = f"cryptography-{version}.tar.gz" vendor_file = f"cryptography-{version}-vendor.tar.bz2" # remove existing vendor directory and file if os.path.isdir(VENDOR_DIR): shutil.rmtree(VENDOR_DIR) try: os.unlink(vendor_file) except FileNotFoundError: pass print(f"Getting crates for {bundle_file}", file=sys.stderr) # extract tar file in tempdir # fetch and vendor Rust crates with tempfile.TemporaryDirectory(dir=here) as tmp: with tarfile.open(bundle_file) as tar: tar.extractall(path=tmp) manifest = os.path.join(tmp, f"cryptography-{version}", CARGO_TOML) cargo("fetch", manifest) cargo("vendor", manifest) print("\nCreating tar ball...", file=sys.stderr) with tarfile.open(vendor_file, "x:bz2") as tar: tar.add(VENDOR_DIR) # remove vendor dir shutil.rmtree(VENDOR_DIR) parser.exit(0, f"Created {vendor_file}\n") if __name__ == "__main__": main()