From d4916b7e935fe531b80b36d9ade0ce208c3e7c0e Mon Sep 17 00:00:00 2001 From: vindard <17693119+vindard@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:13:51 -0400 Subject: [PATCH] build: bring in local packages properly during turbo prune During turbo prune, turbo brings in the necessary local package dirs, and figures out the pruned package.json needed. We would need to also bring along the package dependency js files somehow which turbo doesn't seem to handle internally for local packages. This PR is to explitly copy these local package files across during the build_node_modules step after turbo prune. Future improvements: - figure how to simply do this directly with turbo and local packages --- .../workspace-pnpm/build_node_modules.py | 26 +++++++++++++++++++ toolchains/workspace-pnpm/macros.bzl | 8 ++++++ 2 files changed, 34 insertions(+) diff --git a/toolchains/workspace-pnpm/build_node_modules.py b/toolchains/workspace-pnpm/build_node_modules.py index 4d624066e81..2c3b1acbe94 100644 --- a/toolchains/workspace-pnpm/build_node_modules.py +++ b/toolchains/workspace-pnpm/build_node_modules.py @@ -9,6 +9,23 @@ import sys import tempfile +def copy_dir_except_node_modules(src, dst): + """ + Copy all directories, subdirectories, and files from 'src' to 'dst', + excluding any 'node_modules' directories. + """ + for root, dirs, files in os.walk(src): + if 'node_modules' in dirs: + dirs.remove('node_modules') + + for file in files: + src_path = os.path.join(root, file) + dst_path = os.path.join(dst, os.path.relpath(src_path, src)) + + os.makedirs(os.path.dirname(dst_path), exist_ok=True) + shutil.copy2(src_path, dst_path) + + if __name__ == "__main__": parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( @@ -25,6 +42,10 @@ action="store_true", help="Only install production node modules", ) + parser.add_argument( + "--local-packages-path", + help="Path to vendored npm package dependencies", + ) parser.add_argument( "out_path", help="Path to output tree of `node_modules`", @@ -65,6 +86,11 @@ print(f"Failed to successfully run: {turbo_cmd}") sys.exit(1) + if args.local_packages_path: + copy_dir_except_node_modules( + os.path.join(tempdir, "full", args.local_packages_path), + os.path.join(tempdir, "json", args.local_packages_path), + ) shutil.copy( os.path.join(tempdir, "pnpm-lock.yaml"), os.path.join(tempdir, "json", "pnpm-lock.yaml"), diff --git a/toolchains/workspace-pnpm/macros.bzl b/toolchains/workspace-pnpm/macros.bzl index 1fdcfb774d3..f67d8178429 100644 --- a/toolchains/workspace-pnpm/macros.bzl +++ b/toolchains/workspace-pnpm/macros.bzl @@ -153,6 +153,10 @@ def build_node_modules_impl(ctx: AnalysisContext) -> list[DefaultInfo]: cmd.add("--prod-only") identifier += "--prod " + if ctx.attrs.local_packages: + cmd.add("--local-packages-path") + cmd.add(ctx.attrs.local_packages) + cmd.add(out.as_output()) cmd.hidden([ctx.attrs.workspace]) @@ -176,6 +180,10 @@ build_node_modules = rule( default = False, doc = "Only install production dependencies" ), + "local_packages": attrs.string( + default = "lib", + doc = """NPM vendored dependencies directory""", + ), "_python_toolchain": attrs.toolchain_dep( default = "toolchains//:python", providers = [PythonToolchainInfo],