Skip to content

Commit c86a442

Browse files
committed
Fix bad rebase
1 parent b024468 commit c86a442

File tree

3 files changed

+391
-228
lines changed

3 files changed

+391
-228
lines changed

npm/private/npm_translate_lock.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ See https://github.com/aspect-build/rules_js/issues/1445
162162

163163
generate_repository_files(
164164
rctx,
165+
state.label_store.label("pnpm_lock"),
165166
importers,
166167
packages,
167168
state.patched_dependencies(),

npm/private/npm_translate_lock_generate.bzl

Lines changed: 192 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -145,66 +145,93 @@ sh_binary(
145145
"package": name,
146146
"path": dep_path,
147147
"link_packages": {},
148+
"link_dev_packages": {},
148149
"deps": transitive_deps,
149150
}
150151

151152
# Look for first-party links in importers
152153
for import_path, importer in importers.items():
153-
dependencies = importer.get("all_deps")
154-
if type(dependencies) != "dict":
155-
msg = "expected dict of dependencies in processed importer '{}'".format(import_path)
156-
fail(msg)
157154
link_package = helpers.link_package(root_package, import_path)
158-
for dep_package, dep_version in dependencies.items():
159-
if dep_version.startswith("file:"):
160-
dep_key = "{}+{}".format(dep_package, dep_version)
161-
if not dep_key in fp_links.keys():
162-
# Ignore file: dependencies on packages such as file: tarballs
163-
# TODO(3.0): remove with pnpm <v9
164-
if dep_version in packages:
165-
continue
166-
167-
# pnpm >=v9 where packages always have name@version
168-
if "{}@{}".format(dep_package, dep_version) in packages:
169-
continue
170-
171-
msg = "Expected to file: referenced package {} in first-party links {}".format(dep_key, fp_links.keys())
172-
fail(msg)
173-
fp_links[dep_key]["link_packages"][link_package] = True
174-
elif dep_version.startswith("link:"):
175-
dep_link = dep_version[len("link:"):]
176-
dep_path = helpers.link_package(root_package, dep_link)
177-
dep_key = "{}+{}".format(dep_package, dep_path)
178-
if fp_links.get(dep_key, False):
179-
fp_links[dep_key]["link_packages"][link_package] = True
180-
else:
181-
transitive_deps = {}
182-
raw_deps = {}
183-
if importers.get(dep_link, False):
184-
raw_deps = importers.get(dep_link).get("deps")
185-
for raw_package, raw_version in raw_deps.items():
186-
package_store_name = utils.package_store_name(raw_package, raw_version)
187-
dep_store_target = """"//{root_package}:{package_store_root}/{{}}/{package_store_name}".format(name)""".format(
188-
root_package = root_package,
189-
package_store_name = package_store_name,
190-
package_store_root = utils.package_store_root,
191-
)
192-
if dep_store_target not in transitive_deps:
193-
transitive_deps[dep_store_target] = [raw_package]
194-
else:
195-
transitive_deps[dep_store_target].append(raw_package)
196155

197-
# collapse link aliases lists into to a comma separated strings
198-
for dep_store_target in transitive_deps.keys():
199-
transitive_deps[dep_store_target] = ",".join(transitive_deps[dep_store_target])
200-
fp_links[dep_key] = {
201-
"package": dep_package,
202-
"path": dep_path,
203-
"link_packages": {link_package: True},
204-
"deps": transitive_deps,
205-
}
156+
prod_deps = importer.get("deps", {})
157+
all_deps = importer.get("all_deps", {})
158+
159+
dev_deps = {}
160+
for dep_name, dep_version in all_deps.items():
161+
if dep_name not in prod_deps:
162+
dev_deps[dep_name] = dep_version
163+
164+
for deps_type, deps in [("link_packages", prod_deps), ("link_dev_packages", dev_deps)]:
165+
for dep_package, dep_version in deps.items():
166+
if dep_version.startswith("file:"):
167+
dep_key = "{}+{}".format(dep_package, dep_version)
168+
if not dep_key in fp_links.keys():
169+
# Ignore file: dependencies on packages such as file: tarballs
170+
# TODO(3.0): remove with pnpm <v9
171+
if dep_version in packages:
172+
continue
173+
174+
# pnpm >=v9 where packages always have name@version
175+
if "{}@{}".format(dep_package, dep_version) in packages:
176+
continue
177+
178+
msg = "Expected to file: referenced package {} in first-party links {}".format(dep_key, fp_links.keys())
179+
fail(msg)
180+
if deps_type not in fp_links[dep_key]:
181+
fp_links[dep_key][deps_type] = {}
182+
fp_links[dep_key][deps_type][link_package] = True
183+
elif dep_version.startswith("link:"):
184+
dep_link = dep_version[len("link:"):]
185+
dep_path = helpers.link_package(root_package, dep_link)
186+
dep_key = "{}+{}".format(dep_package, dep_path)
187+
if fp_links.get(dep_key, False):
188+
if deps_type not in fp_links[dep_key]:
189+
fp_links[dep_key][deps_type] = {}
190+
fp_links[dep_key][deps_type][link_package] = True
191+
else:
192+
transitive_deps = {}
193+
raw_deps = {}
194+
if importers.get(dep_link, False):
195+
raw_deps = importers.get(dep_link).get("deps")
196+
for raw_package, raw_version in raw_deps.items():
197+
package_store_name = utils.package_store_name(raw_package, raw_version)
198+
dep_store_target = """"//{root_package}:{package_store_root}/{{}}/{package_store_name}".format(name)""".format(
199+
root_package = root_package,
200+
package_store_name = package_store_name,
201+
package_store_root = utils.package_store_root,
202+
)
203+
if dep_store_target not in transitive_deps:
204+
transitive_deps[dep_store_target] = [raw_package]
205+
else:
206+
transitive_deps[dep_store_target].append(raw_package)
207+
208+
for dep_store_target in transitive_deps.keys():
209+
transitive_deps[dep_store_target] = ",".join(transitive_deps[dep_store_target])
210+
fp_links[dep_key] = {
211+
"package": dep_package,
212+
"path": dep_path,
213+
"link_packages": {},
214+
"link_dev_packages": {},
215+
"deps": transitive_deps,
216+
}
217+
fp_links[dep_key][deps_type][link_package] = True
218+
219+
importer_deps_map = {}
220+
for import_path, importer in importers.items():
221+
link_package = helpers.link_package(root_package, import_path)
222+
prod_deps = importer.get("deps", {})
223+
all_deps = importer.get("all_deps", {})
224+
225+
pkg_deps = {}
226+
for dep_name, dep_version in all_deps.items():
227+
is_dev = dep_name not in prod_deps
228+
pkg_deps[dep_name] = {"version": dep_version, "dev": is_dev}
206229

207-
npm_link_packages_const = """_LINK_PACKAGES = {link_packages}""".format(link_packages = str(link_packages))
230+
importer_deps_map[link_package] = pkg_deps
231+
232+
npm_link_packages_const = """_LINK_PACKAGES = {link_packages}""".format(
233+
link_packages = str(link_packages),
234+
)
208235

209236
# Generate visibility configuration first to check if it's actually non-empty
210237
npm_visibility_config_generated = _generate_npm_visibility_config(rctx.attr.package_visibility)
@@ -222,7 +249,10 @@ sh_binary(
222249
npm_link_targets_bzl = [
223250
"""\
224251
# buildifier: disable=function-docstring
225-
def npm_link_targets(name = "node_modules", package = None):
252+
def npm_link_targets(name = "node_modules", package = None, prod = True, dev = True):
253+
if not prod and not dev:
254+
fail("npm_link_targets: at least one of 'prod' or 'dev' must be True")
255+
226256
bazel_package = package if package != None else native.package_name()
227257
link = bazel_package in _LINK_PACKAGES
228258
@@ -241,7 +271,10 @@ def npm_link_targets(name = "node_modules", package = None):
241271
npm_link_all_packages_bzl = [
242272
"""\
243273
# buildifier: disable=function-docstring
244-
def npm_link_all_packages(name = "node_modules", imported_links = []):
274+
def npm_link_all_packages(name = "node_modules", imported_links = [], prod = True, dev = True):
275+
if not prod and not dev:
276+
fail("npm_link_all_packages: at least one of 'prod' or 'dev' must be True")
277+
245278
bazel_package = native.package_name()
246279
root_package = "{root_package}"
247280
is_root = bazel_package == root_package
@@ -253,7 +286,7 @@ def npm_link_all_packages(name = "node_modules", imported_links = []):
253286
scope_targets = {{}}
254287
255288
for link_fn in imported_links:
256-
new_link_targets, new_scope_targets = link_fn(name)
289+
new_link_targets, new_scope_targets = link_fn(name, prod, dev)
257290
link_targets.extend(new_link_targets)
258291
for _scope, _targets in new_scope_targets.items():
259292
if _scope not in scope_targets:
@@ -299,25 +332,34 @@ def npm_link_all_packages(name = "node_modules", imported_links = []):
299332
if build_file not in rctx_files:
300333
rctx_files[build_file] = []
301334

302-
# the bzl files for the package being linked
303335
if link_package not in links_bzl:
304336
links_bzl[link_package] = []
305337
if link_package not in links_targets_bzl:
306-
links_targets_bzl[link_package] = []
338+
links_targets_bzl[link_package] = {"all": [], "prod": [], "dev": []}
307339

308340
# for each alias of this package
309341
for link_alias in link_aliases:
310-
# link the alias to the underlying package
311342
links_bzl[link_package].append(""" link_{i}("{{}}/{alias}".format(name), link_root_name = name, link_alias = "{alias}")""".format(
312343
i = i,
313344
alias = link_alias,
314345
))
315346

316-
# expose the alias if public
317347
if "//visibility:public" in _import.package_visibility:
318-
add_to_link_targets = """ link_targets.append(":{{}}/{alias}".format(name))""".format(alias = link_alias)
319-
links_bzl[link_package].append(add_to_link_targets)
320-
links_targets_bzl[link_package].append(add_to_link_targets)
348+
add_to_link_all = """ link_targets.append(":{{}}/{alias}".format(name))""".format(alias = link_alias)
349+
links_bzl[link_package].append(add_to_link_all)
350+
351+
append_stmt_base = """link_targets.append(":{{}}/{alias}".format(name))""".format(alias = link_alias)
352+
353+
links_targets_bzl[link_package]["all"].append(" " + append_stmt_base)
354+
355+
importer_deps = importer_deps_map.get(link_package, {})
356+
dep_info = importer_deps.get(link_alias, {})
357+
is_dev = dep_info.get("dev", False)
358+
359+
if is_dev:
360+
links_targets_bzl[link_package]["dev"].append(" " + append_stmt_base)
361+
else:
362+
links_targets_bzl[link_package]["prod"].append(" " + append_stmt_base)
321363
package_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
322364
if package_scope:
323365
links_bzl[link_package].append(_ADD_SCOPE_TARGET3.format(package_scope = package_scope))
@@ -379,21 +421,55 @@ def npm_link_all_packages(name = "node_modules", imported_links = []):
379421
npm_link_all_packages_bzl.extend(bzl)
380422
first_link = False
381423

424+
# Add first-party packages to npm_link_targets before generating the function
425+
for fp_link in fp_links.values():
426+
fp_package = fp_link.get("package")
427+
for link_type in ["link_packages", "link_dev_packages"]:
428+
fp_link_packages = fp_link.get(link_type, {}).keys()
429+
if len(fp_link_packages) > 0:
430+
# Add first-party package links to npm_link_targets for each package that uses it
431+
for fp_link_package in fp_link_packages:
432+
if fp_link_package not in links_targets_bzl:
433+
links_targets_bzl[fp_link_package] = {"all": [], "prod": [], "dev": []}
434+
435+
fp_append_stmt = """link_targets.append(":{{}}/{pkg}".format(name))""".format(pkg = fp_package)
436+
437+
links_targets_bzl[fp_link_package]["all"].append(" " + fp_append_stmt)
438+
439+
if link_type == "link_dev_packages":
440+
links_targets_bzl[fp_link_package]["dev"].append(" " + fp_append_stmt)
441+
else:
442+
links_targets_bzl[fp_link_package]["prod"].append(" " + fp_append_stmt)
443+
382444
if len(links_targets_bzl) > 0:
383445
npm_link_targets_bzl.append(""" if link:""")
384446
first_link = True
385-
for link_package, bzl in links_targets_bzl.items():
447+
for link_package, lists in links_targets_bzl.items():
386448
npm_link_targets_bzl.append(""" {els}if bazel_package == "{pkg}":""".format(
387449
els = "" if first_link else "el",
388450
pkg = link_package,
389451
))
390-
npm_link_targets_bzl.extend(bzl)
452+
453+
if lists["prod"] or lists["dev"]:
454+
npm_link_targets_bzl.append(""" if prod:""")
455+
if lists["prod"]:
456+
npm_link_targets_bzl.extend(lists["prod"])
457+
else:
458+
npm_link_targets_bzl.append(""" pass""")
459+
460+
npm_link_targets_bzl.append(""" if dev:""")
461+
if lists["dev"]:
462+
npm_link_targets_bzl.extend(lists["dev"])
463+
else:
464+
npm_link_targets_bzl.append(""" pass""")
465+
else:
466+
npm_link_targets_bzl.extend(lists["all"])
467+
391468
first_link = False
392469

393470
for fp_link in fp_links.values():
394471
fp_package = fp_link.get("package")
395472
fp_path = fp_link.get("path")
396-
fp_link_packages = fp_link.get("link_packages").keys()
397473
fp_deps = fp_link.get("deps")
398474
fp_target = "//{}:{}".format(
399475
fp_path,
@@ -412,9 +488,17 @@ def npm_link_all_packages(name = "node_modules", imported_links = []):
412488
if len(package_visibility) == 0:
413489
package_visibility = ["//visibility:public"]
414490

415-
if len(fp_link_packages) > 0:
491+
# Collect all link packages from both prod and dev to avoid duplication
492+
all_fp_link_packages = {}
493+
for link_type in ["link_packages", "link_dev_packages"]:
494+
fp_link_packages = fp_link.get(link_type, {}).keys()
495+
for pkg in fp_link_packages:
496+
all_fp_link_packages[pkg] = True
497+
498+
# Generate a single _FP_DIRECT_TMPL block with all link packages
499+
if len(all_fp_link_packages) > 0:
416500
npm_link_all_packages_bzl.append(_FP_DIRECT_TMPL.format(
417-
link_packages = fp_link_packages,
501+
link_packages = list(all_fp_link_packages.keys()),
418502
link_visibility = package_visibility,
419503
pkg = fp_package,
420504
package_directory_output_group = utils.package_directory_output_group,
@@ -423,22 +507,53 @@ def npm_link_all_packages(name = "node_modules", imported_links = []):
423507
package_store_root = utils.package_store_root,
424508
))
425509

426-
npm_link_targets_bzl.append(_FP_DIRECT_TARGET_TMPL.format(
427-
link_packages = fp_link_packages,
510+
# Now handle the prod/dev specific logic for npm_link_targets
511+
for link_type in ["link_packages", "link_dev_packages"]:
512+
fp_link_packages = fp_link.get(link_type, {}).keys()
513+
if len(fp_link_packages) > 0:
514+
# Also add the first-party package to its own package context
515+
fp_package_path = fp_link.get("path")
516+
if fp_package_path and fp_package_path not in links_targets_bzl:
517+
links_targets_bzl[fp_package_path] = {"all": [], "prod": [], "dev": []}
518+
519+
if fp_package_path:
520+
append_stmt_self = """link_targets.append(":{{}}/{pkg}".format(name))""".format(pkg = fp_package)
521+
522+
links_targets_bzl[fp_package_path]["all"].append(" " + append_stmt_self)
523+
524+
if link_type == "link_dev_packages":
525+
links_targets_bzl[fp_package_path]["dev"].append(" " + append_stmt_self)
526+
else:
527+
links_targets_bzl[fp_package_path]["prod"].append(" " + append_stmt_self)
528+
529+
if "//visibility:public" in package_visibility:
530+
# Also add this first-party package to npm_link_targets for packages that use it
531+
for fp_link_package in fp_link_packages:
532+
if fp_link_package not in links_targets_bzl:
533+
links_targets_bzl[fp_link_package] = {"all": [], "prod": [], "dev": []}
534+
535+
fp_append_stmt = """link_targets.append(":{{}}/{pkg}".format(name))""".format(pkg = fp_package)
536+
537+
links_targets_bzl[fp_link_package]["all"].append(" " + fp_append_stmt)
538+
539+
if link_type == "link_dev_packages":
540+
links_targets_bzl[fp_link_package]["dev"].append(" " + fp_append_stmt)
541+
else:
542+
links_targets_bzl[fp_link_package]["prod"].append(" " + fp_append_stmt)
543+
544+
# Add to link_all and scope targets (only once, not per link_type)
545+
if len(all_fp_link_packages) > 0 and "//visibility:public" in package_visibility:
546+
add_to_link_all = """ link_targets.append(":{{}}/{pkg}".format(name))""".format(
428547
pkg = fp_package,
429-
))
548+
)
549+
npm_link_all_packages_bzl.append(add_to_link_all)
430550

431-
# Validation at the top of npm_link_all_packages() already checked access to this package.
432-
# If we reached this point, the calling package can access it, so unconditionally add it.
433551
package_scope = fp_package[:fp_package.find("/", 1)] if fp_package[0] == "@" else None
434552
if package_scope:
435-
npm_link_all_packages_bzl.append(""" link_targets.append(":{{}}/{fp_package}".format(name))
436-
if "{package_scope}" not in scope_targets:
553+
npm_link_all_packages_bzl.append(""" if "{package_scope}" not in scope_targets:
437554
scope_targets["{package_scope}"] = [link_targets[-1]]
438555
else:
439-
scope_targets["{package_scope}"].append(link_targets[-1])""".format(fp_package = fp_package, package_scope = package_scope))
440-
else:
441-
npm_link_all_packages_bzl.append(""" link_targets.append(":{{}}/{fp_package}".format(name))""".format(fp_package = fp_package))
556+
scope_targets["{package_scope}"].append(link_targets[-1])""".format(package_scope = package_scope))
442557

443558
# Generate catch all & scoped js_library targets
444559
npm_link_all_packages_bzl.append("""

0 commit comments

Comments
 (0)