bazelbuild / rules_pkg

Bazel rules for creating packages of many types (zip, tar, deb, rpm, ...)
Apache License 2.0
217 stars 174 forks source link

prefix-stripped directory artifacts end up with two versions, with and without leading . #676

Closed illicitonion closed 1 year ago

illicitonion commented 1 year ago

For this BUILD.bazel file making a tar of a directory artifact:

load("@rules_pkg//pkg:tar.bzl", "pkg_tar")
load("//:rules.bzl", "make_directory")

# Makes a single file in nested directories: dir-dir/subdir/file
make_directory(
    name = "dir",
)

# Should contain `./subdir/file`
pkg_tar(
    name = "tar",
    srcs = [":dir"],
    strip_prefix = "dir-dir",
)

With this simple directory-creating rule:

def _impl(ctx):
    d = ctx.actions.declare_directory("%s-dir" % ctx.attr.name, sibling = None)
    ctx.actions.run_shell(
        outputs = [d],
        command = "mkdir -p $1/subdir && touch $1/subdir/file",
        arguments = [d.path],
    )
    return [DefaultInfo(files = depset([d]))]

make_directory = rule(
    implementation = _impl,
)

I expect to see just ./subdir/ and ./subdir/file in the tar, but instead have both subdir/ and ./subdir as well as ./subdir/file:

% bazel build :tar            
INFO: Invocation ID: 8045b9ca-4244-4714-a1c2-6520e6d6fdf6
INFO: Analyzed target //:tar (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:tar up-to-date:
  bazel-bin/tar.tar
INFO: Elapsed time: 0.135s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
% tar tvf bazel-bin/tar.tar
drwxr-xr-x  0 0      0           0  1 Jan  2000 subdir/
drwxr-xr-x  0 0      0           0  1 Jan  2000 ./subdir/
-r-xr-xr-x  0 0      0           0  1 Jan  2000 ./subdir/file
skoelden commented 1 year ago

I've had the exact same issue and was on my way writing a report as well. I noticed that the behaviour is correct in pkg_zip but not in pkg_tar. Building on your example, adding

pkg_zip(
    name = "zip",
    srcs = [":dir"],
    strip_prefix = "dir-dir",
)

and modifying make_directory by

command = "mkdir -p $1/subdir && touch $1/subdir/file_in_subdir && touch $1/file_in_root",

building (bazel build //...) results in files with the following structure:

$ tar tvf bazel-bin/tar.tar
-r-xr-xr-x 0/0               0 2000-01-01 01:00 ./file_in_root
drwxr-xr-x 0/0               0 2000-01-01 01:00 subdir/
drwxr-xr-x 0/0               0 2000-01-01 01:00 ./subdir/
-r-xr-xr-x 0/0               0 2000-01-01 01:00 ./subdir/file_in_subdir
$ zipinfo bazel-bin/zip.zip
Archive:  bazel-bin/zip.zip
Zip file size: 412 bytes, number of entries: 4
drwxr-xr-x  2.0 unx        0 b- stor 80-Jan-01 00:00 /
?r-xr-xr-x  2.0 unx        0 b- defN 80-Jan-01 00:00 file_in_root
drwxr-xr-x  2.0 unx        0 b- stor 80-Jan-01 00:00 subdir/
?r-xr-xr-x  2.0 unx        0 b- defN 80-Jan-01 00:00 subdir/file_in_subdir
4 files, 0 bytes uncompressed, 4 bytes compressed:  0.0%

I would have expected them to be equal and consider the zip-one to be correct. Running cd bazel-bin, tar cvf dir-dir.tar dir-dir/ and tar tvf dir-dir.tar also gives the structure I would expect:

dr-xr-xr-x ersko/ersko       0 2023-02-20 10:01 dir-dir/
-r-xr-xr-x ersko/ersko       0 2023-02-20 10:01 dir-dir/file_in_root
dr-xr-xr-x ersko/ersko       0 2023-02-20 10:01 dir-dir/subdir/
-r-xr-xr-x ersko/ersko       0 2023-02-20 10:01 dir-dir/subdir/file_in_subdir

Are you sure you would expect ./subdir/ and ./subdir/file and not subdir/ and subdir/file @illicitonion? My understanding is that the . directory is not supposed to be there.

illicitonion commented 1 year ago

Are you sure you would expect ./subdir/ and ./subdir/file and not subdir/ and subdir/file @illicitonion? My understanding is that the . directory is not supposed to be there.

That's a good point, yeah, I don't expect the . prefix