| load("@aspect_bazel_lib//lib:copy_directory.bzl", "copy_directory") | 
 | load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test") | 
 | 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: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)", | 
 |     target_compatible_with = select({ | 
 |         # bsdtar.exe: -s is not supported by this version of bsdtar | 
 |         "@platforms//os:windows": ["@platforms//:incompatible"], | 
 |         "//conditions:default": [], | 
 |     }), | 
 |     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 = [ | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/", | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/", | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/", | 
 |         "-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 low-tech way to mutate the mtree specification, just using regex. | 
 | # See docs on tar about future directions for mtree mutation | 
 | 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 '{}' <$< | sed '/^\\ /d' > $@".format( | 
 |         "; ".join(reversed([ | 
 |             "s#^{s}/##; s#^{s}##".format(s = "/".join(package_name().split("/")[:i])) | 
 |             for (i, _) in enumerate( | 
 |                 package_name().split("/"), | 
 |                 1, | 
 |             ) | 
 |         ])), | 
 |     ), | 
 | ) | 
 |  | 
 | 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 = [ | 
 |         "//lib: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"], | 
 |     out = "6.tar", | 
 | ) | 
 |  | 
 | 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 | 
 |       ) > $@ | 
 |     """, | 
 |     target_compatible_with = select({ | 
 |         # requires runfiles tree, otherwise get | 
 |         # ERROR: cannot find bazel_tools/tools/bash/runfiles/runfiles.bash | 
 |         "@platforms//os:windows": ["@platforms//:incompatible"], | 
 |         # TODO(sahin): incompatible with bzlmod | 
 |         "@aspect_bazel_lib//lib:bzlmod": ["@platforms//:incompatible"], | 
 |         "//conditions:default": [], | 
 |     }), | 
 |     toolchains = ["@bsd_tar_toolchains//:resolved_toolchain"], | 
 | ) | 
 |  | 
 | diff_test( | 
 |     name = "test_runfiles", | 
 |     timeout = "short", | 
 |     file1 = "src_file", | 
 |     file2 = "cat_src_file_output", | 
 | ) | 
 |  | 
 | # Case 7: treeartifacts and source directories | 
 | copy_directory( | 
 |     name = "treeartifact", | 
 |     src = "srcdir", | 
 |     out = "treeartifact", | 
 | ) | 
 |  | 
 | tar( | 
 |     name = "dirs", | 
 |     # Note, testonly should be propagated, proven by | 
 |     # % bazel query --output=label_kind 'attr("testonly", 1,lib/tests/tar:all)' | 
 |     # mtree_spec rule //lib/tests/tar:_dirs.mtree | 
 |     # tar rule //lib/tests/tar:dirs | 
 |     testonly = True, | 
 |     srcs = glob(["srcdir/**"]) + [ | 
 |         "treeartifact", | 
 |     ], | 
 |     out = "7.tar", | 
 | ) | 
 |  | 
 | assert_tar_listing( | 
 |     name = "test_dirs", | 
 |     actual = "dirs", | 
 |     expected = [ | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/", | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/", | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/", | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/srcdir/", | 
 |         "-rwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/srcdir/info", | 
 |         "-rwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/srcdir/pkg", | 
 |         "drwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/treeartifact/", | 
 |         "-rwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/treeartifact/info", | 
 |         "-rwxr-xr-x  0 0      0           0 Jan  1  2023 lib/tests/tar/treeartifact/pkg", | 
 |     ], | 
 | ) | 
 |  | 
 | # Case 8: setting owner of files | 
 | _SRCS8 = [ | 
 |     ":fixture1", | 
 |     "src_file", | 
 | ] | 
 |  | 
 | mtree_spec( | 
 |     name = "mtree8", | 
 |     srcs = _SRCS8, | 
 | ) | 
 |  | 
 | # This is a very simple way to mutate the mtree specification, just using regex. | 
 | # See docs on tar about future directions for mtree mutation | 
 | genrule( | 
 |     name = "change_owner", | 
 |     srcs = ["mtree8"], | 
 |     outs = ["mtree8.mutated"], | 
 |     # Modify uid and gid, 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 | 
 |     # -> | 
 |     # lib/tests/tar/a uid=1000 gid=500 time=1672560000 mode=0755 type=file content=bazel-out/darwin_arm64-opt/bin/lib/tests/tar/a | 
 |     cmd = "sed 's/uid=0/uid=1000/;s/gid=0/gid=500/' <$< >$@", | 
 | ) | 
 |  | 
 | tar( | 
 |     name = "tar_change_owner", | 
 |     srcs = _SRCS8, | 
 |     out = "8.tar", | 
 |     mtree = "change_owner", | 
 | ) | 
 |  | 
 | assert_tar_listing( | 
 |     name = "test_change_owner", | 
 |     actual = "tar_change_owner", | 
 |     expected = [ | 
 |         "drwxr-xr-x  0 1000   500         0 Jan  1  2023 lib/", | 
 |         "drwxr-xr-x  0 1000   500         0 Jan  1  2023 lib/tests/", | 
 |         "drwxr-xr-x  0 1000   500         0 Jan  1  2023 lib/tests/tar/", | 
 |         "-rwxr-xr-x  0 1000   500         7 Jan  1  2023 lib/tests/tar/a", | 
 |         "-rwxr-xr-x  0 1000   500        21 Jan  1  2023 lib/tests/tar/src_file", | 
 |     ], | 
 | ) | 
 |  | 
 | # Case 9: Files from a different repository (#697) | 
 | # Note: This test uses an exported file from skylib, so we do not need to create | 
 | # an additional workspace just for this test. | 
 |  | 
 | tar( | 
 |     name = "tar_different_repo", | 
 |     srcs = ["@bazel_skylib//:LICENSE"], | 
 |     out = "9.tar", | 
 | ) | 
 |  | 
 | assert_archive_contains( | 
 |     name = "test_different_repo", | 
 |     archive = "9.tar", | 
 |     expected = [ | 
 |         "LICENSE", | 
 |     ], | 
 | ) |