From 98ab7d208160dbca671ee3bea7be56e46a068f72 Mon Sep 17 00:00:00 2001 From: Jordan Mele Date: Wed, 7 Feb 2024 14:39:28 +1100 Subject: [PATCH] WIP for action based yarn install --- .bazelversion | 2 +- MODULE.bazel.lock | 126 +++++++++++++++--- e2e/bazel_6_litmus/.bazelversion | 1 - e2e/bazel_6_litmus_workspace/.bazelversion | 1 - .../.bazelrc | 0 e2e/bazel_7_litmus/.bazelversion | 1 + .../BUILD.bazel | 0 .../MODULE.bazel | 2 +- .../WORKSPACE.bazel | 0 e2e/{bazel_6_litmus => bazel_7_litmus}/bar.js | 0 e2e/{bazel_6_litmus => bazel_7_litmus}/foo.js | 0 .../package.json | 0 .../yarn.lock | 0 e2e/bazel_7_litmus_workspace/.bazelversion | 1 + .../BUILD.bazel | 0 .../WORKSPACE.bazel | 0 .../bar.js | 0 .../package.json | 0 .../yarn.lock | 0 lib/private/extensions/node_modules.bzl | 53 +++++++- lib/private/repositories.bzl | 2 + .../yarn_install_via_action/impl.bzl | 52 ++++++++ lib/private/rules/yarn_install.bzl | 37 +++++ 23 files changed, 254 insertions(+), 24 deletions(-) delete mode 100644 e2e/bazel_6_litmus/.bazelversion delete mode 100644 e2e/bazel_6_litmus_workspace/.bazelversion rename e2e/{bazel_6_litmus => bazel_7_litmus}/.bazelrc (100%) create mode 100644 e2e/bazel_7_litmus/.bazelversion rename e2e/{bazel_6_litmus => bazel_7_litmus}/BUILD.bazel (100%) rename e2e/{bazel_6_litmus => bazel_7_litmus}/MODULE.bazel (96%) rename e2e/{bazel_6_litmus => bazel_7_litmus}/WORKSPACE.bazel (100%) rename e2e/{bazel_6_litmus => bazel_7_litmus}/bar.js (100%) rename e2e/{bazel_6_litmus => bazel_7_litmus}/foo.js (100%) rename e2e/{bazel_6_litmus => bazel_7_litmus}/package.json (100%) rename e2e/{bazel_6_litmus => bazel_7_litmus}/yarn.lock (100%) create mode 100644 e2e/bazel_7_litmus_workspace/.bazelversion rename e2e/{bazel_6_litmus_workspace => bazel_7_litmus_workspace}/BUILD.bazel (100%) rename e2e/{bazel_6_litmus_workspace => bazel_7_litmus_workspace}/WORKSPACE.bazel (100%) rename e2e/{bazel_6_litmus_workspace => bazel_7_litmus_workspace}/bar.js (100%) rename e2e/{bazel_6_litmus_workspace => bazel_7_litmus_workspace}/package.json (100%) rename e2e/{bazel_6_litmus_workspace => bazel_7_litmus_workspace}/yarn.lock (100%) create mode 100644 lib/private/repositories/yarn_install_via_action/impl.bzl create mode 100644 lib/private/rules/yarn_install.bzl diff --git a/.bazelversion b/.bazelversion index a69251508..a8907c025 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -7.0.0rc6 +7.0.2 diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 0b85ad953..6ad4eb67d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1534,12 +1534,13 @@ "name": "apple_support~1.5.0~apple_cc_configure_extension~local_config_apple_cc_toolchains" } } - } + }, + "recordedRepoMappingEntries": [] } }, "@@aspect_bazel_lib~1.39.0//lib:extensions.bzl%toolchains": { "general": { - "bzlTransitiveDigest": "JfC/BQZIo8ej1YGTTPrLCDJr1eua5syQ5GaQ9Q/yHZ8=", + "bzlTransitiveDigest": "h6ahPq5GHf0+TNJdz+G50t/UDNJ2SeO/S/G4MNBR1B4=", "accumulatedFileDigests": {}, "envVariables": {}, "generatedRepoSpecs": { @@ -1893,12 +1894,29 @@ "version": "4.25.2" } } - } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib~1.39.0", + "aspect_bazel_lib", + "aspect_bazel_lib~1.39.0" + ], + [ + "aspect_bazel_lib~1.39.0", + "bazel_skylib", + "bazel_skylib~1.5.0" + ], + [ + "aspect_bazel_lib~1.39.0", + "bazel_tools", + "bazel_tools" + ] + ] } }, "@@aspect_rules_js~1.34.1//npm:extensions.bzl%npm": { "general": { - "bzlTransitiveDigest": "spaWsKgETXCNFk+Q9a8OfjtPX+AayUmN+gmidFmmKsk=", + "bzlTransitiveDigest": "nlRUUmhYhfugAnR/GUFrmYJPj45FN3wgPOlnwZYkupo=", "accumulatedFileDigests": { "@@//lib/private:pnpm-lock.yaml": "1051c8efd651fe51aadbb56fbd6e601b4d1296b63ea70d99c5e0749bf5452022", "@@//lib/private:.npmrc": "d94d573d5aa644cdd09ff46d9b9c5e9b59185533420308c9a55ad5dc3176f22b" @@ -2971,12 +2989,44 @@ ] } } - } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib~1.39.0", + "bazel_skylib", + "bazel_skylib~1.5.0" + ], + [ + "aspect_bazel_lib~1.39.0", + "bazel_tools", + "bazel_tools" + ], + [ + "aspect_rules_js~1.34.1", + "aspect_bazel_lib", + "aspect_bazel_lib~1.39.0" + ], + [ + "aspect_rules_js~1.34.1", + "bazel_features", + "bazel_features~0.1.0" + ], + [ + "aspect_rules_js~1.34.1", + "bazel_skylib", + "bazel_skylib~1.5.0" + ], + [ + "aspect_rules_js~1.34.1", + "bazel_tools", + "bazel_tools" + ] + ] } }, "@@aspect_rules_ts~2.1.0//ts:extensions.bzl%ext": { "general": { - "bzlTransitiveDigest": "wimojLw16uMaQPs9p612+Fe1WE/AFL/TeEb+yG4kuAQ=", + "bzlTransitiveDigest": "NIKnw1B2mMpPArLmrgk609jGMhRPnI/pcNvKTYOcve8=", "accumulatedFileDigests": {}, "envVariables": {}, "generatedRepoSpecs": { @@ -2999,7 +3049,14 @@ ] } } - } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_rules_ts~2.1.0", + "bazel_tools", + "bazel_tools" + ] + ] } }, "@@bazel_features~0.1.0//private:extensions.bzl%version_extension": { @@ -3027,12 +3084,13 @@ } } } - } + }, + "recordedRepoMappingEntries": [] } }, "@@bazel_tools//tools/cpp:cc_configure.bzl%cc_configure_extension": { "general": { - "bzlTransitiveDigest": "O9sf6ilKWU9Veed02jG9o2HM/xgV/UAyciuFBuxrFRY=", + "bzlTransitiveDigest": "mcsWHq3xORJexV5/4eCvNOLxFOQKV6eli3fkr+tEaqE=", "accumulatedFileDigests": {}, "envVariables": {}, "generatedRepoSpecs": { @@ -3050,7 +3108,14 @@ "name": "bazel_tools~cc_configure_extension~local_config_cc_toolchains" } } - } + }, + "recordedRepoMappingEntries": [ + [ + "bazel_tools", + "bazel_tools", + "bazel_tools" + ] + ] } }, "@@bazel_tools//tools/osx:xcode_configure.bzl%xcode_configure_extension": { @@ -3068,7 +3133,8 @@ "remote_xcode": "" } } - } + }, + "recordedRepoMappingEntries": [] } }, "@@bazel_tools//tools/sh:sh_configure.bzl%sh_configure_extension": { @@ -3084,12 +3150,13 @@ "name": "bazel_tools~sh_configure_extension~local_config_sh" } } - } + }, + "recordedRepoMappingEntries": [] } }, "@@rules_java~7.1.0//java:extensions.bzl%toolchains": { "general": { - "bzlTransitiveDigest": "iUIRqCK7tkhvcDJCAfPPqSd06IHG0a8HQD0xeQyVAqw=", + "bzlTransitiveDigest": "D02GmifxnV/IhYgspsJMDZ/aE8HxAjXgek5gi6FSto4=", "accumulatedFileDigests": {}, "envVariables": {}, "generatedRepoSpecs": { @@ -3624,12 +3691,24 @@ "build_file": "\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"remotejdk_21\"},\n visibility = [\"//visibility:private\"],\n)\nconfig_setting(\n name = \"version_setting\",\n values = {\"java_runtime_version\": \"21\"},\n visibility = [\"//visibility:private\"],\n)\nalias(\n name = \"version_or_prefix_version_setting\",\n actual = select({\n \":version_setting\": \":version_setting\",\n \"//conditions:default\": \":prefix_version_setting\",\n }),\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@remotejdk21_win//:jdk\",\n)\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [\"@platforms//os:windows\", \"@platforms//cpu:x86_64\"],\n target_settings = [\":version_or_prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@remotejdk21_win//:jdk\",\n)\n" } } - } + }, + "recordedRepoMappingEntries": [ + [ + "rules_java~7.1.0", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_java~7.1.0", + "remote_java_tools", + "rules_java~7.1.0~toolchains~remote_java_tools" + ] + ] } }, "@@rules_jvm_external~5.2//:extensions.bzl%maven": { "general": { - "bzlTransitiveDigest": "ccks4+nmLL7AbTfVn/dMsPp/cnHrckyehlLXDYB5zws=", + "bzlTransitiveDigest": "t3J0655dFC46DA1skk7pw/AYXAmLuNFfvsqLdFpBRBM=", "accumulatedFileDigests": { "@@stardoc~0.6.2//:maven_install.json": "de0bfa778b4ed6aebb77509362dd87ab8d20fc7c7c18d2a7429cdfee03949a21", "@@rules_jvm_external~5.2//:rules_jvm_external_deps_install.json": "3ab1f67b0de4815df110bc72ccd6c77882b3b21d3d1e0a84445847b6ce3235a3" @@ -4906,7 +4985,19 @@ "downloaded_file_path": "software/amazon/awssdk/sdk-core/2.17.183/sdk-core-2.17.183.jar" } } - } + }, + "recordedRepoMappingEntries": [ + [ + "rules_jvm_external~5.2", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_jvm_external~5.2", + "rules_jvm_external", + "rules_jvm_external~5.2" + ] + ] } }, "@@rules_nodejs~6.0.2//nodejs:extensions.bzl%node": { @@ -5002,7 +5093,8 @@ "node_version": "16.0.0" } } - } + }, + "recordedRepoMappingEntries": [] } } } diff --git a/e2e/bazel_6_litmus/.bazelversion b/e2e/bazel_6_litmus/.bazelversion deleted file mode 100644 index 19b860c18..000000000 --- a/e2e/bazel_6_litmus/.bazelversion +++ /dev/null @@ -1 +0,0 @@ -6.4.0 diff --git a/e2e/bazel_6_litmus_workspace/.bazelversion b/e2e/bazel_6_litmus_workspace/.bazelversion deleted file mode 100644 index 19b860c18..000000000 --- a/e2e/bazel_6_litmus_workspace/.bazelversion +++ /dev/null @@ -1 +0,0 @@ -6.4.0 diff --git a/e2e/bazel_6_litmus/.bazelrc b/e2e/bazel_7_litmus/.bazelrc similarity index 100% rename from e2e/bazel_6_litmus/.bazelrc rename to e2e/bazel_7_litmus/.bazelrc diff --git a/e2e/bazel_7_litmus/.bazelversion b/e2e/bazel_7_litmus/.bazelversion new file mode 100644 index 000000000..a8907c025 --- /dev/null +++ b/e2e/bazel_7_litmus/.bazelversion @@ -0,0 +1 @@ +7.0.2 diff --git a/e2e/bazel_6_litmus/BUILD.bazel b/e2e/bazel_7_litmus/BUILD.bazel similarity index 100% rename from e2e/bazel_6_litmus/BUILD.bazel rename to e2e/bazel_7_litmus/BUILD.bazel diff --git a/e2e/bazel_6_litmus/MODULE.bazel b/e2e/bazel_7_litmus/MODULE.bazel similarity index 96% rename from e2e/bazel_6_litmus/MODULE.bazel rename to e2e/bazel_7_litmus/MODULE.bazel index 0f0171c02..ac2d4258f 100644 --- a/e2e/bazel_6_litmus/MODULE.bazel +++ b/e2e/bazel_7_litmus/MODULE.bazel @@ -1,5 +1,5 @@ module( - name = "bazel_6_litmus", + name = "bazel_7_litmus", version = "0.0.0", compatibility_level = 0, ) diff --git a/e2e/bazel_6_litmus/WORKSPACE.bazel b/e2e/bazel_7_litmus/WORKSPACE.bazel similarity index 100% rename from e2e/bazel_6_litmus/WORKSPACE.bazel rename to e2e/bazel_7_litmus/WORKSPACE.bazel diff --git a/e2e/bazel_6_litmus/bar.js b/e2e/bazel_7_litmus/bar.js similarity index 100% rename from e2e/bazel_6_litmus/bar.js rename to e2e/bazel_7_litmus/bar.js diff --git a/e2e/bazel_6_litmus/foo.js b/e2e/bazel_7_litmus/foo.js similarity index 100% rename from e2e/bazel_6_litmus/foo.js rename to e2e/bazel_7_litmus/foo.js diff --git a/e2e/bazel_6_litmus/package.json b/e2e/bazel_7_litmus/package.json similarity index 100% rename from e2e/bazel_6_litmus/package.json rename to e2e/bazel_7_litmus/package.json diff --git a/e2e/bazel_6_litmus/yarn.lock b/e2e/bazel_7_litmus/yarn.lock similarity index 100% rename from e2e/bazel_6_litmus/yarn.lock rename to e2e/bazel_7_litmus/yarn.lock diff --git a/e2e/bazel_7_litmus_workspace/.bazelversion b/e2e/bazel_7_litmus_workspace/.bazelversion new file mode 100644 index 000000000..a8907c025 --- /dev/null +++ b/e2e/bazel_7_litmus_workspace/.bazelversion @@ -0,0 +1 @@ +7.0.2 diff --git a/e2e/bazel_6_litmus_workspace/BUILD.bazel b/e2e/bazel_7_litmus_workspace/BUILD.bazel similarity index 100% rename from e2e/bazel_6_litmus_workspace/BUILD.bazel rename to e2e/bazel_7_litmus_workspace/BUILD.bazel diff --git a/e2e/bazel_6_litmus_workspace/WORKSPACE.bazel b/e2e/bazel_7_litmus_workspace/WORKSPACE.bazel similarity index 100% rename from e2e/bazel_6_litmus_workspace/WORKSPACE.bazel rename to e2e/bazel_7_litmus_workspace/WORKSPACE.bazel diff --git a/e2e/bazel_6_litmus_workspace/bar.js b/e2e/bazel_7_litmus_workspace/bar.js similarity index 100% rename from e2e/bazel_6_litmus_workspace/bar.js rename to e2e/bazel_7_litmus_workspace/bar.js diff --git a/e2e/bazel_6_litmus_workspace/package.json b/e2e/bazel_7_litmus_workspace/package.json similarity index 100% rename from e2e/bazel_6_litmus_workspace/package.json rename to e2e/bazel_7_litmus_workspace/package.json diff --git a/e2e/bazel_6_litmus_workspace/yarn.lock b/e2e/bazel_7_litmus_workspace/yarn.lock similarity index 100% rename from e2e/bazel_6_litmus_workspace/yarn.lock rename to e2e/bazel_7_litmus_workspace/yarn.lock diff --git a/lib/private/extensions/node_modules.bzl b/lib/private/extensions/node_modules.bzl index 7dcab3baa..5f0859e3d 100644 --- a/lib/private/extensions/node_modules.bzl +++ b/lib/private/extensions/node_modules.bzl @@ -2,14 +2,13 @@ `node_modules` module extension implementation. """ -load("//lib/private:repositories.bzl", "yarn_install", "YARN_INSTALL_ATTRS") +load("//lib/private:repositories.bzl", "yarn_install", "yarn_install_via_action", "YARN_INSTALL_ATTRS") visibility(["//lib/private"]) def _node_modules_impl(mctx): root_modules = [] for mod in mctx.modules: - # TODO Use mod.is_root to detect root module and include in returns for attrs in mod.tags.yarn: if mod.is_root: root_modules.append(attrs.name) @@ -31,6 +30,18 @@ def _node_modules_impl(mctx): host_node_bin = attrs.host_node_bin, host_yarn_bin = attrs.host_yarn_bin, ) + for attrs in mod.tags.yarn_via_action: + if mod.is_root: + root_modules.append(attrs.name) + yarn_install_via_action( + name = attrs.name, + package_json = attrs.package_json, + yarn_lock = attrs.yarn_lock, + package_path = attrs.package_path, + host_node_bin = attrs.host_node_bin, + data = attrs.data, + quiet = attrs.quiet, + ) return mctx.extension_metadata( root_module_direct_deps = root_modules, @@ -47,7 +58,43 @@ node_modules = module_extension( ), }), doc = "", - ) + ), + # The Plan + # + # 1. Repo rule parses package.json and yarn.lock + # 2. Repo rule generates `BUILD.bazel` file that calls `yarn_install_via_action` + # This is done so that outputs go to the same directory as the `yarn_install` repo rule. + # 3. Existing interface is preserved, work is just deferred to exec stage. + "yarn_via_action": tag_class( + attrs = { + "name": attr.string( + mandatory = True, + ), + "package_json": attr.label( + allow_single_file = True, + mandatory = True, + ), + "yarn_lock": attr.label( + allow_single_file = True, + mandatory = True, + ), + "package_path": attr.string( + mandatory = True, + ), + "host_node_bin": attr.label( + allow_single_file = True, + mandatory = True, + ), + "data": attr.label( + allow_files = True, + ), + "quiet": attr.bool( + default = True, + doc = "Hides output, except in the event of install failure.", + ), + }, + doc = "", + ), }, doc = "", ) diff --git a/lib/private/repositories.bzl b/lib/private/repositories.bzl index 8bd804dde..a6022dc6c 100644 --- a/lib/private/repositories.bzl +++ b/lib/private/repositories.bzl @@ -7,11 +7,13 @@ load("//lib/private:repositories/nodejs_toolchain_configure/impl.bzl", _nodejs_t load("//lib/private:repositories/nodejs_toolchains.bzl", _nodejs_toolchains = "nodejs_toolchains") load("//lib/private:repositories/yarn_install/attrs.bzl", _YARN_INSTALL_ATTRS = "YARN_INSTALL_ATTRS") load("//lib/private:repositories/yarn_install/impl.bzl", _yarn_install = "yarn_install") +load("//lib/private:repositories/yarn_install_via_action/impl.bzl", _yarn_install_via_action = "yarn_install_via_action") visibility(["//", "//lib"]) YARN_INSTALL_ATTRS = _YARN_INSTALL_ATTRS yarn_install = _yarn_install +yarn_install_via_action = _yarn_install_via_action nodejs_download = _nodejs_download nodejs_download_host = _nodejs_download_host nodejs_toolchain_configure = _nodejs_toolchain_configure diff --git a/lib/private/repositories/yarn_install_via_action/impl.bzl b/lib/private/repositories/yarn_install_via_action/impl.bzl new file mode 100644 index 000000000..8c334879d --- /dev/null +++ b/lib/private/repositories/yarn_install_via_action/impl.bzl @@ -0,0 +1,52 @@ +""" +""" + +visibility(["//lib/private"]) + +def _impl(rctx): + pass + # 1. Resolve `package.json` and `yarn.lock` paths. + + # 2. Process in their original location using API from forked Yarn. + + # 3. Using data from `hoisted` API, generate `BUILD.bazel` file. + # Required targets to match existing API follow. + # - `:node_modules`, catch-all target that includes all dependencies. + # Rule type: `js_library`. + # - `:node_modules/{package_name}`, an alias that allows a subset of outputs to be referenced. + # Rule type: NA, source files. + # - `[{package_scope}/]{package_name}:{package_name}`, normal way packages are referenced + # Rule type: `js_library`. + # - `[{package_scope}/]{package_name}:{package_name}__contents`, implementation detail. + # Rule type: `js_library`. + # - `[{package_scope}/]{package_name}:{package_name}__files`, implementation detail. + # Rule type: `filegroup`. + # - `[{package_scope}/]{package_name}:{package_name}__typings`, implementation detail. + # Rule type: `alias`. + # - `[{package_scope}/]{package_name}:{package_name}__umd`, implementation detail, unused. + # Rule type: `npm_umd_bundle`. + # - `[{package_scope}/]{package_name}:{package_name}__umd_directory_file_path`, implementation detail, unused. + # Rule type: `directory_file_path`. + +yarn_install_via_action = repository_rule( + implementation = _impl, + attrs = { + "package_json": attr.label( + mandatory = True, + allow_single_file = True, + ), + "yarn_lock": attr.label( + mandatory = True, + allow_single_file = True, + ), + "host_node_bin": attr.label( + mandatory = True, + allow_single_file = True, + ), + }, + doc = """ + Parses `package.json` and `yarn.lock`, extracting data required for the `yarn_install` rule. + + The result is similar to the `yarn_install` repository rule when operating in directory mode. + """, +) diff --git a/lib/private/rules/yarn_install.bzl b/lib/private/rules/yarn_install.bzl new file mode 100644 index 000000000..e749483a4 --- /dev/null +++ b/lib/private/rules/yarn_install.bzl @@ -0,0 +1,37 @@ +""" +""" + +visibility(["//lib/private"]) + +def _impl(ctx): + pass + +yarn_install = rule( + implementation = _impl, + attrs = { + "package_json": attr.label( + mandatory = True, + allow_single_file = True, + ), + "yarn_lock": attr.label( + mandatory = True, + allow_single_file = True, + ), + "data": attr.label_list(), + "hoisted_packages": attr.string_list( + doc = """ + Direct dependencies and hoisted indirect dependencies that will appear in `node_modules`. + + This is a list of package names, not paths. For example, `["react", "react-dom"]`. + This enables input granularity in conjunction with other rules. + """, + ), + "quiet": attr.bool( + default = True, + doc = "Hides output, except in the event of install failure.", + ), + }, + doc = "", +) + +# node_modules components are pulled out via `directory_path` rules, or at least a forked version that supports dependencies.