diff options
author | Erik Stringwell <stringwell@gmail.com> | 2024-03-21 15:04:19 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-21 10:04:19 -0400 |
commit | a0eb69a1f33109cea208fe64dcef390c74e6be53 (patch) | |
tree | 934c8b4f6ba3a37801f458f6182c8c3e71695ff7 | |
parent | 20100ce9827e886f9107cbd2758c18e90af07e69 (diff) | |
download | bazelbuild-rules_pkg-a0eb69a1f33109cea208fe64dcef390c74e6be53.tar.gz |
Add support for no parent directory inference (#832) (#834)
Add feature as described in #832.
RELNOTES: Automatic creation of parent directory specifications for
paths with depth can be prevented in `pkg_tar` archives by setting `create_parents=False`.
-rwxr-xr-x | docs/latest.md | 3 | ||||
-rw-r--r-- | pkg/private/tar/build_tar.py | 11 | ||||
-rw-r--r-- | pkg/private/tar/tar.bzl | 4 | ||||
-rw-r--r-- | pkg/private/tar/tar_writer.py | 22 | ||||
-rw-r--r-- | tests/tar/tar_writer_test.py | 19 |
5 files changed, 44 insertions, 15 deletions
diff --git a/docs/latest.md b/docs/latest.md index eea6982..c0c9822 100755 --- a/docs/latest.md +++ b/docs/latest.md @@ -287,7 +287,7 @@ pkg_tar(<a href="#pkg_tar-name">name</a>, <a href="#pkg_tar-allow_duplicates_wit <a href="#pkg_tar-empty_dirs">empty_dirs</a>, <a href="#pkg_tar-empty_files">empty_files</a>, <a href="#pkg_tar-extension">extension</a>, <a href="#pkg_tar-files">files</a>, <a href="#pkg_tar-include_runfiles">include_runfiles</a>, <a href="#pkg_tar-mode">mode</a>, <a href="#pkg_tar-modes">modes</a>, <a href="#pkg_tar-mtime">mtime</a>, <a href="#pkg_tar-out">out</a>, <a href="#pkg_tar-owner">owner</a>, <a href="#pkg_tar-ownername">ownername</a>, <a href="#pkg_tar-ownernames">ownernames</a>, <a href="#pkg_tar-owners">owners</a>, <a href="#pkg_tar-package_dir">package_dir</a>, <a href="#pkg_tar-package_dir_file">package_dir_file</a>, <a href="#pkg_tar-package_file_name">package_file_name</a>, <a href="#pkg_tar-package_variables">package_variables</a>, <a href="#pkg_tar-portable_mtime">portable_mtime</a>, <a href="#pkg_tar-private_stamp_detect">private_stamp_detect</a>, <a href="#pkg_tar-remap_paths">remap_paths</a>, <a href="#pkg_tar-srcs">srcs</a>, <a href="#pkg_tar-stamp">stamp</a>, - <a href="#pkg_tar-strip_prefix">strip_prefix</a>, <a href="#pkg_tar-symlinks">symlinks</a>) + <a href="#pkg_tar-strip_prefix">strip_prefix</a>, <a href="#pkg_tar-symlinks">symlinks</a>, <a href="#pkg_tar-create_parents">symlinks</a>) </pre> @@ -326,6 +326,7 @@ pkg_tar(<a href="#pkg_tar-name">name</a>, <a href="#pkg_tar-allow_duplicates_wit | <a id="pkg_tar-stamp"></a>stamp | Enable file time stamping. Possible values: <li>stamp = 1: Use the time of the build as the modification time of each file in the archive. <li>stamp = 0: Use an "epoch" time for the modification time of each file. This gives good build result caching. <li>stamp = -1: Control the chosen modification time using the --[no]stamp flag. <div class="since"><i>Since 0.5.0</i></div> | Integer | optional | 0 | | <a id="pkg_tar-strip_prefix"></a>strip_prefix | (note: Use strip_prefix = "." to strip path to the package but preserve relative paths of sub directories beneath the package.) | String | optional | "" | | <a id="pkg_tar-symlinks"></a>symlinks | - | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} | +| <a id="pkg_tar-create_parents"></a>create_parents | Implicitly create parent directories with default permissions for file paths where parent directories are not specified. | Boolean | optional | True | diff --git a/pkg/private/tar/build_tar.py b/pkg/private/tar/build_tar.py index f4b9f0d..81ad03f 100644 --- a/pkg/private/tar/build_tar.py +++ b/pkg/private/tar/build_tar.py @@ -42,7 +42,7 @@ class TarFile(object): class DebError(Exception): pass - def __init__(self, output, directory, compression, compressor, default_mtime): + def __init__(self, output, directory, compression, compressor, create_parents, default_mtime): # Directory prefix on all output paths d = directory.strip('/') self.directory = (d + '/') if d else None @@ -50,12 +50,14 @@ class TarFile(object): self.compression = compression self.compressor = compressor self.default_mtime = default_mtime + self.create_parents = create_parents def __enter__(self): self.tarfile = tar_writer.TarFileWriter( self.output, self.compression, self.compressor, + self.create_parents, default_mtime=self.default_mtime) return self @@ -383,6 +385,10 @@ def main(): 'path/to/file=root.root.') parser.add_argument('--stamp_from', default='', help='File to find BUILD_STAMP in') + parser.add_argument('--create_parents', + action='store_true', + help='Automatically creates parent directories implied by a' + ' prefix if they do not exist') options = parser.parse_args() # Parse modes arguments @@ -432,7 +438,8 @@ def main(): directory = helpers.GetFlagValue(options.directory), compression = options.compression, compressor = options.compressor, - default_mtime=default_mtime) as output: + default_mtime=default_mtime, + create_parents=options.create_parents) as output: def file_attributes(filename): if filename.startswith('/'): diff --git a/pkg/private/tar/tar.bzl b/pkg/private/tar/tar.bzl index 963cb5a..8bea9fb 100644 --- a/pkg/private/tar/tar.bzl +++ b/pkg/private/tar/tar.bzl @@ -173,6 +173,9 @@ def _pkg_tar_impl(ctx): args.set_param_file_format("flag_per_line") args.use_param_file("@%s", use_always = False) + if ctx.attr.create_parents: + args.add("--create_parents") + inputs = depset( direct = ctx.files.deps + files, transitive = mapping_context.file_deps, @@ -264,6 +267,7 @@ pkg_tar_impl = rule( "compressor_args": attr.string( doc = """Arg list for `compressor`.""", ), + "create_parents": attr.bool(default = True), # Common attributes "out": attr.output(mandatory = True), diff --git a/pkg/private/tar/tar_writer.py b/pkg/private/tar/tar_writer.py index 325db76..957ce45 100644 --- a/pkg/private/tar/tar_writer.py +++ b/pkg/private/tar/tar_writer.py @@ -46,6 +46,7 @@ class TarFileWriter(object): name, compression='', compressor='', + create_parents=False, default_mtime=None, preserve_tar_mtimes=True): """TarFileWriter wraps tarfile.open(). @@ -106,6 +107,7 @@ class TarFileWriter(object): # we can adjust that here based on the setting of root_dirctory. self.directories.add('/') self.directories.add('./') + self.create_parents = create_parents def __enter__(self): return self @@ -219,7 +221,8 @@ class TarFileWriter(object): mtime = self.default_mtime # Make directories up the file - self.add_parents(name, mtime=mtime, mode=0o755, uid=uid, gid=gid, uname=uname, gname=gname) + if self.create_parents: + self.add_parents(name, mtime=mtime, mode=0o755, uid=uid, gid=gid, uname=uname, gname=gname) tarinfo = tarfile.TarInfo(name) tarinfo.mtime = mtime @@ -291,14 +294,15 @@ class TarFileWriter(object): if prefix: in_name = os.path.normpath(prefix + in_name).replace(os.path.sep, '/') tarinfo.name = in_name - self.add_parents( - path=tarinfo.name, - mtime=tarinfo.mtime, - mode=0o755, - uid=tarinfo.uid, - gid=tarinfo.gid, - uname=tarinfo.uname, - gname=tarinfo.gname) + if self.create_parents: + self.add_parents( + path=tarinfo.name, + mtime=tarinfo.mtime, + mode=0o755, + uid=tarinfo.uid, + gid=tarinfo.gid, + uname=tarinfo.uname, + gname=tarinfo.gname) if prefix is not None: # Relocate internal hardlinks as well to avoid breaking them. diff --git a/tests/tar/tar_writer_test.py b/tests/tar/tar_writer_test.py index ad31b0c..8503d31 100644 --- a/tests/tar/tar_writer_test.py +++ b/tests/tar/tar_writer_test.py @@ -138,7 +138,7 @@ class TarFileWriterTest(unittest.TestCase): {"name": "foo/a", "data": b"a"}, {"name": "foo/ab", "data": b"ab"}, ] - with tar_writer.TarFileWriter(self.tempfile) as f: + with tar_writer.TarFileWriter(self.tempfile, create_parents=True) as f: datafile = self.data_files.Rlocation( "rules_pkg/tests/testdata/tar_test.tar") f.add_tar(datafile, name_filter=lambda n: n != "./b", prefix="foo") @@ -176,7 +176,7 @@ class TarFileWriterTest(unittest.TestCase): self.assertEqual(output_file.mtime, 0) def testAddingDirectoriesForFile(self): - with tar_writer.TarFileWriter(self.tempfile) as f: + with tar_writer.TarFileWriter(self.tempfile, create_parents=True) as f: f.add_file("d/f") content = [ {"name": "d", "mode": 0o755}, @@ -185,7 +185,7 @@ class TarFileWriterTest(unittest.TestCase): self.assertTarFileContent(self.tempfile, content) def testAddingDirectoriesForFileManually(self): - with tar_writer.TarFileWriter(self.tempfile) as f: + with tar_writer.TarFileWriter(self.tempfile, create_parents=True) as f: f.add_file("d", tarfile.DIRTYPE) f.add_file("d/f") @@ -210,6 +210,19 @@ class TarFileWriterTest(unittest.TestCase): ] self.assertTarFileContent(self.tempfile, content) + def testAddingOnlySpecifiedFiles(self): + with tar_writer.TarFileWriter(self.tempfile) as f: + f.add_file("a", tarfile.DIRTYPE) + f.add_file("a/b", tarfile.DIRTYPE) + f.add_file("a/b/", tarfile.DIRTYPE) + f.add_file("a/b/c/f") + content = [ + {"name": "a", "mode": 0o755}, + {"name": "a/b", "mode": 0o755}, + {"name": "a/b/c/f"}, + ] + self.assertTarFileContent(self.tempfile, content) + def testPackageDirAttribute(self): """Tests package_dir of pkg_tar.""" package_dir = self.data_files.Rlocation( |