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 |