diff --git a/docs/npm_import.md b/docs/npm_import.md index de79cb91a..178f49c11 100644 --- a/docs/npm_import.md +++ b/docs/npm_import.md @@ -27,8 +27,8 @@ load("@aspect_rules_js//npm/private:npm_import.bzl", "npm_import") npm_import(name, package, version, deps, extra_build_content, transitive_closure, root_package, link_workspace, link_packages, lifecycle_hooks, lifecycle_hooks_execution_requirements, lifecycle_hooks_env, lifecycle_hooks_use_default_shell_env, integrity, url, commit, - replace_package, package_visibility, patch_args, patches, custom_postinstall, npm_auth, - npm_auth_basic, npm_auth_username, npm_auth_password, bins, dev, kwargs) + replace_package, package_visibility, patch_tool, patch_args, patches, custom_postinstall, + npm_auth, npm_auth_basic, npm_auth_username, npm_auth_password, bins, dev, kwargs) Import a single npm package into Bazel. @@ -151,6 +151,7 @@ Read more about the downloader config: commit | Specific commit to be checked out if url is a git repository. | `""` | | replace_package | Use the specified npm_package target when linking instead of the fetched sources for this npm package.

The injected npm_package target may optionally contribute transitive npm package dependencies on top of the transitive dependencies specified in the pnpm lock file for the same package, however, these transitive dependencies must not collide with pnpm lock specified transitive dependencies.

Any patches specified for this package will be not applied to the injected npm_package target. They will be applied, however, to the fetches sources so they can still be useful for patching the fetched `package.json` file, which is used to determine the generated bin entries for the package.

NB: lifecycle hooks and custom_postinstall scripts, if implicitly or explicitly enabled, will be run on the injected npm_package. These may be disabled explicitly using the `lifecycle_hooks` attribute. | `None` | | package_visibility | Visibility of generated node_module link targets. | `["//visibility:public"]` | +| patch_tool | The patch tool. | `None` | | patch_args | Arguments to pass to the patch tool.

`-p1` will usually be needed for patches generated by git. | `["-p0"]` | | patches | Patch files to apply onto the downloaded npm package. | `[]` | | custom_postinstall | Custom string postinstall script to run on the installed npm package.

