Chromium Code Reviews| Index: remoting/host/installer/build-installer-archive.py |
| =================================================================== |
| --- remoting/host/installer/build-installer-archive.py (revision 133640) |
| +++ remoting/host/installer/build-installer-archive.py (working copy) |
| @@ -17,6 +17,7 @@ |
| import os |
| import shutil |
| +import subprocess |
| import sys |
| import zipfile |
| @@ -37,6 +38,22 @@ |
| os.makedirs(dir, 0775) |
| +def buildDefDictionary(definitions): |
| + """Builds the definition dictionary from the VARIABLE=value array. |
| + |
| + Args: |
| + defs: Array of variable definitions: 'VARIABLE=value'. |
| + |
| + Returns: |
| + Dictionary with the definitions. |
| + """ |
| + defs = {} |
| + for d in definitions: |
| + (key, val) = d.split('=') |
| + defs[key] = val |
| + return defs |
| + |
| + |
| def createZip(zip_path, directory): |
| """Creates a zipfile at zip_path for the given directory. |
| @@ -54,7 +71,7 @@ |
| zip.close() |
| -def copyFileIntoArchive(src_file, out_dir, files_root, dst_file): |
| +def copyFileIntoArchive(src_file, out_dir, files_root, dst_file, defs): |
| """Copies the src_file into the out_dir, preserving the directory structure. |
| Args: |
| @@ -63,6 +80,7 @@ |
| files_root: Path prefix which is stripped of dst_file before appending |
| it to the out_dir. |
| dst_file: Relative path (and filename) where src_file should be copied. |
| + defs: Dictionary of variable definitions. |
| """ |
| root_len = len(files_root) |
| local_file_path = dst_file[root_len:] |
| @@ -70,9 +88,39 @@ |
| dst_dir = os.path.dirname(full_dst_file) |
| if not os.path.exists(dst_dir): |
| os.makedirs(dst_dir, 0775) |
| - shutil.copy2(src_file, full_dst_file) |
| + (base, ext) = os.path.splitext(src_file) |
| + if ext == '.app': |
| + shutil.copytree(src_file, full_dst_file) |
| + else: |
| + copyFileWithDefs(src_file, full_dst_file, defs) |
|
alexeypa (please no reviews)
2012/04/24 16:06:19
This means that copyFileWithDefs could be used for
garykac
2012/04/24 19:48:21
Done.
|
| + |
| +def copyFileWithDefs(src_file, dst_file, defs): |
| + """Copies from src_file to dst_file, performing variable substitution. |
| + |
| + Any @@variables@@ in the source are replaced with |
| + file with the out_dir, preserving the directory structure. |
| + |
| + Args: |
| + src_file: Full or relative path to source file to copy. |
| + out_dir: Target directory where files are copied. |
|
alexeypa (please no reviews)
2012/04/24 16:06:19
nit: This function does not have |out_dir| and |fi
garykac
2012/04/24 19:48:21
Done.
|
| + files_root: Path prefix which is stripped of dst_file before appending |
| + it to the out_dir. |
| + dst_file: Relative path (and filename) where src_file should be copied. |
| + defs: Dictionary of variable definitions. |
| + """ |
| + data = open(src_file, 'r').read() |
| + for key, val in defs.iteritems(): |
| + try: |
| + data = data.replace('@@' + key + '@@', val) |
| + except TypeError: |
| + print repr(key), repr(val) |
| + open(dst_file, 'w').write(data) |
| + shutil.copystat(src_file, dst_file) |
| + #shutil.copy2(src_file, dst_file) |
|
alexeypa (please no reviews)
2012/04/24 16:06:19
nit: Remove the commented out code.
garykac
2012/04/24 19:48:21
Done.
|
| + |
| + |
| def copyZipIntoArchive(out_dir, files_root, zip_file): |
| """Expands the zip_file into the out_dir, preserving the directory structure. |
| @@ -82,32 +130,28 @@ |
| it to the out_dir. |
| zip_file: Relative path (and filename) to the zip file. |
| """ |
| + base_zip_name = os.path.basename(zip_file) |
| + |
| + # We don't use the 'zipfile' module here because it doesn't restore all the |
| + # file permissions correctly. We use the 'unzip' command manually. |
|
alexeypa (please no reviews)
2012/04/24 16:06:19
This does not seem to be cross-platform. I believe
garykac
2012/04/24 19:48:21
Per our discussion, I'll followup this cl with one
|
| + old_dir = os.getcwd(); |
| + os.chdir(os.path.dirname(zip_file)) |
| + subprocess.call(['unzip', '-qq', '-o', base_zip_name]) |
| + os.chdir(old_dir) |
| + |
| # Unzip into correct dir in out_dir. |
| - zip_archive = zipfile.ZipFile(zip_file, 'r') |
| root_len = len(files_root) |
| relative_zip_path = zip_file[root_len:] |
| out_zip_path = os.path.join(out_dir, relative_zip_path) |
| out_zip_dir = os.path.dirname(out_zip_path) |
| - if not os.path.exists(out_zip_dir): |
| - os.makedirs(out_zip_dir, 0775) |
| - # Ideally, we'd simply do: |
| - # zip_archive.extractall(out_zip_dir) |
| - # but http://bugs.python.org/issue4710 bites us because the some 'bots (like |
| - # mac_rel) are still running Python 2.6. |
| - # See http://stackoverflow.com/questions/639962/unzipping-directory-structure-with-python |
| - # for workarounds. |
| - # TODO(garykac): Remove this once all bots are > 2.6. |
| - for f in zip_archive.namelist(): |
| - if f.endswith('/'): |
| - if not os.path.exists(f): |
| - os.makedirs(os.path.join(out_zip_dir, f)) |
| - else: |
| - zip_archive.extract(f, out_zip_dir) |
| + (src_dir, ignore1) = os.path.splitext(zip_file) |
| + (base_dir_name, ignore2) = os.path.splitext(base_zip_name) |
| + shutil.copytree(src_dir, os.path.join(out_zip_dir, base_dir_name)) |
| def buildHostArchive(temp_dir, zip_path, source_files_root, source_files, |
| - gen_files, gen_files_dst): |
| + gen_files, gen_files_dst, defs): |
| """Builds a zip archive with the files needed to build the installer. |
| Args: |
| @@ -119,6 +163,7 @@ |
| gen_files: Full path to binaries to add to archive. |
| gen_files_dst: Relative path of where to add binary files in archive. |
| This array needs to parallel |binaries_src|. |
| + defs: Dictionary of variable definitions. |
| """ |
| cleanDir(temp_dir) |
| @@ -128,28 +173,33 @@ |
| if ext == '.zip': |
|
alexeypa (please no reviews)
2012/04/24 16:06:19
nit: The logic here can be:
if .zip: copyZipIntoA
garykac
2012/04/24 19:48:21
I like that, but I'll do that in a follow-up cl si
|
| copyZipIntoArchive(temp_dir, source_files_root, file) |
| else: |
| - copyFileIntoArchive(file, temp_dir, source_files_root, file) |
| + copyFileIntoArchive(file, temp_dir, source_files_root, file, defs) |
| for bs, bd in zip(gen_files, gen_files_dst): |
| - copyFileIntoArchive(bs, temp_dir, '', bd) |
| + copyFileIntoArchive(bs, temp_dir, '', bd, {}) |
| createZip(zip_path, temp_dir) |
| +def error(msg): |
| + sys.stderr.write('ERROR: %s' % msg) |
| + sys.exit(1) |
| + |
| def usage(): |
| """Display basic usage information.""" |
| print ('Usage: %s\n' |
| ' <temp-dir> <zip-path> <files-root-dir>\n' |
| ' --source-files <list of source files...>\n' |
| ' --generated-files <list of generated target files...>\n' |
| - ' --generated-files-dst <dst for each generated file...>' |
| + ' --generated-files-dst <dst for each generated file...>\n' |
| + ' --defs <list of VARIABLE=value definitions...>' |
| ) % sys.argv[0] |
| def main(): |
| if len(sys.argv) < 3: |
| usage() |
| - return 1 |
| + error('Too few arguments') |
| temp_dir = sys.argv[1] |
| zip_path = sys.argv[2] |
| @@ -159,6 +209,7 @@ |
| source_files = [] |
| generated_files = [] |
| generated_files_dst = [] |
| + definitions = [] |
| for arg in sys.argv[4:]: |
| if arg == '--source-files': |
| arg_mode = 'files' |
| @@ -166,6 +217,8 @@ |
| arg_mode = 'gen-src' |
| elif arg == '--generated-files-dst': |
| arg_mode = 'gen-dst' |
| + elif arg == '--defs': |
| + arg_mode = 'defs' |
| elif arg_mode == 'files': |
| source_files.append(arg) |
| @@ -173,29 +226,29 @@ |
| generated_files.append(arg) |
| elif arg_mode == 'gen-dst': |
| generated_files_dst.append(arg) |
| + elif arg_mode == 'defs': |
| + definitions.append(arg) |
| else: |
| - print "ERROR: Expected --source-files" |
| usage() |
| - return 1 |
| + error('Expected --source-files') |
| # Make sure at least one file was specified. |
| if len(source_files) == 0 and len(generated_files) == 0: |
| - print "ERROR: At least one input file must be specified." |
| - return 1 |
| + error('At least one input file must be specified.') |
| # Ensure that source_files_root ends with a directory separator. |
| if source_files_root[-1:] != os.sep: |
| source_files_root += os.sep |
| # Verify that the 2 generated_files arrays have the same number of elements. |
| - if len(generated_files) < len(generated_files_dst): |
| - print "ERROR: len(--generated-files) != len(--generated-files-dst)" |
| - return 1 |
| - while len(generated_files) > len(generated_files_dst): |
| - generated_files_dst.append('') |
| + if len(generated_files) != len(generated_files_dst): |
| + error('len(--generated-files) != len(--generated-files-dst)') |
| + defs = buildDefDictionary(definitions) |
| + |
| result = buildHostArchive(temp_dir, zip_path, source_files_root, |
| - source_files, generated_files, generated_files_dst) |
| + source_files, generated_files, generated_files_dst, |
| + defs) |
| return 0 |