| 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_mutate", "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, |
| ) |
| |
| mtree_mutate( |
| name = "strip_prefix", |
| mtree = "mtree5", |
| strip_prefix = 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 = [ |
| "//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", |
| # When running remote, BB lays out files with inodes that mtree optimizes into a hardlink |
| tags = ["no-remote-exec"], |
| ) |
| |
| 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", |
| "-rwxr-xr-x 0 0 0 1 Jan 1 2023 lib/tests/tar/srcdir/space in name.txt", |
| "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", |
| "-rwxr-xr-x 0 0 0 1 Jan 1 2023 lib/tests/tar/treeartifact/space in name.txt", |
| ], |
| ) |
| |
| # 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", |
| ], |
| ) |
| |
| # Case 10: Can reference generated files |
| tar( |
| name = "tar_location_expansion", |
| srcs = ["@bazel_skylib//:LICENSE"], |
| out = "10.tar", |
| mtree = [ |
| "a uid=0 gid=0 time=1672560000 mode=0755 type=file content=$(location @bazel_skylib//:LICENSE)", |
| ], |
| ) |
| |
| assert_tar_listing( |
| name = "test_tar_location_expansion", |
| actual = "tar_location_expansion", |
| expected = [ |
| "-rwxr-xr-x 0 0 0 11358 Jan 1 2023 a", |
| ], |
| ) |
| |
| # Case 11: Can create tar without srcs |
| tar( |
| name = "create_tmp", |
| mtree = ["./tmp time=1501783453.0 mode=1777 gid=0 uid=0 type=dir"], |
| ) |
| |
| assert_tar_listing( |
| name = "test_create_create_tmp", |
| actual = "create_tmp", |
| expected = [ |
| "drwxrwxrwt 0 0 0 0 Aug 3 2017 ./tmp/", |
| ], |
| ) |
| |
| # Case 12: arbitrary mtree modifications |
| mtree_mutate( |
| name = "modified1", |
| mtree = "source-casync.mtree", |
| strip_prefix = "xattr", |
| ) |
| |
| diff_test( |
| name = "test1", |
| file1 = "modified1.mtree", |
| file2 = "expected1.mtree", |
| ) |
| |
| mtree_mutate( |
| name = "modified2", |
| mtime = 946684740, # 1999-12-31, 23:59 |
| mtree = "source-casync.mtree", |
| owner = "123", |
| ownername = "fred", |
| ) |
| |
| diff_test( |
| name = "test2", |
| file1 = "modified2.mtree", |
| file2 = "expected2.mtree", |
| ) |