• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
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
27if __name__ == "__main__":
28
29    workspace_root = Path(
30        os.environ.get("BUILD_WORKSPACE_DIRECTORY",
31                       str(Path(__file__).parent.parent.parent.parent.parent)))
32    metadata_dir = workspace_root / "crate_universe/test_data/metadata"
33    cargo = os.getenv("CARGO", "cargo")
34
35    with tempfile.TemporaryDirectory() as temp_dir:
36        temp_dir_path = Path(temp_dir)
37        temp_dir_path.mkdir(parents=True, exist_ok=True)
38
39        for test_dir in metadata_dir.iterdir():
40
41            # Check to see if the directory contains a Cargo manifest
42            real_manifest = test_dir / "Cargo.toml"
43            if not real_manifest.exists():
44                continue
45
46            # Copy the test directory into a temp directory (and out from under a Cargo workspace)
47            manifest_dir = temp_dir_path / test_dir.name
48            shutil.copytree(test_dir, manifest_dir)
49
50            manifest = manifest_dir / "Cargo.toml"
51            lockfile = manifest_dir / "Cargo.lock"
52
53            if lockfile.exists():
54                proc = run_subprocess([cargo, "update", "--manifest-path", str(manifest), "--workspace"])
55            else:
56                # Generate Lockfile
57                proc = run_subprocess([cargo, "generate-lockfile", "--manifest-path", str(manifest)])
58
59                if not lockfile.exists():
60                    print("Faield to generate lockfile")
61                    print("Args:", proc.args, file=sys.stderr)
62                    print("stderr:", proc.stderr.decode("utf-8"), file=sys.stderr)
63                    print("stdout:", proc.stdout.decode("utf-8"), file=sys.stderr)
64                    exit(1)
65
66            shutil.copy2(str(lockfile), str(test_dir / "Cargo.lock"))
67
68            # Generate metadata
69            proc = subprocess.run(
70                [cargo, "metadata", "--format-version", "1", "--manifest-path", str(manifest)],
71                capture_output=True)
72
73            if proc.returncode:
74                print("Subcommand exited with error", proc.returncode, file=sys.stderr)
75                print("Args:", proc.args, file=sys.stderr)
76                print("stderr:", proc.stderr.decode("utf-8"), file=sys.stderr)
77                print("stdout:", proc.stdout.decode("utf-8"), file=sys.stderr)
78                exit(proc.returncode)
79
80            cargo_home = os.environ.get("CARGO_HOME", str(Path.home() / ".cargo"))
81
82            # Replace the temporary directory so package IDs are predictable
83            metadata_text = proc.stdout.decode("utf-8")
84            metadata_text = metadata_text.replace(temp_dir, "{TEMP_DIR}")
85            metadata_text = metadata_text.replace(cargo_home, "{CARGO_HOME}")
86
87            # Write metadata to disk
88            metadata = json.loads(metadata_text)
89            output = test_dir / "metadata.json"
90            output.write_text(json.dumps(metadata, indent=4, sort_keys=True) + "\n")
91