OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """Creates a zip archive for the Chrome Remote Desktop Host installer. |
| 7 |
| 8 This script builds a zip file that contains all the files needed to build an |
| 9 installer for Chrome Remote Desktop Host. |
| 10 |
| 11 This zip archive is then used by the signing bots to: |
| 12 (1) Sign the binaries |
| 13 (2) Build the final installer |
| 14 |
| 15 TODO(garykac) We should consider merging this with build-webapp.py. |
| 16 """ |
| 17 |
| 18 import os |
| 19 import shutil |
| 20 import sys |
| 21 import zipfile |
| 22 |
| 23 |
| 24 def cleanDir(dir): |
| 25 """Deletes and recreates the dir to make sure it is clean. |
| 26 |
| 27 Args: |
| 28 dir: The directory to clean. |
| 29 """ |
| 30 try: |
| 31 shutil.rmtree(dir) |
| 32 except OSError: |
| 33 if os.path.exists(dir): |
| 34 raise |
| 35 else: |
| 36 pass |
| 37 os.makedirs(dir, 0775) |
| 38 |
| 39 |
| 40 def createZip(zip_path, directory): |
| 41 """Creates a zipfile at zip_path for the given directory. |
| 42 |
| 43 Args: |
| 44 zip_path: Path to zip file to create. |
| 45 directory: Directory with contents to archive. |
| 46 """ |
| 47 zipfile_base = os.path.splitext(os.path.basename(zip_path))[0] |
| 48 zip = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) |
| 49 for (root, dirs, files) in os.walk(directory): |
| 50 for f in files: |
| 51 full_path = os.path.join(root, f) |
| 52 rel_path = os.path.relpath(full_path, directory) |
| 53 zip.write(full_path, os.path.join(zipfile_base, rel_path)) |
| 54 zip.close() |
| 55 |
| 56 |
| 57 def copyFileIntoArchive(src_file, out_dir, files_root, dst_file): |
| 58 """Copies the src_file into the out_dir, preserving the directory structure. |
| 59 |
| 60 Args: |
| 61 src_file: Full or relative path to source file to copy. |
| 62 out_dir: Target directory where files are copied. |
| 63 files_root: Path prefix which is stripped of dst_file before appending |
| 64 it to the temp_dir. |
| 65 dst_file: Relative path (and filename) where src_file should be copied. |
| 66 """ |
| 67 root_len = len(files_root) |
| 68 local_path = dst_file[root_len:] |
| 69 full_dst_file = os.path.join(out_dir, local_path) |
| 70 dst_dir = os.path.dirname(full_dst_file) |
| 71 if not os.path.exists(dst_dir): |
| 72 os.makedirs(dst_dir, 0775) |
| 73 shutil.copy2(src_file, full_dst_file) |
| 74 |
| 75 |
| 76 def buildHostArchive(temp_dir, zip_path, source_files_root, source_files, |
| 77 gen_files, gen_files_dst): |
| 78 """Builds a zip archive with the files needed to build the installer. |
| 79 |
| 80 Args: |
| 81 temp_dir: Temporary dir used to build up the contents for the archive. |
| 82 zip_path: Full path to the zip file to create. |
| 83 source_files_root: Path prefix to strip off |files| when adding to archive. |
| 84 source_files: The array of files to add to archive. The path structure is |
| 85 preserved (except for the |files_root| prefix). |
| 86 gen_files: Full path to binaries to add to archive. |
| 87 gen_files_dst: Relative path of where to add binary files in archive. |
| 88 This array needs to parallel |binaries_src|. |
| 89 """ |
| 90 cleanDir(temp_dir) |
| 91 |
| 92 for file in source_files: |
| 93 base_file = os.path.basename(file) |
| 94 if base_file == '*': |
| 95 # Copy entire directory tree. |
| 96 for (root, dirs, files) in os.walk(os.path.dirname(file)): |
| 97 for f in files: |
| 98 full_path = os.path.join(root, f) |
| 99 copyFileIntoArchive(full_path, temp_dir, files_root, full_path) |
| 100 else: |
| 101 copyFileIntoArchive(file, temp_dir, source_files_root, file) |
| 102 |
| 103 for bs, bd in zip(gen_files, gen_files_dst): |
| 104 copyFileIntoArchive(bs, temp_dir, '', bd) |
| 105 |
| 106 createZip(zip_path, temp_dir) |
| 107 |
| 108 |
| 109 def usage(): |
| 110 """Display basic usage information.""" |
| 111 print ('Usage: %s\n' |
| 112 ' <temp-dir> <zip-path> <files-root-dir>\n' |
| 113 ' --source-files <list of source files...>\n' |
| 114 ' --generated-files <list of generated target files...>\n' |
| 115 ' --generated-files-dst <dst for each generated file...>' |
| 116 ) % sys.argv[0] |
| 117 |
| 118 |
| 119 def main(): |
| 120 if len(sys.argv) < 3: |
| 121 usage() |
| 122 return 1 |
| 123 |
| 124 temp_dir = sys.argv[1] |
| 125 zip_path = sys.argv[2] |
| 126 source_files_root = sys.argv[3] |
| 127 |
| 128 arg_mode = '' |
| 129 source_files = [] |
| 130 generated_files = [] |
| 131 generated_files_dst = [] |
| 132 for arg in sys.argv[4:]: |
| 133 if arg == '--source-files': |
| 134 arg_mode = 'files' |
| 135 elif arg == '--generated-files': |
| 136 arg_mode = 'gen-src' |
| 137 elif arg == '--generated-files-dst': |
| 138 arg_mode = 'gen-dst' |
| 139 |
| 140 elif arg_mode == 'files': |
| 141 source_files.append(arg) |
| 142 elif arg_mode == 'gen-src': |
| 143 generated_files.append(arg) |
| 144 elif arg_mode == 'gen-dst': |
| 145 generated_files_dst.append(arg) |
| 146 else: |
| 147 print "ERROR: Expected --source-files" |
| 148 usage() |
| 149 return 1 |
| 150 |
| 151 # Make sure at least one file was specified. |
| 152 if len(source_files) == 0 and len(generated_files) == 0: |
| 153 print "ERROR: At least one input file must be specified." |
| 154 return 1 |
| 155 |
| 156 # Ensure that source_files_root ends with a directory separator. |
| 157 if source_files_root[-1:] != os.sep: |
| 158 source_files_root += os.sep |
| 159 |
| 160 # Verify that the 2 generated_files arrays have the same number of elements. |
| 161 if len(generated_files) < len(generated_files_dst): |
| 162 print "ERROR: len(--generated-files) != len(--generated-files-dst)" |
| 163 return 1 |
| 164 while len(generated_files) > len(generated_files_dst): |
| 165 generated_files_dst.append('') |
| 166 |
| 167 result = buildHostArchive(temp_dir, zip_path, source_files_root, |
| 168 source_files, generated_files, generated_files_dst) |
| 169 |
| 170 return 0 |
| 171 |
| 172 if __name__ == '__main__': |
| 173 sys.exit(main()) |
OLD | NEW |