From e7a1ba187c96df78d83f1adb0eac1b7db24f96bc Mon Sep 17 00:00:00 2001 From: Austin Schuh Date: Mon, 1 May 2023 10:36:09 -0700 Subject: [PATCH] Add support for setting uid/gid from pkg_attributes (#671) This enables the user to produce identical tarballs to fix https://github.com/bazelbuild/rules_pkg/issues/670 Signed-off-by: Austin Schuh Co-authored-by: aiuto --- docs/latest.md | 9 +- pkg/install.bzl | 18 ++-- pkg/mappings.bzl | 33 +++++-- pkg/private/manifest.py | 6 +- pkg/private/pkg_files.bzl | 90 ++++++++++++++----- pkg/private/tar/build_tar.py | 5 ++ pkg/private/tar/tar.bzl | 2 + pkg/private/zip/build_zip.py | 2 + tests/mappings/all.manifest.golden | 8 +- tests/mappings/executable.manifest.golden | 8 +- .../executable.manifest.windows.golden | 6 +- tests/mappings/glob_for_texts_manifest.golden | 8 +- tests/mappings/node_modules_manifest.golden | 14 +-- tests/mappings/utf8_manifest.golden | 12 +-- tests/tar/BUILD | 40 ++++++++- tests/tar/pkg_tar_test.py | 17 ++++ 16 files changed, 211 insertions(+), 67 deletions(-) diff --git a/docs/latest.md b/docs/latest.md index f32040a1..483f097e 100755 --- a/docs/latest.md +++ b/docs/latest.md @@ -63,19 +63,22 @@ attributes = pkg_attributes( mode = "0644", user = "root", group = "wheel", + uid = 5, + gid = 7, my_custom_attribute = "some custom value", ) ``` `mode`, `user`, and `group` correspond to common UNIX-style filesystem -permissions. Attributes should always be specified using the `pkg_attributes` -helper macro. +permissions. `uid` and `gid` correspond to the numeric uid/gid. Attributes +should always be specified using the `pkg_attributes` helper macro. Each mapping rule has some default mapping attributes. At this time, the only default is "mode", which will be set if it is not otherwise overridden by the user. If `user` and `group` are not specified, then defaults for them will be chosen -by the underlying package builder. Any specific behavior from package builders +by the underlying package builder. If `uid` and `gid` are not specified, +they will default to 0. Any specific behavior from package builders should not be relied upon. Any other attributes should be specified as additional arguments to diff --git a/pkg/install.bzl b/pkg/install.bzl index 0be91d05..846401d7 100644 --- a/pkg/install.bzl +++ b/pkg/install.bzl @@ -28,13 +28,17 @@ def _pkg_install_script_impl(ctx): files_to_run = [] content_map = {} for src in ctx.attr.srcs: - process_src(content_map, - files_to_run, - src = src, - origin = src.label, - default_mode = "0644", - default_user = None, - default_group = None) + process_src( + content_map, + files_to_run, + src = src, + origin = src.label, + default_mode = "0644", + default_user = None, + default_group = None, + default_uid = None, + default_gid = None, + ) manifest_file = ctx.actions.declare_file(ctx.attr.name + "-install-manifest.json") diff --git a/pkg/mappings.bzl b/pkg/mappings.bzl index e49acd07..b42dd6b2 100644 --- a/pkg/mappings.bzl +++ b/pkg/mappings.bzl @@ -72,15 +72,21 @@ strip_prefix = struct( from_root = _sp_from_root, ) -def pkg_attributes(mode = None, user = None, group = None, **kwargs): +def pkg_attributes( + mode = None, + user = None, + group = None, + uid = None, + gid = None, + **kwargs): """Format attributes for use in package mapping rules. If "mode" is not provided, it will default to the mapping rule's default mode. These vary per mapping rule; consult the respective documentation for more details. - Not providing any of "user", or "group" will result in the package builder - choosing one for you. The chosen value should not be relied upon. + Not providing any of "user", "group", "uid", or "gid" will result in the package + builder choosing one for you. The chosen value should not be relied upon. Well-known attributes outside of the above are documented in the rules_pkg reference. @@ -90,8 +96,10 @@ def pkg_attributes(mode = None, user = None, group = None, **kwargs): Args: mode: string: UNIXy octal permissions, as a string. - user: string: Filesystem owning user. - group: string: Filesystem owning group. + user: string: Filesystem owning user name. + group: string: Filesystem owning group name. + uid: int: Filesystem owning user id. + gid: int: Filesystem owning group id. **kwargs: any other desired attributes. Returns: @@ -105,6 +113,21 @@ def pkg_attributes(mode = None, user = None, group = None, **kwargs): ret["user"] = user if group: ret["group"] = group + if uid != None: + if type(uid) != type(0): + fail('Got "' + str(uid) + '" instead of integer uid') + ret["uid"] = uid + if gid != None: + if type(gid) != type(0): + fail('Got "' + str(gid) + '" instead of integer gid') + ret["gid"] = gid + + if user != None and user.isdigit() and uid == None: + print("Warning: found numeric username and no uid, did you mean to specify the uid instead?") + + if group != None and group.isdigit() and gid == None: + print("Warning: found numeric group and no gid, did you mean to specify the gid instead?") + return json.encode(ret) #### diff --git a/pkg/private/manifest.py b/pkg/private/manifest.py index 57b7ddda..6bfd3871 100644 --- a/pkg/private/manifest.py +++ b/pkg/private/manifest.py @@ -33,15 +33,19 @@ class ManifestEntry(object): mode: str user: str group: str + uid: int + gid: int origin: str = None - def __init__(self, type, dest, src, mode, user, group, origin = None): + def __init__(self, type, dest, src, mode, user, group, uid = None, gid = None, origin = None): self.type = type self.dest = dest self.src = src self.mode = mode self.user = user self.group = group + self.uid = uid + self.gid = gid self.origin = origin def __repr__(self): diff --git a/pkg/private/pkg_files.bzl b/pkg/private/pkg_files.bzl index f0fe60b3..cd8e1ad5 100644 --- a/pkg/private/pkg_files.bzl +++ b/pkg/private/pkg_files.bzl @@ -57,6 +57,8 @@ _DestFile = provider( "link_to": "path to link to. src must not be set", "entry_type": "string. See ENTRY_IS_* values above.", "origin": "target which added this", + "uid": "uid, or empty", + "gid": "gid, or empty", }, ) @@ -83,16 +85,22 @@ def _check_dest(content_map, dest, src, origin): src, ) -def _merge_attributes(info, mode, user, group): +def _merge_attributes(info, mode, user, group, uid, gid): if hasattr(info, "attributes"): attrs = info.attributes mode = attrs.get("mode") or mode user = attrs.get("user") or user group = attrs.get("group") or group - return (mode, user, group) - -def _process_pkg_dirs(content_map, pkg_dirs_info, origin, default_mode, default_user, default_group): - attrs = _merge_attributes(pkg_dirs_info, default_mode, default_user, default_group) + new_uid = attrs.get("uid") + if new_uid != None: + uid = new_uid + new_gid = attrs.get("gid") + if new_gid != None: + gid = new_gid + return (mode, user, group, uid, gid) + +def _process_pkg_dirs(content_map, pkg_dirs_info, origin, default_mode, default_user, default_group, default_uid, default_gid): + attrs = _merge_attributes(pkg_dirs_info, default_mode, default_user, default_group, default_uid, default_gid) for dir in pkg_dirs_info.dirs: dest = dir.strip("/") _check_dest(content_map, dest, None, origin) @@ -102,11 +110,13 @@ def _process_pkg_dirs(content_map, pkg_dirs_info, origin, default_mode, default_ mode = attrs[0], user = attrs[1], group = attrs[2], + uid = attrs[3], + gid = attrs[4], origin = origin, ) -def _process_pkg_files(content_map, pkg_files_info, origin, default_mode, default_user, default_group): - attrs = _merge_attributes(pkg_files_info, default_mode, default_user, default_group) +def _process_pkg_files(content_map, pkg_files_info, origin, default_mode, default_user, default_group, default_uid, default_gid): + attrs = _merge_attributes(pkg_files_info, default_mode, default_user, default_group, default_uid, default_gid) for filename, src in pkg_files_info.dest_src_map.items(): dest = filename.strip("/") _check_dest(content_map, dest, src, origin) @@ -116,12 +126,14 @@ def _process_pkg_files(content_map, pkg_files_info, origin, default_mode, defaul mode = attrs[0], user = attrs[1], group = attrs[2], + uid = attrs[3], + gid = attrs[4], origin = origin, ) -def _process_pkg_symlink(content_map, pkg_symlink_info, origin, default_mode, default_user, default_group): +def _process_pkg_symlink(content_map, pkg_symlink_info, origin, default_mode, default_user, default_group, default_uid, default_gid): dest = pkg_symlink_info.destination.strip("/") - attrs = _merge_attributes(pkg_symlink_info, default_mode, default_user, default_group) + attrs = _merge_attributes(pkg_symlink_info, default_mode, default_user, default_group, default_uid, default_gid) _check_dest(content_map, dest, None, origin) content_map[dest] = _DestFile( src = None, @@ -129,20 +141,22 @@ def _process_pkg_symlink(content_map, pkg_symlink_info, origin, default_mode, de mode = attrs[0], user = attrs[1], group = attrs[2], + uid = attrs[3], + gid = attrs[4], origin = origin, link_to = pkg_symlink_info.target, ) -def _process_pkg_filegroup(content_map, pkg_filegroup_info, origin, default_mode, default_user, default_group): +def _process_pkg_filegroup(content_map, pkg_filegroup_info, origin, default_mode, default_user, default_group, default_uid, default_gid): if hasattr(pkg_filegroup_info, "pkg_dirs"): for d in pkg_filegroup_info.pkg_dirs: - _process_pkg_dirs(content_map, d[0], d[1], default_mode, default_user, default_group) + _process_pkg_dirs(content_map, d[0], d[1], default_mode, default_user, default_group, default_uid, default_gid) if hasattr(pkg_filegroup_info, "pkg_files"): for pf in pkg_filegroup_info.pkg_files: - _process_pkg_files(content_map, pf[0], pf[1], default_mode, default_user, default_group) + _process_pkg_files(content_map, pf[0], pf[1], default_mode, default_user, default_group, default_uid, default_gid) if hasattr(pkg_filegroup_info, "pkg_symlinks"): for psl in pkg_filegroup_info.pkg_symlinks: - _process_pkg_symlink(content_map, psl[0], psl[1], default_mode, default_user, default_group) + _process_pkg_symlink(content_map, psl[0], psl[1], default_mode, default_user, default_group, default_uid, default_gid) def process_src( content_map, @@ -151,7 +165,9 @@ def process_src( origin, default_mode, default_user, - default_group): + default_group, + default_uid, + default_gid): """Add an entry to the content map. Args: @@ -162,6 +178,8 @@ def process_src( default_mode: fallback mode to use for Package*Info elements without mode default_user: fallback user to use for Package*Info elements without user default_group: fallback mode to use for Package*Info elements without group + default_uid: fallback uid to use for Package*Info elements without uid + default_gid: fallback gid to use for Package*Info elements without gid Returns: True if src was a Package*Info and added to content_map. @@ -180,6 +198,8 @@ def process_src( default_mode = default_mode, default_user = default_user, default_group = default_group, + default_uid = default_uid, + default_gid = default_gid, ) found_info = True if PackageFilegroupInfo in src: @@ -190,6 +210,8 @@ def process_src( default_mode = default_mode, default_user = default_user, default_group = default_group, + default_uid = default_uid, + default_gid = default_gid, ) found_info = True if PackageSymlinkInfo in src: @@ -200,6 +222,8 @@ def process_src( default_mode = default_mode, default_user = default_user, default_group = default_group, + default_uid = default_uid, + default_gid = default_gid, ) found_info = True if PackageDirsInfo in src: @@ -210,11 +234,13 @@ def process_src( default_mode = "0555", default_user = default_user, default_group = default_group, + default_uid = default_uid, + default_gid = default_gid, ) found_info = True return found_info -def add_directory(content_map, dir_path, origin, mode = None, user = None, group = None): +def add_directory(content_map, dir_path, origin, mode = None, user = None, group = None, uid = None, gid = None): """Add an empty directory to the content map. Args: @@ -232,9 +258,11 @@ def add_directory(content_map, dir_path, origin, mode = None, user = None, group mode = mode, user = user, group = group, + uid = uid, + gid = gid, ) -def add_empty_file(content_map, dest_path, origin, mode = None, user = None, group = None): +def add_empty_file(content_map, dest_path, origin, mode = None, user = None, group = None, uid = None, gid = None): """Add a single file to the content map. Args: @@ -254,6 +282,8 @@ def add_empty_file(content_map, dest_path, origin, mode = None, user = None, gro mode = mode, user = user, group = group, + uid = uid, + gid = gid, ) def add_label_list( @@ -263,7 +293,9 @@ def add_label_list( srcs, default_mode = None, default_user = None, - default_group = None): + default_group = None, + default_uid = None, + default_gid = None): """Helper method to add a list of labels (typically 'srcs') to a content_map. Args: @@ -274,6 +306,8 @@ def add_label_list( default_mode: fallback mode to use for Package*Info elements without mode default_user: fallback user to use for Package*Info elements without user default_group: fallback mode to use for Package*Info elements without group + default_uid: fallback uid to use for Package*Info elements without uid + default_gid: fallback gid to use for Package*Info elements without guid """ if hasattr(ctx.attr, "include_runfiles"): @@ -297,6 +331,8 @@ def add_label_list( default_mode = default_mode, default_user = default_user, default_group = default_group, + default_uid = default_uid, + default_gid = default_gid, ): # Add in the files of srcs which are not pkg_* types add_from_default_info( @@ -308,6 +344,8 @@ def add_label_list( default_mode = default_mode, default_user = default_user, default_group = default_group, + default_uid = default_uid, + default_gid = default_gid, include_runfiles = include_runfiles, ) @@ -320,6 +358,8 @@ def add_from_default_info( default_mode = None, default_user = None, default_group = None, + default_uid = None, + default_gid = None, include_runfiles = False): """Helper method to add the DefaultInfo of a target to a content_map. @@ -378,6 +418,8 @@ def add_from_default_info( mode = fmode, user = default_user, group = default_group, + uid = default_uid, + gid = default_gid, ) def get_my_executable(src): @@ -409,7 +451,7 @@ def get_my_executable(src): return ftr.executable return None -def add_single_file(content_map, dest_path, src, origin, mode = None, user = None, group = None): +def add_single_file(content_map, dest_path, src, origin, mode = None, user = None, group = None, uid = None, gid = None): """Add an single file to the content map. Args: @@ -430,9 +472,11 @@ def add_single_file(content_map, dest_path, src, origin, mode = None, user = Non mode = mode, user = user, group = group, + uid = uid, + gid = gid, ) -def add_symlink(content_map, dest_path, src, origin, mode = None, user = None, group = None): +def add_symlink(content_map, dest_path, src, origin, mode = None, user = None, group = None, uid = None, gid = None): """Add a symlink to the content map. Args: @@ -454,9 +498,11 @@ def add_symlink(content_map, dest_path, src, origin, mode = None, user = None, g mode = mode, user = user, group = group, + uid = uid, + gid = gid, ) -def add_tree_artifact(content_map, dest_path, src, origin, mode = None, user = None, group = None): +def add_tree_artifact(content_map, dest_path, src, origin, mode = None, user = None, group = None, uid = None, gid = None): """Add an tree artifact (directory output) to the content map. Args: @@ -475,6 +521,8 @@ def add_tree_artifact(content_map, dest_path, src, origin, mode = None, user = N mode = mode, user = user, group = group, + uid = uid, + gid = gid, ) def write_manifest(ctx, manifest_file, content_map, use_short_path=False, pretty_print=False): @@ -532,6 +580,8 @@ def _encode_manifest_entry(dest, df, use_short_path, pretty_print=False): "mode": df.mode or "", "user": df.user or None, "group": df.group or None, + "uid": df.uid, + "gid": df.gid, "origin": origin_str, } diff --git a/pkg/private/tar/build_tar.py b/pkg/private/tar/build_tar.py index aa64ee89..fde98d24 100644 --- a/pkg/private/tar/build_tar.py +++ b/pkg/private/tar/build_tar.py @@ -308,6 +308,11 @@ def add_manifest_entry(self, entry, file_attributes): else: # Use group that legacy tar process would assign attrs['names'] = (entry.user, attrs.get('names')[1]) + if entry.uid is not None: + if entry.gid is not None: + attrs['ids'] = (entry.uid, entry.gid) + else: + attrs['ids'] = (entry.uid, entry.uid) if entry.type == manifest.ENTRY_IS_LINK: self.add_link(entry.dest, entry.src, **attrs) elif entry.type == manifest.ENTRY_IS_DIR: diff --git a/pkg/private/tar/tar.bzl b/pkg/private/tar/tar.bzl index dc901a57..a2caa905 100644 --- a/pkg/private/tar/tar.bzl +++ b/pkg/private/tar/tar.bzl @@ -127,6 +127,8 @@ def _pkg_tar_impl(ctx): default_mode = None, default_user = None, default_group = None, + default_uid = None, + default_gid = None, ): src_files = src[DefaultInfo].files.to_list() if ctx.attr.include_runfiles: diff --git a/pkg/private/zip/build_zip.py b/pkg/private/zip/build_zip.py index 97ef5b10..fe8ffab5 100644 --- a/pkg/private/zip/build_zip.py +++ b/pkg/private/zip/build_zip.py @@ -251,6 +251,8 @@ def _load_manifest(prefix, manifest_path): mode = "0o755", user = None, group = None, + uid = None, + gid = None, origin = "parent directory of {}".format(manifest_map[dest].origin), ) diff --git a/tests/mappings/all.manifest.golden b/tests/mappings/all.manifest.golden index 475ec964..6a5f1072 100644 --- a/tests/mappings/all.manifest.golden +++ b/tests/mappings/all.manifest.golden @@ -1,7 +1,7 @@ [ - {"type": "file", "dest": "BUILD", "src": "tests/mappings/BUILD", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:BUILD"}, - {"type": "dir", "dest": "foodir", "src": null, "mode": "711", "user": "foo", "group": "bar", "origin": "@//tests/mappings:dirs"}, + {"type": "file", "dest": "BUILD", "src": "tests/mappings/BUILD", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:BUILD"}, + {"type": "dir", "dest": "foodir", "src": null, "mode": "711", "user": "foo", "group": "bar", "uid": null, "gid": null, "origin": "@//tests/mappings:dirs"}, - {"type": "file", "dest": "mappings_test.bzl", "src": "tests/mappings/mappings_test.bzl", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:files"}, - {"type": "tree", "dest": "treeartifact", "src": "tests/mappings/treeartifact", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:directory-with-contents"} + {"type": "file", "dest": "mappings_test.bzl", "src": "tests/mappings/mappings_test.bzl", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:files"}, + {"type": "tree", "dest": "treeartifact", "src": "tests/mappings/treeartifact", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:directory-with-contents"} ] diff --git a/tests/mappings/executable.manifest.golden b/tests/mappings/executable.manifest.golden index 7f85aabf..b869a1d8 100644 --- a/tests/mappings/executable.manifest.golden +++ b/tests/mappings/executable.manifest.golden @@ -1,5 +1,5 @@ [ - {"type": "file", "dest": "an_executable.runfiles/tests/BUILD", "src": "tests/BUILD", "mode": "", "user": null, "group": null, "origin": "@//tests:an_executable"}, - {"type": "file", "dest": "an_executable.runfiles/tests/an_executable", "src": "tests/an_executable", "mode": "0755", "user": null, "group": null, "origin": "@//tests:an_executable"}, - {"type": "file", "dest": "an_executable", "src": "tests/an_executable", "mode": "0755", "user": null, "group": null, "origin": "@//tests:an_executable"} -] \ No newline at end of file + {"type": "file", "dest": "an_executable.runfiles/tests/BUILD", "src": "tests/BUILD", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:an_executable"}, + {"type": "file", "dest": "an_executable.runfiles/tests/an_executable", "src": "tests/an_executable", "mode": "0755", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:an_executable"}, + {"type": "file", "dest": "an_executable", "src": "tests/an_executable", "mode": "0755", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:an_executable"} +] diff --git a/tests/mappings/executable.manifest.windows.golden b/tests/mappings/executable.manifest.windows.golden index 55b0804c..b6a22d4c 100644 --- a/tests/mappings/executable.manifest.windows.golden +++ b/tests/mappings/executable.manifest.windows.golden @@ -1,5 +1,5 @@ [ - {"type": "file", "dest": "an_executable.exe.runfiles/tests/BUILD", "src": "tests/BUILD", "mode": "", "user": null, "group": null, "origin": "@//tests:an_executable"}, - {"type": "file", "dest": "an_executable.exe.runfiles/tests/an_executable.exe", "src": "tests/an_executable.exe", "mode": "0755", "user": null, "group": null, "origin": "@//tests:an_executable"}, - {"type": "file", "dest": "an_executable.exe", "src": "tests/an_executable.exe", "mode": "0755", "user": null, "group": null, "origin": "@//tests:an_executable"} + {"type": "file", "dest": "an_executable.exe.runfiles/tests/BUILD", "src": "tests/BUILD", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:an_executable"}, + {"type": "file", "dest": "an_executable.exe.runfiles/tests/an_executable.exe", "src": "tests/an_executable.exe", "mode": "0755", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:an_executable"}, + {"type": "file", "dest": "an_executable.exe", "src": "tests/an_executable.exe", "mode": "0755", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:an_executable"} ] diff --git a/tests/mappings/glob_for_texts_manifest.golden b/tests/mappings/glob_for_texts_manifest.golden index c144b83f..9ff7e216 100644 --- a/tests/mappings/glob_for_texts_manifest.golden +++ b/tests/mappings/glob_for_texts_manifest.golden @@ -1,6 +1,6 @@ [ - {"type": "file", "dest": "file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", "src": "tests/testdata/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", "mode": "", "user": null, "group": null, "origin": "@//tests:glob_for_texts"}, - {"type": "file", "dest": "hello.txt", "src": "tests/testdata/hello.txt", "mode": "", "user": null, "group": null, "origin": "@//tests:glob_for_texts"}, - {"type": "file", "dest": "loremipsum.txt", "src": "tests/testdata/loremipsum.txt", "mode": "", "user": null, "group": null, "origin": "@//tests:glob_for_texts"}, - {"type": "file", "dest": "test_tar_package_dir_file.txt", "src": "tests/testdata/test_tar_package_dir_file.txt", "mode": "", "user": null, "group": null, "origin": "@//tests:glob_for_texts"} + {"type": "file", "dest": "file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", "src": "tests/testdata/file_with_a_ridiculously_long_name_consectetur_adipiscing_elit_fusce_laoreet_lorem_neque_sed_pharetra_erat.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"}, + {"type": "file", "dest": "hello.txt", "src": "tests/testdata/hello.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"}, + {"type": "file", "dest": "loremipsum.txt", "src": "tests/testdata/loremipsum.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"}, + {"type": "file", "dest": "test_tar_package_dir_file.txt", "src": "tests/testdata/test_tar_package_dir_file.txt", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests:glob_for_texts"} ] diff --git a/tests/mappings/node_modules_manifest.golden b/tests/mappings/node_modules_manifest.golden index 436128b8..b234629f 100755 --- a/tests/mappings/node_modules_manifest.golden +++ b/tests/mappings/node_modules_manifest.golden @@ -1,9 +1,9 @@ [ - {"type": "symlink", "dest": "node_modules/.pnpm/bar@1.0.0/node_modules/bar", "src": "STORE/bar", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/bar@1.0.0/node_modules/qar", "src": "../../qar@2.0.0/node_modules/qar", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/bar", "src": "../../bar@1.0.0/node_modules/bar", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/foo", "src": "STORE/foo", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/qar", "src": "../../qar@2.0.0/node_modules/qar", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/.pnpm/qar@2.0.0/node_modules/qar", "src": "STORE/qar", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:node_modules"}, - {"type": "symlink", "dest": "node_modules/foo", "src": ".pnpm/foo@1.0.0/node_modules/foo", "mode": "", "user": null, "group": null, "origin": "@//tests/mappings:node_modules"} + {"type": "symlink", "dest": "node_modules/.pnpm/bar@1.0.0/node_modules/bar", "src": "STORE/bar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, + {"type": "symlink", "dest": "node_modules/.pnpm/bar@1.0.0/node_modules/qar", "src": "../../qar@2.0.0/node_modules/qar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, + {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/bar", "src": "../../bar@1.0.0/node_modules/bar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, + {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/foo", "src": "STORE/foo", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, + {"type": "symlink", "dest": "node_modules/.pnpm/foo@1.0.0/node_modules/qar", "src": "../../qar@2.0.0/node_modules/qar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, + {"type": "symlink", "dest": "node_modules/.pnpm/qar@2.0.0/node_modules/qar", "src": "STORE/qar", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"}, + {"type": "symlink", "dest": "node_modules/foo", "src": ".pnpm/foo@1.0.0/node_modules/foo", "mode": "", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:node_modules"} ] diff --git a/tests/mappings/utf8_manifest.golden b/tests/mappings/utf8_manifest.golden index a875085f..11352ca7 100644 --- a/tests/mappings/utf8_manifest.golden +++ b/tests/mappings/utf8_manifest.golden @@ -1,8 +1,8 @@ [ - {"type": "file", "dest": "1-a", "src": "tests/testdata/utf8/1-a", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "2-λ", "src": "tests/testdata/utf8/2-λ", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "3-世", "src": "tests/testdata/utf8/3-世", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "BUILD", "src": "tests/testdata/utf8/BUILD", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "sübdir/2-λ", "src": "tests/testdata/utf8/sübdir/2-λ", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:utf8_files"}, - {"type": "file", "dest": "sübdir/hello", "src": "tests/testdata/utf8/sübdir/hello", "mode": "0644", "user": null, "group": null, "origin": "@//tests/mappings:utf8_files"} + {"type": "file", "dest": "1-a", "src": "tests/testdata/utf8/1-a", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, + {"type": "file", "dest": "2-λ", "src": "tests/testdata/utf8/2-λ", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, + {"type": "file", "dest": "3-世", "src": "tests/testdata/utf8/3-世", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, + {"type": "file", "dest": "BUILD", "src": "tests/testdata/utf8/BUILD", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, + {"type": "file", "dest": "sübdir/2-λ", "src": "tests/testdata/utf8/sübdir/2-λ", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"}, + {"type": "file", "dest": "sübdir/hello", "src": "tests/testdata/utf8/sübdir/hello", "mode": "0644", "user": null, "group": null, "uid": null, "gid": null, "origin": "@//tests/mappings:utf8_files"} ] diff --git a/tests/tar/BUILD b/tests/tar/BUILD index bd3712b6..629acfe7 100644 --- a/tests/tar/BUILD +++ b/tests/tar/BUILD @@ -15,6 +15,7 @@ """Tests for pkg_tar.""" # buildifier: disable=bzl-visibility +load("//pkg:mappings.bzl", "pkg_attributes") load("//pkg:mappings.bzl", "pkg_files", "pkg_mklink", "strip_prefix") load("//pkg:verify_archive.bzl", "verify_archive_test") load("//pkg/private/tar:tar.bzl", "SUPPORTED_TAR_COMPRESSIONS", "pkg_tar") @@ -123,8 +124,8 @@ pkg_mklink( pkg_tar( name = "test_tar_package_dir", srcs = [ - ":mylink", ":etc/nsswitch.conf", + ":mylink", ], package_dir = "/my/package", ) @@ -343,7 +344,9 @@ py_test( ":test-tar-empty_dirs.tar", ":test-tar-empty_files.tar", ":test-tar-files_dict.tar", + ":test-tar-long-filename", ":test-tar-mtime.tar", + ":test-tar-repackaging-long-filename.tar", ":test-tar-strip_prefix-dot.tar", ":test-tar-strip_prefix-empty.tar", ":test-tar-strip_prefix-etc.tar", @@ -351,11 +354,11 @@ py_test( ":test-tar-strip_prefix-substring.tar", ":test_tar_leading_dotslash", ":test_tar_package_dir_substitution.tar", - ":test-tar-long-filename", - ":test-tar-repackaging-long-filename.tar", ":test-tar-tree-artifact", ":test-tar-tree-artifact-noroot", ":test-tar-with-runfiles", + ":test-pkg-tar-with-attributes", + ":test-pkg-tar-from-pkg-files-with-attributes", ":test-tree-input-with-strip-prefix", "//tests:testdata/tar_test.tar", "//tests:testdata/tar_test.tar.bz2", @@ -397,6 +400,37 @@ pkg_tar( extension = ".tar.gz", ) +pkg_files( + name = "test-pkg-files-with-attributes", + srcs = [ + "//tests:testdata/loremipsum.txt", + ], + attributes = pkg_attributes( + gid = 1000, + group = "grp", + mode = "0440", + uid = 0, + user = "person", + ), + prefix = "/foo/bar", +) + +pkg_tar( + name = "test-pkg-tar-from-pkg-files-with-attributes", + srcs = [ + ":test-pkg-files-with-attributes", + ], +) + +pkg_tar( + name = "test-pkg-tar-with-attributes", + srcs = [ + "//tests:testdata/loremipsum.txt", + ], + owner = "0.1000", + package_dir = "/foo/bar", +) + pkg_tar( name = "test-tar-compression-from-extension-tgz", srcs = [ diff --git a/tests/tar/pkg_tar_test.py b/tests/tar/pkg_tar_test.py index fabdffca..eef744d2 100644 --- a/tests/tar/pkg_tar_test.py +++ b/tests/tar/pkg_tar_test.py @@ -258,6 +258,23 @@ def test_tar_leading_dotslash(self): ] self.assertTarFileContent('test_tar_leading_dotslash.tar', content) + + def test_pkg_tar_with_attributes(self): + content = [ + {'name': 'foo','uid': 0, 'gid': 1000, 'uname': '', 'gname': ''}, + {'name': 'foo/bar','uid': 0, 'gid': 1000, 'uname': '', 'gname': ''}, + {'name': 'foo/bar/loremipsum.txt','uid': 0, 'gid': 1000, 'uname': '', 'gname': ''}, + ] + self.assertTarFileContent('test-pkg-tar-with-attributes.tar', content) + + def test_pkg_files_with_attributes(self): + content = [ + {'name': 'foo','uid': 0, 'gid': 1000, 'uname': 'person', 'gname': 'grp'}, + {'name': 'foo/bar','uid': 0, 'gid': 1000, 'uname': 'person', 'gname': 'grp'}, + {'name': 'foo/bar/loremipsum.txt','uid': 0, 'gid': 1000, 'uname': 'person', 'gname': 'grp'}, + ] + self.assertTarFileContent('test-pkg-tar-from-pkg-files-with-attributes.tar', content) + def test_tar_with_tree_artifact_and_strip_prefix(self): content = [ {'name': 'a', 'isdir': True},