summaryrefslogtreecommitdiffstats
path: root/SCons/Tool
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2021-01-18 22:17:13 (GMT)
committerGitHub <noreply@github.com>2021-01-18 22:17:13 (GMT)
commitb3d9b508843a58aa5127d31dadb0f066561c2a2d (patch)
treeef1c9bf5b7da84e927cb3788a46d7ad101a7fcc1 /SCons/Tool
parent96479d5daac38b29d42b764f64301efca133c791 (diff)
parentfda865786b2d82ee906240ec11c30c36624698c9 (diff)
downloadSCons-b3d9b508843a58aa5127d31dadb0f066561c2a2d.zip
SCons-b3d9b508843a58aa5127d31dadb0f066561c2a2d.tar.gz
SCons-b3d9b508843a58aa5127d31dadb0f066561c2a2d.tar.bz2
Merge pull request #3862 from djh82/feature/zipbuilder_override_timestamp
Allow Zip tool to override timestamp on included files.
Diffstat (limited to 'SCons/Tool')
-rw-r--r--SCons/Tool/zip.py48
-rw-r--r--SCons/Tool/zip.xml16
2 files changed, 52 insertions, 12 deletions
diff --git a/SCons/Tool/zip.py b/SCons/Tool/zip.py
index cbf2c16..f3d38fe 100644
--- a/SCons/Tool/zip.py
+++ b/SCons/Tool/zip.py
@@ -8,8 +8,9 @@ selection method.
"""
+# MIT License
#
-# __COPYRIGHT__
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -29,39 +30,62 @@ selection method.
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import os.path
+import os
import SCons.Builder
import SCons.Defaults
import SCons.Node.FS
import SCons.Util
+import time
import zipfile
+
zip_compression = zipfile.ZIP_DEFLATED
-def zip(target, source, env):
- compression = env.get('ZIPCOMPRESSION', 0)
- zf = zipfile.ZipFile(str(target[0]), 'w', compression)
+def _create_zipinfo_for_file(fname, arcname, date_time, compression):
+ st = os.stat(fname)
+ if not date_time:
+ mtime = time.localtime(st.st_mtime)
+ date_time = mtime[0:6]
+ zinfo = zipfile.ZipInfo(filename=arcname, date_time=date_time)
+ zinfo.external_attr = (st.st_mode & 0xFFFF) << 16 # Unix attributes
+ zinfo.compress_type = compression
+ zinfo.file_size = st.st_size
+ return zinfo
+
+
+def zip_builder(target, source, env):
+ compression = env.get('ZIPCOMPRESSION', zipfile.ZIP_STORED)
+ zip_root = str(env.get('ZIPROOT', ''))
+ date_time = env.get('ZIP_OVERRIDE_TIMESTAMP')
+
+ files = []
for s in source:
if s.isdir():
for dirpath, dirnames, filenames in os.walk(str(s)):
for fname in filenames:
path = os.path.join(dirpath, fname)
if os.path.isfile(path):
- zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))))
+ files.append(path)
else:
- zf.write(str(s), os.path.relpath(str(s), str(env.get('ZIPROOT', ''))))
- zf.close()
+ files.append(str(s))
+
+ with zipfile.ZipFile(str(target[0]), 'w', compression) as zf:
+ for fname in files:
+ arcname = os.path.relpath(fname, zip_root)
+ # TODO: Switch to ZipInfo.from_file when 3.6 becomes the base python version
+ zinfo = _create_zipinfo_for_file(fname, arcname, date_time, compression)
+ with open(fname, "rb") as f:
+ zf.writestr(zinfo, f.read())
+
# Fix PR #3569 - If you don't specify ZIPCOM and ZIPCOMSTR when creating
# env, then it will ignore ZIPCOMSTR set afterwards.
-zipAction = SCons.Action.Action(zip, "$ZIPCOMSTR", varlist=['ZIPCOMPRESSION'])
+zipAction = SCons.Action.Action(zip_builder, "$ZIPCOMSTR",
+ varlist=['ZIPCOMPRESSION', 'ZIPROOT', 'ZIP_OVERRIDE_TIMESTAMP'])
ZipBuilder = SCons.Builder.Builder(action=SCons.Action.Action('$ZIPCOM', '$ZIPCOMSTR'),
source_factory=SCons.Node.FS.Entry,
diff --git a/SCons/Tool/zip.xml b/SCons/Tool/zip.xml
index 8cf03f4..f9f01d9 100644
--- a/SCons/Tool/zip.xml
+++ b/SCons/Tool/zip.xml
@@ -164,4 +164,20 @@ containing a file with the name
</para>
</summary>
</cvar>
+
+<cvar name="ZIP_OVERRIDE_TIMESTAMP">
+<summary>
+<para>
+An optional timestamp which overrides the last modification time of
+the file when stored inside the Zip archive. This is a tuple of six values:
+
+Year (>= 1980)
+Month (one-based)
+Day of month (one-based)
+Hours (zero-based)
+Minutes (zero-based)
+Seconds (zero-based)
+</para>
+</summary>
+</cvar>
</sconsdoc>