wip preserve symlinks
This commit is contained in:
parent
43f8b3e524
commit
e8d14e8801
|
@ -1,5 +1,21 @@
|
|||
# Edits mtree files. See the modify_mtree macro in /lib/tar.bzl.
|
||||
{
|
||||
if (preserve_symlink != "") {
|
||||
# By default Bazel reports symlinks as regular file/dir therefore mtree_spec has no way of knowing that a file
|
||||
# is a symlink. This is a problem when we want to preserve symlinks especially for symlink sensitive applications
|
||||
# such as nodejs with pnpm. To work around this we need to determine if a file a symlink and if so, we need to
|
||||
# determine where the symlink points to by calling readlink repeatedly until we get the final destination.
|
||||
#
|
||||
# We then need to decide if it's a symlink based on how many times we had to call readlink and where we ended up.
|
||||
#
|
||||
# Unlike Bazels own symlinks, which points out of the sandbox symlinks, symlinks created by ctx.actions.symlink
|
||||
# stays within the bazel sandbox so it's possible to detect those.
|
||||
#
|
||||
# See https://github.com/bazelbuild/rules_pkg/pull/609
|
||||
if ($0 ~ /type=file/) {
|
||||
|
||||
}
|
||||
}
|
||||
if (strip_prefix != "") {
|
||||
if ($1 == strip_prefix) {
|
||||
# this line declares the directory which is now the root. It may be discarded.
|
||||
|
|
|
@ -137,6 +137,8 @@ def tar(name, mtree = "auto", stamp = 0, **kwargs):
|
|||
def mtree_mutate(
|
||||
name,
|
||||
mtree,
|
||||
srcs = None,
|
||||
preserve_symlinks = False,
|
||||
strip_prefix = None,
|
||||
package_dir = None,
|
||||
mtime = None,
|
||||
|
@ -148,6 +150,8 @@ def mtree_mutate(
|
|||
|
||||
Args:
|
||||
name: name of the target, output will be `[name].mtree`.
|
||||
srcs: source files to be used when resolving symlinks. required if `preserve_symlinks` is set to True.
|
||||
preserve_symlinks: preserve symlinks
|
||||
mtree: input mtree file, typically created by `mtree_spec`.
|
||||
strip_prefix: prefix to remove from all paths in the tar. Files and directories not under this prefix are dropped.
|
||||
package_dir: directory prefix to add to all paths in the tar.
|
||||
|
@ -155,6 +159,7 @@ def mtree_mutate(
|
|||
owner: new uid for all entries.
|
||||
ownername: new uname for all entries.
|
||||
awk_script: may be overridden to change the script containing the modification logic.
|
||||
|
||||
**kwargs: additional named parameters to genrule
|
||||
"""
|
||||
vars = []
|
||||
|
@ -168,6 +173,10 @@ def mtree_mutate(
|
|||
vars.append("-v owner='{}'".format(owner))
|
||||
if ownername:
|
||||
vars.append("-v ownername='{}'".format(ownername))
|
||||
if preserve_symlinks:
|
||||
vars.append("-v preserve_symlinks=1")
|
||||
if not srcs:
|
||||
fail("preserve_symlinks requires srcs to be set in order to resolve symlinks")
|
||||
|
||||
native.genrule(
|
||||
name = name,
|
||||
|
|
|
@ -4,6 +4,7 @@ load("@aspect_bazel_lib//lib:tar.bzl", "mtree_mutate", "mtree_spec", "tar")
|
|||
load("@aspect_bazel_lib//lib:testing.bzl", "assert_archive_contains")
|
||||
load("@bazel_skylib//rules:write_file.bzl", "write_file")
|
||||
load(":asserts.bzl", "assert_tar_listing", "assert_unused_listing")
|
||||
load(":node_modules_tree.bzl", "node_modules_tree")
|
||||
|
||||
# The examples below work with both source files and generated files.
|
||||
# Here we generate a file to use in the examples.
|
||||
|
@ -465,3 +466,22 @@ assert_unused_listing(
|
|||
"lib/tests/tar/unused/space in name.txt",
|
||||
],
|
||||
)
|
||||
|
||||
#############
|
||||
# Example 16: mtree_mutate preserves symlinks
|
||||
node_modules_tree(
|
||||
name = "e16_node_modules",
|
||||
)
|
||||
|
||||
mtree_spec(
|
||||
name = "mtree16",
|
||||
srcs = [
|
||||
":e16_node_modules",
|
||||
],
|
||||
)
|
||||
|
||||
assert_tar_listing(
|
||||
name = "test_16_before_processing",
|
||||
actual = ":mtree16",
|
||||
expected = [],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# https://github.com/bazelbuild/rules_pkg/pull/609
|
||||
def impl(ctx):
|
||||
# packages
|
||||
# - a
|
||||
# - b depends on a
|
||||
store_a = ctx.actions.declare_directory("node_modules/.pnpm/a@0.0.0/node_modules/a")
|
||||
store_b = ctx.actions.declare_directory("node_modules/.pnpm/b@0.0.0/node_modules/b")
|
||||
|
||||
ctx.actions.run_shell(
|
||||
outputs = [store_a, store_b],
|
||||
command = "echo 'test' > %s/package.json" % store_a.path,
|
||||
)
|
||||
|
||||
dep_symlink_b_to_a = ctx.actions.declare_directory("node_modules/.pnpm/b@0.0.0/node_modules/a")
|
||||
|
||||
ctx.actions.symlink(
|
||||
output = dep_symlink_b_to_a,
|
||||
target_file = store_a,
|
||||
)
|
||||
|
||||
node_modules_a = ctx.actions.declare_directory("node_modules/a")
|
||||
ctx.actions.symlink(
|
||||
output = node_modules_a,
|
||||
target_file = store_a,
|
||||
)
|
||||
|
||||
# single file
|
||||
a = ctx.actions.declare_file("dir/a")
|
||||
ctx.actions.run_shell(
|
||||
outputs = [a],
|
||||
command = "echo 'test' > %s" % a.path,
|
||||
)
|
||||
|
||||
b = ctx.actions.declare_file("dir/b")
|
||||
ctx.actions.symlink(
|
||||
output = b,
|
||||
target_file = a,
|
||||
)
|
||||
|
||||
return DefaultInfo(files = depset([
|
||||
store_a,
|
||||
store_b,
|
||||
dep_symlink_b_to_a,
|
||||
node_modules_a,
|
||||
a,
|
||||
b,
|
||||
]))
|
||||
|
||||
node_modules_tree = rule(
|
||||
implementation = impl,
|
||||
)
|
Loading…
Reference in New Issue