Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor mtree_spec to vis encode filenames #795

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion e2e/smoke/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test")
load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template")
load("@aspect_bazel_lib//lib:jq.bzl", "jq")
load("@aspect_bazel_lib//lib:tar.bzl", "tar")
load("@aspect_bazel_lib//lib:tar.bzl", "mtree_spec", "tar")
load("@aspect_bazel_lib//lib:yq.bzl", "yq")

# Validate that JQ works and resolves its toolchain
Expand Down Expand Up @@ -93,6 +93,28 @@ tar(
mtree = [],
)

mtree_spec(
name = "testdata_mtree",
srcs = [":testdata_files"],
)

tar(
name = "testdata_tar",
srcs = [":testdata_files"],
mtree = [":testdata_mtree"],
)

filegroup(
name = "testdata_files",
srcs = glob(["testdata/**/*"]),
)

diff_test(
name = "mtree_golden_test",
file1 = ":testdata_mtree",
file2 = "testdata_mtree.spec.golden",
)

bats_test(
name = "bats",
srcs = [
Expand Down
Empty file.
Empty file.
Empty file.
4 changes: 4 additions & 0 deletions e2e/smoke/testdata_mtree.spec.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
testdata uid=0 gid=0 time=1672560000 mode=0755 type=dir
testdata/file\040empty\040with\040spaces.txt uid=0 gid=0 time=1672560000 mode=0755 type=file content=testdata/file\040empty\040with\040spaces.txt
testdata/file\040empty\040with\040\360\237\230\215.txt uid=0 gid=0 time=1672560000 mode=0755 type=file content=testdata/file\040empty\040with\040\360\237\230\215.txt
testdata/file-empty.txt uid=0 gid=0 time=1672560000 mode=0755 type=file content=testdata/file-empty.txt
56 changes: 44 additions & 12 deletions lib/private/tar.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -161,17 +161,15 @@ def _tar_impl(ctx):
return DefaultInfo(files = depset([out]), runfiles = ctx.runfiles([out]))

def _mtree_line(file, type, content = None, uid = "0", gid = "0", time = "1672560000", mode = "0755"):
spec = [
file,
"uid=" + uid,
"gid=" + gid,
"time=" + time,
"mode=" + mode,
"type=" + type,
]
if content:
spec.append("content=" + content)
return " ".join(spec)
return json.encode(struct(
file = file,
uid = uid,
gid = gid,
time = time,
mode = mode,
type = type,
content = content,
))

# This function exactly same as the one from "@aspect_bazel_lib//lib:paths.bzl"
# except that it takes workspace_name directly instead of the ctx object.
Expand All @@ -198,6 +196,7 @@ def _expand(file, expander, transform = to_repository_relative_path):

def _mtree_impl(ctx):
out = ctx.outputs.out or ctx.actions.declare_file(ctx.attr.name + ".spec")
json_out = ctx.actions.declare_file(out.basename + ".json", sibling = out)

content = ctx.actions.args()
content.set_param_file_format("multiline")
Expand Down Expand Up @@ -230,7 +229,40 @@ def _mtree_impl(ctx):
allow_closure = True,
)

ctx.actions.write(out, content = content)
ctx.actions.write(json_out, content = content)

jq_bin = ctx.toolchains["@aspect_bazel_lib//lib:jq_toolchain_type"].jqinfo.bin

ctx.actions.run_shell(
tools = [jq_bin],
inputs = [json_out],
outputs = [out],
command = """
while IFS= read -r jsonl; do
file=$({jq} -r '.file' <<< "$jsonl")
gid=$({jq} -r '.gid' <<< "$jsonl")
uid=$({jq} -r '.uid' <<< "$jsonl")
time=$({jq} -r '.time' <<< "$jsonl")
mode=$({jq} -r '.mode' <<< "$jsonl")
type=$({jq} -r '.type' <<< "$jsonl")
content=$({jq} -r '.content' <<< "$jsonl")

file_encoded=$(echo -n "$file" | vis -wo)
mtree_line="$file_encoded uid=$uid gid=$gid time=$time mode=$mode type=$type"
if [ "$content" != "null" ]; then
content_encoded=$(echo -n "$content" | vis -wo)
mtree_line="$mtree_line content=$content_encoded"
fi

echo "$mtree_line" >> {output}
done < {input}
""".format(
jq = jq_bin.path,
input = json_out.path,
output = out.path,
),
mnemonic = "MtreeSpec",
)

return DefaultInfo(files = depset([out]), runfiles = ctx.runfiles([out]))

Expand Down
1 change: 1 addition & 0 deletions lib/tar.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ mtree_spec = rule(
doc = "Create an mtree specification to map a directory hierarchy. See https://man.freebsd.org/cgi/man.cgi?mtree(8)",
implementation = _tar_lib.mtree_implementation,
attrs = _tar_lib.mtree_attrs,
toolchains = ["@aspect_bazel_lib//lib:jq_toolchain_type"],
)

tar_rule = _tar
Expand Down
Loading