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

Code before:
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.


# A simple script to use cargo vendor to vendor the dependencies and then create an archive.
import argparse
import os
import shutil
import subprocess
import tempfile


def vendor():
    parser = argparse.ArgumentParser(prog="vendor_servo")
    parser.add_argument("--force", action="store_true")

    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)

Review comment (suggestion):
Hmm, can you explain why `git clean` over e.g. `git status` or `git diff`? We'd mostly run this in CI, so it probably doesn't matter too much, but I expect one also wouldn't want any changed files.

Code after:
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.


# A simple script to use cargo vendor to vendor the dependencies and then create an archive.
import argparse
import os
import shutil
import subprocess
import tempfile
import pathlib


def vendor():
    parser = argparse.ArgumentParser(prog="vendor_servo")
    parser.add_argument("--force", action="store_true")
    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