1#!/usr/bin/env python3 2 3from pathlib import Path 4from typing import List 5import json 6import os 7import shutil 8import shutil 9import subprocess 10import sys 11import tempfile 12 13 14def run_subprocess(command: List[str]) -> subprocess.CompletedProcess[str]: 15 proc = subprocess.run(command, capture_output=True, check=False) 16 17 if proc.returncode: 18 print("Subcommand exited with error", proc.returncode, file=sys.stderr) 19 print("Args:", proc.args, file=sys.stderr) 20 print("stderr:", proc.stderr.decode("utf-8"), file=sys.stderr) 21 print("stdout:", proc.stdout.decode("utf-8"), file=sys.stderr) 22 exit(proc.returncode) 23 24 return proc 25 26 27def main() -> None: 28 """The main entrypoint.""" 29 workspace_root = Path( 30 os.environ.get( 31 "BUILD_WORKSPACE_DIRECTORY", 32 str(Path(__file__).parent.parent.parent.parent.parent), 33 ) 34 ) 35 metadata_dir = workspace_root / "crate_universe/test_data/metadata" 36 cargo = os.getenv("CARGO", "cargo") 37 38 with tempfile.TemporaryDirectory() as temp_dir: 39 temp_dir_path = Path(temp_dir) 40 temp_dir_path.mkdir(parents=True, exist_ok=True) 41 42 for test_dir in metadata_dir.iterdir(): 43 44 # Check to see if the directory contains a Cargo manifest 45 real_manifest = test_dir / "Cargo.toml" 46 if not real_manifest.exists(): 47 continue 48 49 # Copy the test directory into a temp directory (and out from under a Cargo workspace) 50 manifest_dir = temp_dir_path / test_dir.name 51 shutil.copytree(test_dir, manifest_dir) 52 53 manifest = manifest_dir / "Cargo.toml" 54 lockfile = manifest_dir / "Cargo.lock" 55 56 if lockfile.exists(): 57 proc = run_subprocess( 58 [cargo, "update", "--manifest-path", str(manifest), "--workspace"] 59 ) 60 else: 61 # Generate Lockfile 62 proc = run_subprocess( 63 [cargo, "generate-lockfile", "--manifest-path", str(manifest)] 64 ) 65 66 if not lockfile.exists(): 67 print("Faield to generate lockfile") 68 print("Args:", proc.args, file=sys.stderr) 69 print("stderr:", proc.stderr.decode("utf-8"), file=sys.stderr) 70 print("stdout:", proc.stdout.decode("utf-8"), file=sys.stderr) 71 exit(1) 72 73 shutil.copy2(str(lockfile), str(test_dir / "Cargo.lock")) 74 75 # Generate metadata 76 proc = run_subprocess( 77 [ 78 cargo, 79 "metadata", 80 "--format-version", 81 "1", 82 "--manifest-path", 83 str(manifest), 84 ] 85 ) 86 87 cargo_home = os.environ.get("CARGO_HOME", str(Path.home() / ".cargo")) 88 89 # Replace the temporary directory so package IDs are predictable 90 metadata_text = proc.stdout.decode("utf-8") 91 metadata_text = metadata_text.replace(temp_dir, "{TEMP_DIR}") 92 metadata_text = metadata_text.replace(cargo_home, "{CARGO_HOME}") 93 94 # Write metadata to disk 95 metadata = json.loads(metadata_text) 96 output = test_dir / "metadata.json" 97 output.write_text(json.dumps(metadata, indent=4, sort_keys=True) + "\n") 98 99 100if __name__ == "__main__": 101 main() 102