Skip to content

Commit fa81ba1

Browse files
authored
Created bazel level option to control prefix duplication in tar creation.
The `rules_pkg` mainline has the behaviour where it doesn't allow prefix duplication where a subfolder name mimics the top level directory name. Since sometimes this directory structure is desired, a bazel level option was added to control the behaviour. ## Features - Added the `allow_prefix_duplication` flag to tar creation to allow calls to pkg_tar in bazel to control the desired directory structure. This flag defaults to false to mimic the mainline behaviour. Merge Pull Request #2.
2 parents aeeba7f + e9641b9 commit fa81ba1

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

pkg/private/tar/build_tar.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class DebError(Exception):
4444

4545
def __init__(self, output, directory, compression, compressor, create_parents,
4646
allow_dups_from_deps, default_mtime, compression_level,
47-
tar_format=None):
47+
tar_format=None, allow_prefix_duplication=False):
4848
# Directory prefix on all output paths
4949
d = directory.strip('/')
5050
self.directory = (d + '/') if d else None
@@ -56,6 +56,7 @@ def __init__(self, output, directory, compression, compressor, create_parents,
5656
self.allow_dups_from_deps = allow_dups_from_deps
5757
self.compression_level = compression_level
5858
self.tar_format = tar_format
59+
self.allow_prefix_duplication = allow_prefix_duplication
5960

6061
def __enter__(self):
6162
self.tarfile = tar_writer.TarFileWriter(
@@ -80,14 +81,16 @@ def normalize_path(self, path: str) -> str:
8081
# No path should ever come in with slashes on either end, but protect
8182
# against that anyway.
8283
dest = dest.strip('/')
83-
# This prevents a potential problem for users with both a prefix_dir and
84-
# symlinks that also repeat the prefix_dir. The old behavior was that we
85-
# would get just the symlink path. Now we are prefixing with the prefix,
86-
# so you get the file in the wrong place.
87-
# We silently de-dup that. If people come up with a real use case for
88-
# the /a/b/a/b/rest... output we can start an issue and come up with a
89-
# solution at that time.
90-
if self.directory and not dest.startswith(self.directory):
84+
# The default behavior is to not allow duplication of the prefix. If a
85+
# directory structure that contains duplicate prefixes is desired, the
86+
# allow_prefix_duplication flag can be set to True. Preventing prefix
87+
# duplication prevents a potential problem for users with both a prefix_dir
88+
# and symlinks that also repeat the prefix_dir. The behavior can be
89+
# controlled by the user in pkg_tar as a bazel level option to allow fine
90+
# grained control.
91+
if self.directory and self.allow_prefix_duplication:
92+
dest = self.directory + dest
93+
elif self.directory and not dest.startswith(self.directory):
9194
dest = self.directory + dest
9295
return dest
9396

@@ -415,6 +418,11 @@ def main():
415418
parser.add_argument(
416419
'--compression_level', default=-1,
417420
help='Specify the numeric compress level in gzip mode; may be 0-9 or -1 (default to 6).')
421+
parser.add_argument(
422+
'--allow_prefix_duplication', action='store_true',
423+
help='Allow prefix duplication in the output tar. By default prefix duplication is not allowed.' +
424+
' For example if you want to create a tar with package_dir = "a/b" and a srcs = ["a/b/c.txt"],'
425+
' you can set this flag to allow the prefix "a/b" to be duplicated in the tar.')
418426
options = parser.parse_args()
419427

420428
# Parse modes arguments
@@ -481,7 +489,8 @@ def main():
481489
create_parents=options.create_parents,
482490
allow_dups_from_deps=options.allow_dups_from_deps,
483491
compression_level = compression_level,
484-
tar_format=tar_format) as output:
492+
tar_format=tar_format,
493+
allow_prefix_duplication=options.allow_prefix_duplication) as output:
485494

486495
def file_attributes(filename):
487496
if filename.startswith('/'):

pkg/private/tar/tar.bzl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ def _pkg_tar_impl(ctx):
119119
)
120120
if ctx.attr.compression_level:
121121
args.add("--compression_level", ctx.attr.compression_level)
122-
122+
if ctx.attr.allow_prefix_duplication:
123+
args.add("--allow_prefix_duplication")
123124
# Now we begin processing the files.
124125
path_mapper = None
125126
if ctx.attr.remap_paths:
@@ -279,6 +280,11 @@ pkg_tar_impl = rule(
279280
),
280281
"create_parents": attr.bool(default = True),
281282
"allow_duplicates_from_deps": attr.bool(default = False),
283+
"allow_prefix_duplication": attr.bool(
284+
default = False,
285+
doc = """If true, we allow prefix duplication in the output tar. By default prefix duplication is not allowed.""" +
286+
"""For example if you want to create a tar with package_dir = "a/b" and a srcs = ["a/b/c.txt"],"""
287+
),
282288
"compression_level": attr.int(
283289
doc = """Specify the numeric compression level in gzip mode; may be 0-9 or -1 (default to 6).""",
284290
default = -1,

0 commit comments

Comments
 (0)