diff options
author | William Deegan <bill@baddogconsulting.com> | 2021-01-18 22:17:13 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-18 22:17:13 (GMT) |
commit | b3d9b508843a58aa5127d31dadb0f066561c2a2d (patch) | |
tree | ef1c9bf5b7da84e927cb3788a46d7ad101a7fcc1 /SCons/Tool | |
parent | 96479d5daac38b29d42b764f64301efca133c791 (diff) | |
parent | fda865786b2d82ee906240ec11c30c36624698c9 (diff) | |
download | SCons-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.py | 48 | ||||
-rw-r--r-- | SCons/Tool/zip.xml | 16 |
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> |