From 5bf14de1fd9db9693f2edd6d2a4f39467282d10d Mon Sep 17 00:00:00 2001 From: Dennis Ludewig <48102160+dennis3620@users.noreply.github.com> Date: Fri, 29 Jan 2021 10:23:15 +0100 Subject: [PATCH] Extend pkg_tar rule with stamp_mtime attribute for use with workspace status variables --- pkg/.bazelrc | 2 ++ pkg/archive.py | 19 ++++++++++++++++++- pkg/build_tar.py | 11 ++++++++--- pkg/docs/reference.md | 16 ++++++++++++++++ pkg/pkg.bzl | 19 ++++++++++++++++++- pkg/tests/BUILD | 10 ++++++++++ pkg/tests/archive_test.py | 5 +++++ pkg/tests/pkg_tar_test.py | 8 ++++++++ pkg/tests/testdata/test_volatile-status.txt | 1 + pkg/tests/workspace_status.sh | 5 +++++ 10 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 pkg/.bazelrc create mode 100644 pkg/tests/testdata/test_volatile-status.txt create mode 100755 pkg/tests/workspace_status.sh diff --git a/pkg/.bazelrc b/pkg/.bazelrc new file mode 100644 index 00000000..ec5049ea --- /dev/null +++ b/pkg/.bazelrc @@ -0,0 +1,2 @@ +# Define workspace status command for stamp_mtime attribute in pkg_tar rule +test --workspace_status_command=./tests/workspace_status.sh \ No newline at end of file diff --git a/pkg/archive.py b/pkg/archive.py index c379dc15..32b003b7 100644 --- a/pkg/archive.py +++ b/pkg/archive.py @@ -123,7 +123,8 @@ def __init__(self, compression='', root_directory='.', default_mtime=None, - preserve_tar_mtimes=True): + preserve_tar_mtimes=True, + workspace_status_file=None): """TarFileWriter wraps tarfile.open(). Args: @@ -155,6 +156,22 @@ def __init__(self, self.default_mtime = 0 elif default_mtime == 'portable': self.default_mtime = PORTABLE_MTIME + elif workspace_status_file is not None: + default_mtime_strip = default_mtime.strip() + if not default_mtime_strip.startswith("{") or not default_mtime_strip.endswith("}"): + raise self.Error('Workspace status file provided, but mtime does not contain a valid key.') + default_mtime_key = default_mtime_strip[1:-1] + key_found = False + with open(workspace_status_file, 'r') as f: + for line in f: + key, value = line.strip().split(' ', 1) + if key == default_mtime_key: + key_found = True + self.default_mtime = int(value) + break + if not key_found: + raise self.Error('Key "{}" was not found in workspace status file. '.format(default_mtime_key) + + 'Please check if the volatile workspace status file contains this key.') else: self.default_mtime = int(default_mtime) diff --git a/pkg/build_tar.py b/pkg/build_tar.py index f861ea3d..fc922e64 100644 --- a/pkg/build_tar.py +++ b/pkg/build_tar.py @@ -30,19 +30,21 @@ class DebError(Exception): pass def __init__(self, output, directory, compression, root_directory, - default_mtime): + default_mtime, workspace_status_file=None): self.directory = directory self.output = output self.compression = compression self.root_directory = root_directory self.default_mtime = default_mtime + self.workspace_status_file = workspace_status_file def __enter__(self): self.tarfile = archive.TarFileWriter( self.output, self.compression, self.root_directory, - default_mtime=self.default_mtime) + default_mtime=self.default_mtime, + workspace_status_file=self.workspace_status_file) return self def __exit__(self, t, v, traceback): @@ -256,6 +258,9 @@ def main(): 'path/to/file=root.root.') parser.add_argument('--root_directory', default='./', help='Default root directory is named "."') + parser.add_argument('--workspace_status_file', + help='Workspace status file with volatile keys/values ' + 'for use with "mtime" containing the corresponding key to use.') options = parser.parse_args() # Parse modes arguments @@ -298,7 +303,7 @@ def main(): # Add objects to the tar file with TarFile( options.output, helpers.GetFlagValue(options.directory), - options.compression, options.root_directory, options.mtime) as output: + options.compression, options.root_directory, options.mtime, options.workspace_status_file) as output: def file_attributes(filename): if filename.startswith('/'): diff --git a/pkg/docs/reference.md b/pkg/docs/reference.md index f6d43568..9b650c93 100644 --- a/pkg/docs/reference.md +++ b/pkg/docs/reference.md @@ -244,6 +244,22 @@ Creates a tar file from a list of inputs.

+ + stamp_mtime + + String, optional +

+ Stamp variable from workspace status file. + The key's name must not start with STABLE_ + because only "volatile" keys are read. +

+

+ + stamp_mtime = "{STAMP_MTIME}", + +

