From 816384444d178e7c4961f369a1e7d2dde871ea5c Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Fri, 22 Aug 2014 12:21:50 +0100 Subject: [PATCH] Archiver script improvements. Relating to #235. * Rolled back to using deflate for zip files, as some Windows versions don't support LZMA, which could confuse users into thinking the archive is broken. * Added support for using 7-zip if it is installed. * Added archive filename versioning using `git describe --tags --long` if git.exe is found in the PATH or in a GitHub for Windows install. --- src/archive.py | 77 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/src/archive.py b/src/archive.py index ca4c7a5f..b77f2711 100644 --- a/src/archive.py +++ b/src/archive.py @@ -30,21 +30,65 @@ import sys import os import shutil import zipfile +import subprocess temp_path = os.path.join('..', 'build', 'archive.tmp') archive_name = 'LOOT Archive.zip' -# Set archive name if alternative is given. -if (len(sys.argv) > 1): - archive_name = sys.argv[1] +# Some initial setup. +# +# There are two compression methods available: +# +# * Zip (Deflate) +# * 7-zip (LZMA) +# +# Python 3.3+ can also do BZIP2 and LZMA zip archives, but they don't have good +# Windows OS support, so people think they should be able to open them without +# an archiving utility, find they can't, and think the archive is broken. So +# they won't be used. +# +# Look for 7-zip in its default install location, and use it if it is found. +# Fall back to zip if not. +# +# Archives are named using the output of `git describe --tags --long`, if Git +# is found in the current PATH. Otherwise, they will simply be named +# 'LOOT Archive'. -# Delete the temporary folder if it already exists. +# Python 3.3+ has shutil.which, but 2.7 doesn't. +if 'which' in dir(shutil): + git = shutil.which('git.exe') +else: + git = None + path = os.getenv('PATH') + for p in path.split(os.path.pathsep): + p = os.path.join(p, 'git.exe') + if os.path.exists(p) and os.access(p, os.X_OK): + git = p + +if not git: + # Git wasn't found in PATH, do a search (in GitHub install location). + github = os.path.join( os.getenv('LOCALAPPDATA'), 'GitHub' ) + for folder, subdirs, files in os.walk(github): + for subdir in subdirs: + # Check for a \\cmd\git.exe + if os.path.exists( os.path.join( folder, subdir, 'cmd', 'git.exe') ): + git = os.path.join( folder, subdir, 'cmd', 'git.exe') + + +if git: + args = [git, 'describe', '--tags', '--long'] + output = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() + if len(output[1]) == 0: + archive_name = 'LOOT ' + output[0].decode('ascii')[:-1] + else: + archive_name = 'LOOT Archive' +else: + archive_name = 'LOOT Archive' + +# Delete the temporary folder if it already exists, then create it. if os.path.exists(temp_path): shutil.rmtree(temp_path) - -# First make sure that the temporary folder for the archive exists. -if not os.path.exists(temp_path): - os.makedirs(temp_path) +os.makedirs(temp_path) # Now copy everything into the temporary folder. shutil.copy( os.path.join('..', 'build', 'Release', 'LOOT.exe'), temp_path ) @@ -73,11 +117,18 @@ shutil.copy( os.path.join('..', 'docs', 'LOOT Readme.html'), os.path.join(temp_p # Now compress the temporary folder. (Creating a zip because I can't get pylzma to work...) os.chdir(temp_path) -zip = zipfile.ZipFile( os.path.join('..', archive_name), 'w', zipfile.ZIP_LZMA ) -for root, dirs, files in os.walk('.'): - for file in files: - zip.write(os.path.join(root, file)) -zip.close() + +sevenzip_path = os.path.join('C:\\', 'Program Files', '7-Zip', '7z.exe') +if os.path.exists(sevenzip_path): + out_path = os.path.join('..', archive_name + '.7z') + args = [sevenzip_path, 'a', '-r', out_path] + subprocess.call(args) +else: + zip = zipfile.ZipFile( os.path.join('..', archive_name + '.zip'), 'w', zipfile.ZIP_DEFLATED ) + for root, dirs, files in os.walk('.'): + for file in files: + zip.write(os.path.join(root, file)) + zip.close() os.chdir('..') # And finally, delete the temporary folder.