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