+ + diff --git a/pkg/pkg.bzl b/pkg/pkg.bzl index 3237b5c4..d9b20348 100644 --- a/pkg/pkg.bzl +++ b/pkg/pkg.bzl @@ -90,12 +90,28 @@ def _pkg_tar_impl(ctx): "--owner=" + ctx.attr.owner, "--owner_name=" + ctx.attr.ownername, ] + stamp_inputs = [] if ctx.attr.mtime != _DEFAULT_MTIME: if ctx.attr.portable_mtime: fail("You may not set both mtime and portable_mtime") + if ctx.attr.stamp_mtime: + fail("You may not set both mtime and stamp_mtime") args.append("--mtime=%d" % ctx.attr.mtime) if ctx.attr.portable_mtime: + if ctx.attr.stamp_mtime: + fail("You may not set both portable_mtime and stamp_mtime") args.append("--mtime=portable") + if ctx.attr.stamp_mtime: + # Only ctx.version_file for file volatile-status.txt is needed + # because change of key/value should not invalid existing build + stamp_inputs += [ctx.version_file] + stamp_mtime_strip = ctx.attr.stamp_mtime.strip() + if not stamp_mtime_strip.startswith("{") or not stamp_mtime_strip.endswith("}"): + fail("You set stamp_mtime, but this doesn't contain a valid key variable") + # Add mtime with stamped mtime variable + args.append("--mtime=%s" % stamp_mtime_strip) + # Add volatile-status.txt file as argument + args.append("--workspace_status_file=%s" % ctx.version_file.path) # Add runfiles if requested file_inputs = [] @@ -162,7 +178,7 @@ def _pkg_tar_impl(ctx): ctx.actions.run( mnemonic = "PackageTar", progress_message = "Writing: %s" % output_file.path, - inputs = file_inputs + ctx.files.deps + files, + inputs = file_inputs + ctx.files.deps + files + stamp_inputs, executable = ctx.executable.build_tar, arguments = ["@" + arg_file.path], outputs = [output_file], @@ -322,6 +338,7 @@ pkg_tar_impl = rule( "modes": attr.string_dict(), "mtime": attr.int(default = _DEFAULT_MTIME), "portable_mtime": attr.bool(default = True), + "stamp_mtime": attr.string(), "owner": attr.string(default = "0.0"), "ownername": attr.string(default = "."), "owners": attr.string_dict(), diff --git a/pkg/tests/BUILD b/pkg/tests/BUILD index 69809802..343972b9 100644 --- a/pkg/tests/BUILD +++ b/pkg/tests/BUILD @@ -400,6 +400,15 @@ pkg_tar( portable_mtime = False, ) +pkg_tar( + name = "test-tar-stamp_mtime", + srcs = [ + ":etc/nsswitch.conf", + ], + portable_mtime = False, + stamp_mtime = "{STAMP_MTIME}", +) + py_test( name = "pkg_tar_test", size = "medium", @@ -411,6 +420,7 @@ py_test( ":test-tar-empty_files.tar", ":test-tar-files_dict.tar", ":test-tar-mtime.tar", + ":test-tar-stamp_mtime.tar", ":test-tar-strip_prefix-dot.tar", ":test-tar-strip_prefix-empty.tar", ":test-tar-strip_prefix-etc.tar", diff --git a/pkg/tests/archive_test.py b/pkg/tests/archive_test.py index af51b70a..6d8e4038 100644 --- a/pkg/tests/archive_test.py +++ b/pkg/tests/archive_test.py @@ -271,6 +271,11 @@ def testPreserveTarMtimesFalse(self): for output_file in f.tar: self.assertEqual(output_file.mtime, 0) + def testStampMtime(self): + with archive.TarFileWriter(self.tempfile, default_mtime="{STAMP_MTIME}", + workspace_status_file="./tests/testdata/test_volatile-status.txt") as f: + self.assertEqual(f.default_mtime, 946684741) + def testAddingDirectoriesForFile(self): with archive.TarFileWriter(self.tempfile) as f: f.add_file("d/f") diff --git a/pkg/tests/pkg_tar_test.py b/pkg/tests/pkg_tar_test.py index 902d11a1..5caeb44b 100644 --- a/pkg/tests/pkg_tar_test.py +++ b/pkg/tests/pkg_tar_test.py @@ -142,6 +142,14 @@ def test_mtime(self): ] self.assertTarFileContent('test-tar-mtime.tar', content) + def test_stamp_mtime(self): + # Note strange mtime. It is specified in the testdata/workspace_status.sh file. + content = [ + {'name': '.', 'mtime': 946684741}, + {'name': './nsswitch.conf', 'mtime': 946684741}, + ] + self.assertTarFileContent('test-tar-stamp_mtime.tar', content) + def test_basic(self): # Check the set of 'test-tar-basic-*' smoke test. content = [ diff --git a/pkg/tests/testdata/test_volatile-status.txt b/pkg/tests/testdata/test_volatile-status.txt new file mode 100644 index 00000000..b40fe741 --- /dev/null +++ b/pkg/tests/testdata/test_volatile-status.txt @@ -0,0 +1 @@ +STAMP_MTIME 946684741 \ No newline at end of file diff --git a/pkg/tests/workspace_status.sh b/pkg/tests/workspace_status.sh new file mode 100755 index 00000000..16ba330d --- /dev/null +++ b/pkg/tests/workspace_status.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +stamp_mtime=946684741 # 1999-12-31, 23:58:01 +cat << EOF +STAMP_MTIME ${stamp_mtime} +EOF \ No newline at end of file