Repository: servo/servo
File: etc/vendor_servo.py (Python)

Code before:
    args = parser.parse_args()
    if os.path.basename(os.getcwd()) != "servo":
        print("Please call from top level servo directory")
        return

    git_clean = subprocess.run(["git", "clean", "--dry-run", "-x"], capture_output=True)
    if git_clean is not None and not args.force:
        print("git clean -x would have removed some files. These would end up in the archive. Aborting")
        print("run git clean --dry-run -x")
        print("Or run with --force")
        return

    # coying servo into directory
    with tempfile.TemporaryDirectory() as tmpdirname:
        print(f"Copying servo repo to temporary directory {tmpdirname}")
        shutil.copytree(
            ".",
            tmpdirname + "/",
            ignore=shutil.ignore_patterns("*.git", "target", "etc", ".venv"),
            dirs_exist_ok=True,
        )
        os.chdir(tmpdirname)
        # shutil.rmtree('.git/')
        # vendoring crates
        print("Vendoring Crates")
        vendor_process = subprocess.run(["cargo", "vendor", "vendor/"], capture_output=True, encoding="Utf8")
        out = vendor_process.stdout
        print("Modifying cargo")
        with open("Cargo.toml", "a") as toml:
            toml.write("\n")
            toml.writelines(out)
        print("Making archive in /tmp/servo.tar.gz. This might take a while.")
        shutil.make_archive("/tmp/servo", format="gztar", base_dir="./")
    return 0


if __name__ == "__main__":
    vendor()


Review comment (bug):
Will this raise an exception if something goes wrong (network error or similar), or silently continue?

Code after:
    parser.add_argument(
        "--filename",
        type=pathlib.Path,
        help="name of the output archive without the extension, e.g. `servo` for `servo.tar.gz`",
    )

    args = parser.parse_args()
    # This script is `etc/vendor_servo.py`, so the grandparent of the filename is the servo root directory.
    servo_root = pathlib.Path(os.path.realpath(__file__)).parent.parent

    git_status = subprocess.run(["git", "status", "--porcelain"], capture_output=True, check=True)
    if len(git_status.stdout) > 0 and not args.force:
        print("git working directory is not clean. Check `git status` or run with --force")
        return

    git_revision = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True, check=True)

    # copying servo into temporary directory
    with tempfile.TemporaryDirectory() as tmpdirname:
        print(f"Copying servo repo to temporary directory {tmpdirname}")
        shutil.copytree(
            servo_root,
            tmpdirname + "/",
            ignore=shutil.ignore_patterns("*.git", "target", "etc", ".venv"),
            dirs_exist_ok=True,
        )
        os.chdir(tmpdirname)
        # Save the git hash into a file so that the archive can be mapped to a git revision.
        with open("GIT_REVISION", "w") as revision_file:
            revision_file.write(git_revision.stdout)
        # vendoring crates
        print("Vendoring Crates")
        vendor_process = subprocess.run(
            ["cargo", "vendor", "--locked", "vendor/", "--versioned-dirs"],
            capture_output=True,
            encoding="utf-8",
            check=True,
        )
        out = vendor_process.stdout
        print("Modifying .cargo/config.toml")
        with open(".cargo/config.toml", "a") as toml:
            toml.write("\n")
            toml.writelines(out)

        file = tempfile.gettempdir() + "/servo"
        print(f"Making archive in {file}.tar.gz")
        shutil.make_archive(file, format="gztar", base_dir="./")
        tmp_file_path = file + ".tar.gz"
        if args.filename is not None:
            name = pathlib.Path(args.filename)
            if name.is_absolute():