| load("@aspect_bazel_lib//lib:tar.bzl", "mtree_spec", "tar") |
| load("@aspect_bazel_lib//lib:testing.bzl", "assert_archive_contains") |
| load("@bazel_skylib//:bzl_library.bzl", "bzl_library") |
| load("@bazel_skylib//rules:diff_test.bzl", "diff_test") |
| load("@bazel_skylib//rules:write_file.bzl", "write_file") |
| load(":asserts.bzl", "assert_tar_listing") |
| |
| write_file( |
| name = "fixture1", |
| out = "a", |
| content = ["hello a"], |
| ) |
| |
| # Case 1: Show that you can run any `tar` command you like, using a genrule. |
| genrule( |
| name = "tar_genrule", |
| srcs = [ |
| ":fixture1", |
| "src_file", |
| ], |
| outs = ["1.tar"], |
| cmd = "$(BSDTAR_BIN) --create --dereference --file $@ -s '#$(BINDIR)##' $(execpath :fixture1) $(execpath src_file)", |
| toolchains = ["@bsd_tar_toolchains//:resolved_toolchain"], |
| ) |
| |
| assert_archive_contains( |
| name = "test_genrule", |
| archive = "1.tar", |
| expected = [ |
| "lib/tests/tar/a", |
| "lib/tests/tar/src_file", |
| ], |
| ) |
| |
| # Case 2: demonstrate using a custom mtree formatted specification. |
| # Copied from the output of `man tar`: |
| # An input file in mtree(5) format can be used to create an output |
| # archive with arbitrary ownership, permissions, or names that differ |
| # from existing data on disk: |
| # $ cat input.mtree |
| # #mtree |
| # usr/bin uid=0 gid=0 mode=0755 type=dir |
| # usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls |
| # $ tar -cvf output.tar @input.mtree |
| tar( |
| name = "tar_custom_mtree", |
| srcs = ["src_file"], |
| mtree = [ |
| "usr/bin uid=0 gid=0 mode=0755 time=1672560000 type=dir", |
| "usr/bin/ls uid=0 gid=0 mode=0755 time=1672560000 type=file content={}/src_file".format(package_name()), |
| ], |
| ) |
| |
| assert_tar_listing( |
| name = "test_custom_mtree", |
| actual = "tar_custom_mtree", |
| expected = [ |
| "drwxr-xr-x 0 0 0 0 Jan 1 2023 usr/bin/", |
| "-rwxr-xr-x 0 0 0 21 Jan 1 2023 usr/bin/ls", |
| ], |
| ) |
| |
| # Case 3: compression |
| tar( |
| name = "tar_compress", |
| srcs = ["a"], |
| out = "3.tgz", |
| compress = "gzip", |
| ) |
| |
| assert_archive_contains( |
| name = "test_compress", |
| archive = "3.tgz", |
| expected = ["lib/tests/tar/a"], |
| type = "tar", |
| ) |
| |
| # Case 4: permit arbitrary flags |
| write_file( |
| name = "fixture4", |
| out = ".git", |
| content = ["it's a folder"], |
| ) |
| |
| tar( |
| name = "tar_flags", |
| srcs = [ |
| ".git", |
| "a", |
| "src_file", |
| ], |
| out = "4.tar", |
| # Due to this argument, .git should not appear in the resulting tar |
| args = ["--exclude-vcs"], |
| ) |
| |
| assert_tar_listing( |
| name = "test_flags", |
| actual = "tar_flags", |
| expected = [ |
| "-rwxr-xr-x 0 0 0 7 Jan 1 2023 lib/tests/tar/a", |
| "-rwxr-xr-x 0 0 0 21 Jan 1 2023 lib/tests/tar/src_file", |
| ], |
| ) |
| |
| # Case 5: strip_prefix |
| _SRCS5 = [ |
| ":fixture1", |
| "src_file", |
| ] |
| |
| mtree_spec( |
| name = "mtree5", |
| srcs = _SRCS5, |
| ) |
| |
| # This is a very simple way to mutate the mtree specification, just using regex. |
| # In theory, this can be used for arbitrary replacements like using mode=644 or something, |
| # but we'll probably have to add a richer API to the mtree_spec rule to make this more ergonomic. |
| genrule( |
| name = "strip_prefix", |
| srcs = ["mtree5"], |
| outs = ["mtree5.stripped"], |
| # Modify lines starting with the package name, e.g. |
| # lib/tests/tar/a uid=0 gid=0 time=1672560000 mode=0755 type=file content=bazel-out/darwin_arm64-opt/bin/lib/tests/tar/a |
| # -> |
| # a uid=0 gid=0 time=1672560000 mode=0755 type=file content=bazel-out/darwin_arm64-opt/bin/lib/tests/tar/a |
| cmd = "sed s#^{}/## <$< >$@".format(package_name()), |
| ) |
| |
| tar( |
| name = "tar_strip_prefix", |
| srcs = _SRCS5, |
| out = "5.tar", |
| mtree = "strip_prefix", |
| ) |
| |
| assert_tar_listing( |
| name = "test_strip_prefix", |
| actual = "tar_strip_prefix", |
| expected = [ |
| "-rwxr-xr-x 0 0 0 7 Jan 1 2023 a", |
| "-rwxr-xr-x 0 0 0 21 Jan 1 2023 src_file", |
| ], |
| ) |
| |
| bzl_library( |
| name = "asserts", |
| srcs = ["asserts.bzl"], |
| visibility = ["//visibility:public"], |
| deps = [ |
| "@bazel_skylib//rules:diff_test", |
| "@bazel_skylib//rules:write_file", |
| ], |
| ) |
| |
| # Case 6: Runfiles |
| sh_binary( |
| name = "cat_src_file", |
| srcs = ["cat_src_file.sh"], |
| data = ["src_file"], |
| deps = ["@bazel_tools//tools/bash/runfiles"], |
| ) |
| |
| tar( |
| name = "tar_runfiles", |
| srcs = [":cat_src_file"], |
| tags = [ |
| # bsdtar does an optimization where it canonicalizes files in the archive with same dev/inode |
| # by hardlinking them to make the archive smaller. This is an unhermetic behavior because |
| # bazel uses different sandboxing mechanisms depending on the platform and they don't suffer |
| # from this problem. |
| # However, on some RBE implementations like buildbuddy where everything is a hardlink (assuming) |
| # this doesn't work as it allows bsdtar to optimize archive by canonicalizing entries. |
| # See: https://github.com/aspect-build/bazel-lib/issues/620 |
| "no-remote-exec", |
| ], |
| ) |
| |
| genrule( |
| name = "run_program_with_runfiles", |
| srcs = [":tar_runfiles"], |
| outs = ["cat_src_file_output"], |
| cmd = """\ |
| export DIR=$$(mktemp -d) |
| $(BSDTAR_BIN) --extract --file $(execpath :tar_runfiles) --directory $$DIR |
| ( |
| cd $$DIR |
| ./lib/tests/tar/cat_src_file |
| ) > $@ |
| """, |
| toolchains = ["@bsd_tar_toolchains//:resolved_toolchain"], |
| ) |
| |
| assert_tar_listing( |
| name = "test_runfiles_listing", |
| actual = "tar_runfiles", |
| expected = [ |
| "-rwxr-xr-x 0 0 0 819 Jan 1 2023 lib/tests/tar/cat_src_file.sh", |
| "-rwxr-xr-x 0 0 0 819 Jan 1 2023 lib/tests/tar/cat_src_file", |
| "-rwxr-xr-x 0 0 0 819 Jan 1 2023 lib/tests/tar/cat_src_file.runfiles/aspect_bazel_lib/lib/tests/tar/cat_src_file.sh", |
| "-rwxr-xr-x 0 0 0 819 Jan 1 2023 lib/tests/tar/cat_src_file.runfiles/aspect_bazel_lib/lib/tests/tar/cat_src_file", |
| "-rwxr-xr-x 0 0 0 21 Jan 1 2023 lib/tests/tar/cat_src_file.runfiles/aspect_bazel_lib/lib/tests/tar/src_file", |
| "-rwxr-xr-x 0 0 0 17312 Jan 1 2023 lib/tests/tar/cat_src_file.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash", |
| ], |
| ) |
| |
| diff_test( |
| name = "test_runfiles", |
| timeout = "short", |
| file1 = "src_file", |
| file2 = "cat_src_file_output", |
| ) |