Runs after any existing lifecycle hooks if any are enabled. | `""` | diff --git a/docs/npm_translate_lock.md b/docs/npm_translate_lock.md index a5e7f5f2a..bb928da1c 100644 --- a/docs/npm_translate_lock.md +++ b/docs/npm_translate_lock.md @@ -63,7 +63,7 @@ load("@aspect_rules_js//npm/private:npm_translate_lock.bzl", "npm_translate_lock npm_translate_lock(name, pnpm_lock, npm_package_lock, yarn_lock, update_pnpm_lock, node_toolchain_prefix, yq_toolchain_prefix, preupdate, npmrc, use_home_npmrc, data, - patches, patch_args, custom_postinstalls, package_visibility, prod, + patches, patch_tool, patch_args, custom_postinstalls, package_visibility, prod, public_hoist_packages, dev, no_optional, run_lifecycle_hooks, lifecycle_hooks, lifecycle_hooks_envs, lifecycle_hooks_exclude, lifecycle_hooks_execution_requirements, lifecycle_hooks_no_sandbox, @@ -111,6 +111,7 @@ For more about how to use npm_translate_lock, read [pnpm and rules_js](/docs/pnp | use_home_npmrc | Use the `$HOME/.npmrc` file (or `$USERPROFILE/.npmrc` when on Windows) if it exists.

Settings from home `.npmrc` are merged with settings loaded from the `.npmrc` file specified in the `npmrc` attribute, if any. Where there are conflicting settings, the home `.npmrc` values will take precedence.

WARNING: The repository rule will not be invalidated by changes to the home `.npmrc` file since there is no way to specify this file as an input to the repository rule. If changes are made to the home `.npmrc` you can force the repository rule to re-run and pick up the changes by running: `bazel run @{name}//:sync` where `name` is the name of the `npm_translate_lock` you want to re-run.

Because of the repository rule invalidation issue, using the home `.npmrc` is not recommended. `.npmrc` settings should generally go in the `npmrc` in your repository so they are shared by all developers. The home `.npmrc` should be reserved for authentication settings for private npm repositories. | `None` | | data | Data files required by this repository rule when auto-updating the pnpm lock file.

Only needed when `update_pnpm_lock` is True. Read more: [using update_pnpm_lock](/docs/pnpm.md#update_pnpm_lock) | `[]` | | patches | A map of package names or package names with their version (e.g., "my-package" or "my-package@v1.2.3") to a label list of patches to apply to the downloaded npm package. Multiple matches are additive.

These patches are applied after any patches in [pnpm.patchedDependencies](https://pnpm.io/next/package_json#pnpmpatcheddependencies).

Read more: [patching](/docs/pnpm.md#patching) | `{}` | +| patch_tool | The patch tool. | `None` | | patch_args | A map of package names or package names with their version (e.g., "my-package" or "my-package@v1.2.3") to a label list arguments to pass to the patch tool. The most specific match wins.

Read more: [patching](/docs/pnpm.md#patching) | `{"*": ["-p0"]}` | | custom_postinstalls | A map of package names or package names with their version (e.g., "my-package" or "my-package@v1.2.3") to a custom postinstall script to apply to the downloaded npm package after its lifecycle scripts runs. If the version is left out of the package name, the script will run on every version of the npm package. If a custom postinstall scripts exists for a package as well as for a specific version, the script for the versioned package will be appended with `&&` to the non-versioned package script.

For example,

custom_postinstalls = {
    "@foo/bar": "echo something > somewhere.txt",
    "fum@0.0.1": "echo something_else > somewhere_else.txt",
},


Custom postinstalls are additive and joined with ` && ` when there are multiple matches for a package. More specific matches are appended to previous matches. | `{}` | | package_visibility | A map of package names or package names with their version (e.g., "my-package" or "my-package@v1.2.3") to a visibility list to use for the package's generated node_modules link targets. Multiple matches are additive. If there are no matches then the package's generated node_modules link targets default to public visibility (`["//visibility:public"]`). | `{}` | diff --git a/npm/extensions.bzl b/npm/extensions.bzl index 3965df286..5d07b3ef4 100644 --- a/npm/extensions.bzl +++ b/npm/extensions.bzl @@ -156,6 +156,7 @@ WARNING: Cannot determine home directory in order to load home `.npmrc` file in npm_auth_username = i.npm_auth_username, package = i.package, package_visibility = i.package_visibility, + patch_tool = i.patch_tool, patch_args = i.patch_args, patches = i.patches, replace_package = i.replace_package, @@ -188,6 +189,7 @@ def _npm_import_bzlmod(i): npm_auth_password = i.npm_auth_password, package = i.package, package_visibility = i.package_visibility, + patch_tool = i.patch_tool, patch_args = i.patch_args, patches = i.patches, replace_package = i.replace_package, diff --git a/npm/private/npm_import.bzl b/npm/private/npm_import.bzl index 641a31251..6e47212b4 100644 --- a/npm/private/npm_import.bzl +++ b/npm/private/npm_import.bzl @@ -503,7 +503,12 @@ def _npm_import_rule_impl(rctx): # apply patches to the extracted package before reading the package.json incase # the patch targets the package.json itself - patch(rctx, patch_args = rctx.attr.patch_args, patch_directory = _EXTRACT_TO_DIRNAME) + patch( + rctx, + patch_tool = rctx.path(rctx.attr.patch_tool) if rctx.attr.patch_tool else "patch", + patch_args = rctx.attr.patch_args, + patch_directory = _EXTRACT_TO_DIRNAME, + ) pkg_json = json.decode(rctx.read(_EXTRACT_TO_PACKAGE_JSON)) @@ -822,6 +827,7 @@ _ATTRS = dicts.add(_COMMON_ATTRS, { "npm_auth_basic": attr.string(), "npm_auth_password": attr.string(), "npm_auth_username": attr.string(), + "patch_tool": attr.label(), "patch_args": attr.string_list(), "patches": attr.label_list(), "url": attr.string(), @@ -886,6 +892,7 @@ def npm_import( commit = "", replace_package = None, package_visibility = ["//visibility:public"], + patch_tool = None, patch_args = ["-p0"], patches = [], custom_postinstall = "", @@ -1095,6 +1102,8 @@ def npm_import( package_visibility: Visibility of generated node_module link targets. + patch_tool: The patch tool. + patch_args: Arguments to pass to the patch tool. `-p1` will usually be needed for patches generated by git. @@ -1161,6 +1170,7 @@ def npm_import( integrity = integrity, url = url, commit = commit, + patch_tool = patch_tool, patch_args = patch_args, patches = patches, custom_postinstall = custom_postinstall, diff --git a/npm/private/npm_translate_lock.bzl b/npm/private/npm_translate_lock.bzl index 9d31387a5..6bfed9870 100644 --- a/npm/private/npm_translate_lock.bzl +++ b/npm/private/npm_translate_lock.bzl @@ -65,6 +65,7 @@ _ATTRS = { "npm_package_target_name": attr.string(), "npmrc": attr.label(), "package_visibility": attr.string_list_dict(), + "patch_tool": attr.label(), "patch_args": attr.string_list_dict(), "patches": attr.string_list_dict(), "use_pnpm": attr.label(default = "@pnpm//:package/bin/pnpm.cjs"), # bzlmod pnpm extension @@ -161,6 +162,7 @@ def npm_translate_lock( use_home_npmrc = None, data = [], patches = {}, + patch_tool = None, patch_args = {"*": ["-p0"]}, custom_postinstalls = {}, package_visibility = {}, @@ -277,6 +279,8 @@ def npm_translate_lock( Read more: [patching](/docs/pnpm.md#patching) + patch_tool: The patch tool. + patch_args: A map of package names or package names with their version (e.g., "my-package" or "my-package@v1.2.3") to a label list arguments to pass to the patch tool. The most specific match wins. @@ -569,6 +573,7 @@ def npm_translate_lock( npmrc = npmrc, use_home_npmrc = use_home_npmrc, patches = patches, + patch_tool = patch_tool, patch_args = patch_args, custom_postinstalls = custom_postinstalls, package_visibility = package_visibility, diff --git a/npm/private/npm_translate_lock_generate.bzl b/npm/private/npm_translate_lock_generate.bzl index b85445ae1..619ac6a00 100644 --- a/npm/private/npm_translate_lock_generate.bzl +++ b/npm/private/npm_translate_lock_generate.bzl @@ -18,7 +18,7 @@ _NPM_IMPORT_TMPL = \ version = "{version}", url = "{url}", system_tar = "{system_tar}", - package_visibility = {package_visibility},{maybe_dev}{maybe_commit}{maybe_generate_bzl_library_targets}{maybe_integrity}{maybe_deps}{maybe_transitive_closure}{maybe_patches}{maybe_patch_args}{maybe_lifecycle_hooks}{maybe_custom_postinstall}{maybe_lifecycle_hooks_env}{maybe_lifecycle_hooks_execution_requirements}{maybe_bins}{maybe_npm_auth}{maybe_npm_auth_basic}{maybe_npm_auth_username}{maybe_npm_auth_password}{maybe_replace_package}{maybe_lifecycle_hooks_use_default_shell_env} + package_visibility = {package_visibility},{maybe_dev}{maybe_commit}{maybe_generate_bzl_library_targets}{maybe_integrity}{maybe_deps}{maybe_transitive_closure}{maybe_patches}{maybe_patch_tool}{maybe_patch_args}{maybe_lifecycle_hooks}{maybe_custom_postinstall}{maybe_lifecycle_hooks_env}{maybe_lifecycle_hooks_execution_requirements}{maybe_bins}{maybe_npm_auth}{maybe_npm_auth_basic}{maybe_npm_auth_username}{maybe_npm_auth_password}{maybe_replace_package}{maybe_lifecycle_hooks_use_default_shell_env} ) """ @@ -511,6 +511,8 @@ def _gen_npm_import(rctx, system_tar, _import, link_workspace): deps = %s,""" % starlark_codegen_utils.to_dict_attr(_import.deps, 2)) if len(_import.deps) > 0 else "" maybe_transitive_closure = (""" transitive_closure = %s,""" % starlark_codegen_utils.to_dict_list_attr(_import.transitive_closure, 2)) if len(_import.transitive_closure) > 0 else "" + maybe_patch_tool = (""" + patch_tool = "%s",""" % _import.patch_tool) if _import.patch_tool else "" maybe_patches = (""" patches = %s,""" % _import.patches) if len(_import.patches) > 0 else "" maybe_patch_args = (""" @@ -562,6 +564,7 @@ def _gen_npm_import(rctx, system_tar, _import, link_workspace): maybe_npm_auth_basic = maybe_npm_auth_basic, maybe_npm_auth_password = maybe_npm_auth_password, maybe_npm_auth_username = maybe_npm_auth_username, + maybe_patch_tool = maybe_patch_tool, maybe_patch_args = maybe_patch_args, maybe_patches = maybe_patches, maybe_replace_package = maybe_replace_package, diff --git a/npm/private/npm_translate_lock_helpers.bzl b/npm/private/npm_translate_lock_helpers.bzl index 841195027..af0bf0ce0 100644 --- a/npm/private/npm_translate_lock_helpers.bzl +++ b/npm/private/npm_translate_lock_helpers.bzl @@ -449,6 +449,7 @@ ERROR: can not apply both `pnpm.patchedDependencies` and `npm_translate_lock(pat name = repo_name, package = name, package_visibility = package_visibility, + patch_tool = attr.patch_tool, patch_args = patch_args, patches = patches, root_package = root_package,