Skip to content

Commit

Permalink
fix: allow users to provide the version of @pnpm repo (#1741)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeagle authored May 16, 2024
1 parent 5d41461 commit 97d0966
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 17 deletions.
4 changes: 2 additions & 2 deletions docs/npm_translate_lock.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions e2e/bzlmod/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ use_repo(npm, "npm_meaning-of-life__links")

pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm")

# Choose a different version of pnpm - note that only the "root" module may do this,
# not some transitive dependency.
pnpm.pnpm(
name = "pnpm",
pnpm_version = "8.15.2",
)

# Allows developers to run the identical version of pnpm for local workflows like
# bazel run -- @pnpm --dir $PWD install
use_repo(pnpm, "pnpm")
52 changes: 44 additions & 8 deletions npm/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ See https://bazel.build/docs/bzlmod#extension-definition

load("@bazel_features//:features.bzl", "bazel_features")
load("//npm:repositories.bzl", "npm_import", "pnpm_repository", _LATEST_PNPM_VERSION = "LATEST_PNPM_VERSION")
load("//npm/private:npm_import.bzl", "npm_import_lib", "npm_import_links_lib")
load("//npm/private:npm_translate_lock.bzl", "npm_translate_lock", "npm_translate_lock_lib")
load("//npm/private:npm_translate_lock_helpers.bzl", npm_translate_lock_helpers = "helpers")
load("//npm/private:npm_translate_lock_macro_helpers.bzl", macro_helpers = "helpers")
load("//npm/private:npm_import.bzl", "npm_import_lib", "npm_import_links_lib")
load("//npm/private:npm_translate_lock_state.bzl", "npm_translate_lock_state")
load("//npm/private:npmrc.bzl", "parse_npmrc")
load("//npm/private:transitive_closure.bzl", "translate_to_transitive_closure")
load("//npm/private:utils.bzl", "utils")

LATEST_PNPM_VERSION = _LATEST_PNPM_VERSION
_DEFAULT_PNPM_REPO_NAME = "pnpm"

def _npm_extension_impl(module_ctx):
for mod in module_ctx.modules:
Expand Down Expand Up @@ -250,22 +251,57 @@ npm = module_extension(
},
)

# copied from https://github.com/bazelbuild/bazel-skylib/blob/b459822483e05da514b539578f81eeb8a705d600/lib/versions.bzl#L60
# to avoid taking a dependency on skylib here
def _parse_version(version):
return tuple([int(n) for n in version.split(".")])

def _pnpm_extension_impl(module_ctx):
registrations = {}
integrity = {}
for mod in module_ctx.modules:
for attr in mod.tags.pnpm:
pnpm_repository(
name = attr.name,
pnpm_version = (
(attr.pnpm_version, attr.pnpm_version_integrity) if attr.pnpm_version_integrity else attr.pnpm_version
),
)
if attr.name != _DEFAULT_PNPM_REPO_NAME and not mod.is_root:
fail("""\
Only the root module may override the default name for the pnpm repository.
This prevents conflicting registrations in the global namespace of external repos.
""")
if attr.name not in registrations.keys():
registrations[attr.name] = []
registrations[attr.name].append(attr.pnpm_version)
if attr.pnpm_version_integrity:
integrity[attr.pnpm_version] = attr.pnpm_version_integrity
for name, versions in registrations.items():
# Use "Minimal Version Selection" like bzlmod does for resolving module conflicts
# Note, the 'sorted(list)' function in starlark doesn't allow us to provide a custom comparator
if len(versions) > 1:
selected = versions[0]
selected_tuple = _parse_version(selected)
for idx in range(1, len(versions)):
if _parse_version(versions[idx]) > selected_tuple:
selected = versions[idx]
selected_tuple = _parse_version(selected)

# buildifier: disable=print
print("NOTE: repo '{}' has multiple versions {}; selected {}".format(name, versions, selected))
else:
selected = versions[0]

pnpm_repository(
name = name,
pnpm_version = (selected, integrity[selected]) if selected in integrity.keys() else selected,
)

pnpm = module_extension(
implementation = _pnpm_extension_impl,
tag_classes = {
"pnpm": tag_class(
attrs = {
"name": attr.string(),
"name": attr.string(
doc = """Name of the generated repository, allowing more than one pnpm version to be registered.
Overriding the default is only permitted in the root module.""",
default = _DEFAULT_PNPM_REPO_NAME,
),
"pnpm_version": attr.string(default = LATEST_PNPM_VERSION),
"pnpm_version_integrity": attr.string(),
},
Expand Down
8 changes: 1 addition & 7 deletions npm/private/npm_translate_lock.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -507,13 +507,7 @@ def npm_translate_lock(
Can be left unspecified and the rules_js default `LATEST_PNPM_VERSION` will be used.
Use `use_pnpm` for bzlmod.
use_pnpm: label of the pnpm extension to use.
Can be left unspecified and the rules_js default pnpm extension (with the `LATEST_PNPM_VERSION`) will be used.
Use `pnpm_version` for non-bzlmod.
use_pnpm: label of the pnpm entry point to use.
register_copy_directory_toolchains: if True, `@aspect_bazel_lib//lib:repositories.bzl` `register_copy_directory_toolchains()` is called if the toolchain is not already registered
Expand Down

0 comments on commit 97d0966

Please sign in to comment.