#!/usr/bin/env python3
"""
Installs package node modules via Pnpm and Turbo.
"""
import argparse
import os
import shutil
import subprocess
import sys
import tempfile
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
"--package-dir",
help="Path to the workspace member package",
)
group.add_argument(
"--root-dir",
help="Path to the workspace root",
)
parser.add_argument(
"--package-name",
help="Override the default-derived npm package name",
)
parser.add_argument(
"--turbo-bin",
required=True,
help="Path to `turbo` binary",
)
parser.add_argument(
"--prod-only",
action="store_true",
help="Only install production node modules",
)
parser.add_argument(
"out_path",
help="Path to output tree of `node_modules`",
)
args = parser.parse_args()
with tempfile.TemporaryDirectory() as tempdir:
# `turbo prune` is pretty keen on the `--out-dir` being a sub-directory
# of the workspace root, so we're going to create a symlink under the
# `buck-out` directory which links back to the `tempdir`, only for the
# `turbo prune` call.
turbo_out_path = os.path.join(os.path.dirname(args.out_path), "tmp")
os.symlink(
tempdir,
turbo_out_path,
)
turbo_cmd = [
args.turbo_bin,
"prune",
"--out-dir",
turbo_out_path,
"--docker",
]
if args.package_dir:
if args.package_name:
scope = args.package_name
else:
scope = os.path.basename(args.package_dir)
turbo_cmd.append("--scope")
turbo_cmd.append(scope)
if args.root_dir:
turbo_cwd = args.root_dir
else:
turbo_cwd = None
turbo_exit_code = subprocess.call(turbo_cmd, cwd=turbo_cwd)
# Clean up the temporary symlink
os.unlink(turbo_out_path)
if turbo_exit_code != 0:
print(f"Failed to successfully run: {turbo_cmd}")
sys.exit(1)
shutil.copy(
os.path.join(tempdir, "pnpm-lock.yaml"),
os.path.join(tempdir, "json", "pnpm-lock.yaml"),
)
shutil.copytree(
os.path.join(tempdir, "json"),
args.out_path,
symlinks=True,
)
pnpm_cmd = ["pnpm", "install", "--frozen-lockfile"]
if args.prod_only:
pnpm_cmd.append("--prod")
pnpm_exit_code = subprocess.call(pnpm_cmd, cwd=args.out_path)
sys.exit(pnpm_exit_code)