| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Creates a zip archive for the Chrome Remote Desktop Host installer. | 6 """Creates a zip archive for the Chrome Remote Desktop Host installer. |
| 7 | 7 |
| 8 This script builds a zip file that contains all the files needed to build an | 8 This script builds a zip file that contains all the files needed to build an |
| 9 installer for Chrome Remote Desktop Host. | 9 installer for Chrome Remote Desktop Host. |
| 10 | 10 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 zipfile_base = os.path.splitext(os.path.basename(zip_path))[0] | 64 zipfile_base = os.path.splitext(os.path.basename(zip_path))[0] |
| 65 zip = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) | 65 zip = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) |
| 66 for (root, dirs, files) in os.walk(directory): | 66 for (root, dirs, files) in os.walk(directory): |
| 67 for f in files: | 67 for f in files: |
| 68 full_path = os.path.join(root, f) | 68 full_path = os.path.join(root, f) |
| 69 rel_path = os.path.relpath(full_path, directory) | 69 rel_path = os.path.relpath(full_path, directory) |
| 70 zip.write(full_path, os.path.join(zipfile_base, rel_path)) | 70 zip.write(full_path, os.path.join(zipfile_base, rel_path)) |
| 71 zip.close() | 71 zip.close() |
| 72 | 72 |
| 73 | 73 |
| 74 def remapSrcFile(dst_root, src_root, src_file): | 74 def remapSrcFile(dst_root, src_roots, src_file): |
| 75 """Calculates destination file path and creates directory. | 75 """Calculates destination file path and creates directory. |
| 76 | 76 |
| 77 The |src_root| prefix is stripped from |src_file| before | 77 Any matching |src_roots| prefix is stripped from |src_file| before |
| 78 appending to |dst_root|. | 78 appending to |dst_root|. |
| 79 | 79 |
| 80 For example, given: | 80 For example, given: |
| 81 dst_root = /output | 81 dst_root = '/output' |
| 82 src_root = host/installer/mac | 82 src_roots = ['host/installer/mac'] |
| 83 src_file = host/installer/mac/Scripts/keystone_install.sh | 83 src_file = 'host/installer/mac/Scripts/keystone_install.sh' |
| 84 The final calculated path is: | 84 The final calculated path is: |
| 85 /output/Scripts/keystone_install.sh | 85 '/output/Scripts/keystone_install.sh' |
| 86 |
| 87 The |src_file| must match one of the |src_roots| prefixes. If there are no |
| 88 matches, then an error is reported. |
| 89 |
| 90 If multiple |src_roots| match, then only the first match is applied. Because |
| 91 of this, if you have roots that share a common prefix, the longest string |
| 92 should be first in this array. |
| 86 | 93 |
| 87 Args: | 94 Args: |
| 88 dst_root: Target directory where files are copied. | 95 dst_root: Target directory where files are copied. |
| 89 src_root: Path prefix which is stripped of |src_file| before appending | 96 src_roots: Array of path prefixes which will be stripped of |src_file| |
| 90 it to the |dst_root|. | 97 (if they match) before appending it to the |dst_root|. |
| 91 src_file: Source file to be copied. | 98 src_file: Source file to be copied. |
| 92 Returns: | 99 Returns: |
| 93 Full path to destination file in |dst_root|. | 100 Full path to destination file in |dst_root|. |
| 94 """ | 101 """ |
| 95 # Strip of directory prefix. | 102 # Strip of directory prefix. |
| 96 if src_file.startswith(src_root): | 103 found_root = False |
| 97 src_file = src_file[len(src_root):] | 104 for root in src_roots: |
| 105 if src_file.startswith(root): |
| 106 src_file = src_file[len(root):] |
| 107 found_root = True |
| 108 break |
| 109 |
| 110 if not found_root: |
| 111 error('Unable to match prefix for %s' % src_file) |
| 112 |
| 98 dst_file = os.path.join(dst_root, src_file) | 113 dst_file = os.path.join(dst_root, src_file) |
| 99 # Make sure target directory exists. | 114 # Make sure target directory exists. |
| 100 dst_dir = os.path.dirname(dst_file) | 115 dst_dir = os.path.dirname(dst_file) |
| 101 if not os.path.exists(dst_dir): | 116 if not os.path.exists(dst_dir): |
| 102 os.makedirs(dst_dir, 0775) | 117 os.makedirs(dst_dir, 0775) |
| 103 return dst_file | 118 return dst_file |
| 104 | 119 |
| 105 | 120 |
| 106 def copyFileWithDefs(src_file, dst_file, defs): | 121 def copyFileWithDefs(src_file, dst_file, defs): |
| 107 """Copies from src_file to dst_file, performing variable substitution. | 122 """Copies from src_file to dst_file, performing variable substitution. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 | 159 |
| 145 # Unzip into correct dir in out_dir. | 160 # Unzip into correct dir in out_dir. |
| 146 out_zip_path = remapSrcFile(out_dir, files_root, zip_file) | 161 out_zip_path = remapSrcFile(out_dir, files_root, zip_file) |
| 147 out_zip_dir = os.path.dirname(out_zip_path) | 162 out_zip_dir = os.path.dirname(out_zip_path) |
| 148 | 163 |
| 149 (src_dir, ignore1) = os.path.splitext(zip_file) | 164 (src_dir, ignore1) = os.path.splitext(zip_file) |
| 150 (base_dir_name, ignore2) = os.path.splitext(base_zip_name) | 165 (base_dir_name, ignore2) = os.path.splitext(base_zip_name) |
| 151 shutil.copytree(src_dir, os.path.join(out_zip_dir, base_dir_name)) | 166 shutil.copytree(src_dir, os.path.join(out_zip_dir, base_dir_name)) |
| 152 | 167 |
| 153 | 168 |
| 154 def buildHostArchive(temp_dir, zip_path, source_files_root, source_files, | 169 def buildHostArchive(temp_dir, zip_path, source_file_roots, source_files, |
| 155 gen_files, gen_files_dst, defs): | 170 gen_files, gen_files_dst, defs): |
| 156 """Builds a zip archive with the files needed to build the installer. | 171 """Builds a zip archive with the files needed to build the installer. |
| 157 | 172 |
| 158 Args: | 173 Args: |
| 159 temp_dir: Temporary dir used to build up the contents for the archive. | 174 temp_dir: Temporary dir used to build up the contents for the archive. |
| 160 zip_path: Full path to the zip file to create. | 175 zip_path: Full path to the zip file to create. |
| 161 source_files_root: Path prefix to strip off |files| when adding to archive. | 176 source_file_roots: Array of path prefixes to strip off |files| when adding |
| 177 to the archive. |
| 162 source_files: The array of files to add to archive. The path structure is | 178 source_files: The array of files to add to archive. The path structure is |
| 163 preserved (except for the |files_root| prefix). | 179 preserved (except for the |files_root| prefix). |
| 164 gen_files: Full path to binaries to add to archive. | 180 gen_files: Full path to binaries to add to archive. |
| 165 gen_files_dst: Relative path of where to add binary files in archive. | 181 gen_files_dst: Relative path of where to add binary files in archive. |
| 166 This array needs to parallel |binaries_src|. | 182 This array needs to parallel |binaries_src|. |
| 167 defs: Dictionary of variable definitions. | 183 defs: Dictionary of variable definitions. |
| 168 """ | 184 """ |
| 169 cleanDir(temp_dir) | 185 cleanDir(temp_dir) |
| 170 | 186 |
| 171 for f in source_files: | 187 for f in source_files: |
| 172 dst_file = remapSrcFile(temp_dir, source_files_root, f) | 188 dst_file = remapSrcFile(temp_dir, source_file_roots, f) |
| 173 base_file = os.path.basename(f) | 189 base_file = os.path.basename(f) |
| 174 (base, ext) = os.path.splitext(f) | 190 (base, ext) = os.path.splitext(f) |
| 175 if ext == '.zip': | 191 if ext == '.zip': |
| 176 copyZipIntoArchive(temp_dir, source_files_root, f) | 192 copyZipIntoArchive(temp_dir, source_file_roots, f) |
| 177 elif ext in ['.sh', '.packproj', '.plist']: | 193 elif ext in ['.sh', '.packproj', '.plist']: |
| 178 copyFileWithDefs(f, dst_file, defs) | 194 copyFileWithDefs(f, dst_file, defs) |
| 179 else: | 195 else: |
| 180 shutil.copy2(src_file, dst_file) | 196 shutil.copy2(f, dst_file) |
| 181 | 197 |
| 182 for bs, bd in zip(gen_files, gen_files_dst): | 198 for bs, bd in zip(gen_files, gen_files_dst): |
| 183 dst_file = remapSrcFile(temp_dir, source_files_root, bd) | 199 dst_file = os.path.join(temp_dir, bd) |
| 184 if os.path.isdir(bs): | 200 if os.path.isdir(bs): |
| 185 shutil.copytree(bs, dst_file) | 201 shutil.copytree(bs, dst_file) |
| 186 else: | 202 else: |
| 187 shutil.copy2(bs, dst_file) | 203 shutil.copy2(bs, dst_file) |
| 188 | 204 |
| 189 createZip(zip_path, temp_dir) | 205 createZip(zip_path, temp_dir) |
| 190 | 206 |
| 191 | 207 |
| 192 def error(msg): | 208 def error(msg): |
| 193 sys.stderr.write('ERROR: %s' % msg) | 209 sys.stderr.write('ERROR: %s\n' % msg) |
| 194 sys.exit(1) | 210 sys.exit(1) |
| 195 | 211 |
| 196 | 212 |
| 197 def usage(): | 213 def usage(): |
| 198 """Display basic usage information.""" | 214 """Display basic usage information.""" |
| 199 print ('Usage: %s\n' | 215 print ('Usage: %s\n' |
| 200 ' <temp-dir> <zip-path> <files-root-dir>\n' | 216 ' <temp-dir> <zip-path>\n' |
| 217 ' --source-file-roots <list of roots to strip off source files...>\n' |
| 201 ' --source-files <list of source files...>\n' | 218 ' --source-files <list of source files...>\n' |
| 202 ' --generated-files <list of generated target files...>\n' | 219 ' --generated-files <list of generated target files...>\n' |
| 203 ' --generated-files-dst <dst for each generated file...>\n' | 220 ' --generated-files-dst <dst for each generated file...>\n' |
| 204 ' --defs <list of VARIABLE=value definitions...>' | 221 ' --defs <list of VARIABLE=value definitions...>' |
| 205 ) % sys.argv[0] | 222 ) % sys.argv[0] |
| 206 | 223 |
| 207 | 224 |
| 208 def main(): | 225 def main(): |
| 209 if len(sys.argv) < 3: | 226 if len(sys.argv) < 2: |
| 210 usage() | 227 usage() |
| 211 error('Too few arguments') | 228 error('Too few arguments') |
| 212 | 229 |
| 213 temp_dir = sys.argv[1] | 230 temp_dir = sys.argv[1] |
| 214 zip_path = sys.argv[2] | 231 zip_path = sys.argv[2] |
| 215 source_files_root = sys.argv[3] | |
| 216 | 232 |
| 217 arg_mode = '' | 233 arg_mode = '' |
| 234 source_file_roots = [] |
| 218 source_files = [] | 235 source_files = [] |
| 219 generated_files = [] | 236 generated_files = [] |
| 220 generated_files_dst = [] | 237 generated_files_dst = [] |
| 221 definitions = [] | 238 definitions = [] |
| 222 for arg in sys.argv[4:]: | 239 for arg in sys.argv[3:]: |
| 223 if arg == '--source-files': | 240 if arg == '--source-file-roots': |
| 241 arg_mode = 'src-roots' |
| 242 elif arg == '--source-files': |
| 224 arg_mode = 'files' | 243 arg_mode = 'files' |
| 225 elif arg == '--generated-files': | 244 elif arg == '--generated-files': |
| 226 arg_mode = 'gen-src' | 245 arg_mode = 'gen-src' |
| 227 elif arg == '--generated-files-dst': | 246 elif arg == '--generated-files-dst': |
| 228 arg_mode = 'gen-dst' | 247 arg_mode = 'gen-dst' |
| 229 elif arg == '--defs': | 248 elif arg == '--defs': |
| 230 arg_mode = 'defs' | 249 arg_mode = 'defs' |
| 231 | 250 |
| 251 elif arg_mode == 'src-roots': |
| 252 source_file_roots.append(arg) |
| 232 elif arg_mode == 'files': | 253 elif arg_mode == 'files': |
| 233 source_files.append(arg) | 254 source_files.append(arg) |
| 234 elif arg_mode == 'gen-src': | 255 elif arg_mode == 'gen-src': |
| 235 generated_files.append(arg) | 256 generated_files.append(arg) |
| 236 elif arg_mode == 'gen-dst': | 257 elif arg_mode == 'gen-dst': |
| 237 generated_files_dst.append(arg) | 258 generated_files_dst.append(arg) |
| 238 elif arg_mode == 'defs': | 259 elif arg_mode == 'defs': |
| 239 definitions.append(arg) | 260 definitions.append(arg) |
| 240 else: | 261 else: |
| 241 usage() | 262 usage() |
| 242 error('Expected --source-files') | 263 error('Expected --source-files') |
| 243 | 264 |
| 244 # Make sure at least one file was specified. | 265 # Make sure at least one file was specified. |
| 245 if len(source_files) == 0 and len(generated_files) == 0: | 266 if len(source_files) == 0 and len(generated_files) == 0: |
| 246 error('At least one input file must be specified.') | 267 error('At least one input file must be specified.') |
| 247 | 268 |
| 248 # Ensure that source_files_root ends with a directory separator. | 269 # Ensure that each path in source_file_roots ends with a directory separator. |
| 249 if source_files_root[-1:] != os.sep: | 270 for root in source_file_roots: |
| 250 source_files_root += os.sep | 271 if root[-1:] != os.sep: |
| 272 error('Each source-file-root should end with a "\": %s' % root) |
| 273 |
| 274 # Sort roots to ensure the longest one is first. See comment in remapSrcFile |
| 275 # for why this is necessary. |
| 276 source_file_roots.sort(key=len, reverse=True) |
| 251 | 277 |
| 252 # Verify that the 2 generated_files arrays have the same number of elements. | 278 # Verify that the 2 generated_files arrays have the same number of elements. |
| 253 if len(generated_files) != len(generated_files_dst): | 279 if len(generated_files) != len(generated_files_dst): |
| 254 error('len(--generated-files) != len(--generated-files-dst)') | 280 error('len(--generated-files) != len(--generated-files-dst)') |
| 255 | 281 |
| 256 defs = buildDefDictionary(definitions) | 282 defs = buildDefDictionary(definitions) |
| 257 | 283 |
| 258 result = buildHostArchive(temp_dir, zip_path, source_files_root, | 284 result = buildHostArchive(temp_dir, zip_path, source_file_roots, |
| 259 source_files, generated_files, generated_files_dst, | 285 source_files, generated_files, generated_files_dst, |
| 260 defs) | 286 defs) |
| 261 | 287 |
| 262 return 0 | 288 return 0 |
| 263 | 289 |
| 264 | 290 |
| 265 if __name__ == '__main__': | 291 if __name__ == '__main__': |
| 266 sys.exit(main()) | 292 sys.exit(main()) |
| OLD | NEW |