OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 """Script to create Chrome Installer archive. | 6 """Script to create Chrome Installer archive. |
7 | 7 |
8 This script is used to create an archive of all the files required for a | 8 This script is used to create an archive of all the files required for a |
9 Chrome install in appropriate directory structure. It reads chrome.release | 9 Chrome install in appropriate directory structure. It reads chrome.release |
10 file as input, creates chrome.7z archive, compresses setup.exe and | 10 file as input, creates chrome.7z archive, compresses setup.exe and |
11 generates packed_files.txt for mini_installer project. | 11 generates packed_files.txt for mini_installer project. |
12 | 12 |
13 """ | 13 """ |
14 | 14 |
15 import ConfigParser | 15 import ConfigParser |
16 import glob | 16 import glob |
17 import md5 | |
18 import optparse | 17 import optparse |
19 import os | 18 import os |
20 import shutil | 19 import shutil |
20 import subprocess | |
21 import sys | 21 import sys |
22 | 22 |
23 | 23 |
24 ARCHIVE_DIR = "installer_archive" | 24 ARCHIVE_DIR = "installer_archive" |
25 | 25 |
26 # suffix to uncompresed full archive file, appended to options.output_name | 26 # suffix to uncompresed full archive file, appended to options.output_name |
27 ARCHIVE_SUFFIX = ".7z" | 27 ARCHIVE_SUFFIX = ".7z" |
28 BSDIFF_EXEC = "bsdiff.exe" | 28 BSDIFF_EXEC = "bsdiff.exe" |
29 CHROME_DIR = "Chrome-bin" | 29 CHROME_DIR = "Chrome-bin" |
30 CHROME_PATCH_FILE_SUFFIX = "_patch" # prefixed by options.output_name | 30 CHROME_PATCH_FILE_SUFFIX = "_patch" # prefixed by options.output_name |
31 | 31 |
32 # compressed full archive suffix, will be prefixed by options.output_name | 32 # compressed full archive suffix, will be prefixed by options.output_name |
33 COMPRESSED_ARCHIVE_SUFFIX = ".packed.7z" | 33 COMPRESSED_ARCHIVE_SUFFIX = ".packed.7z" |
34 | 34 |
35 COMPRESSED_FILE_EXT = ".packed.7z" # extension of patch archive file | 35 COMPRESSED_FILE_EXT = ".packed.7z" # extension of patch archive file |
36 COURGETTE_EXEC = "courgette.exe" | 36 COURGETTE_EXEC = "courgette.exe" |
37 MINI_INSTALLER_INPUT_FILE = "packed_files.txt" | 37 MINI_INSTALLER_INPUT_FILE = "packed_files.txt" |
38 PACKED_FILE_COMMENTS = """ | |
39 // This file is automatically generated by create_installer_archive.py. | |
40 // It contains the resource entries that are going to be linked inside | |
41 // mini_installer.exe. For each file to be linked there should be two | |
42 // lines: | |
43 // - The first line contains the output filename (without path) and the | |
44 // type of the resource ('BN' - not compressed , 'BL' - LZ compressed, | |
45 // 'B7' - LZMA compressed) | |
46 // - The second line contains the path to the input file. Uses '/' to | |
47 // separate path components. | |
48 """ | |
49 PATCH_FILE_EXT = '.diff' | 38 PATCH_FILE_EXT = '.diff' |
50 SETUP_EXEC = "setup.exe" | 39 SETUP_EXEC = "setup.exe" |
51 SETUP_PATCH_FILE_PREFIX = "setup_patch" | 40 SETUP_PATCH_FILE_PREFIX = "setup_patch" |
52 TEMP_ARCHIVE_DIR = "temp_installer_archive" | 41 TEMP_ARCHIVE_DIR = "temp_installer_archive" |
53 VERSION_FILE = "VERSION" | 42 VERSION_FILE = "VERSION" |
54 | 43 |
55 def BuildVersion(output_dir): | 44 |
45 def BuildVersion(build_dir): | |
56 """Returns the full build version string constructed from information in | 46 """Returns the full build version string constructed from information in |
57 VERSION_FILE. Any segment not found in that file will default to '0'. | 47 VERSION_FILE. Any segment not found in that file will default to '0'. |
58 """ | 48 """ |
59 major = 0 | 49 major = 0 |
60 minor = 0 | 50 minor = 0 |
61 build = 0 | 51 build = 0 |
62 patch = 0 | 52 patch = 0 |
63 for line in open(os.path.join(output_dir, "..", "..", "chrome", VERSION_FILE), 'r'): | 53 for line in open(os.path.join(build_dir, '../../chrome', VERSION_FILE), 'r'): |
64 line = line.rstrip() | 54 line = line.rstrip() |
65 if line.startswith('MAJOR='): | 55 if line.startswith('MAJOR='): |
66 major = line[6:] | 56 major = line[6:] |
67 elif line.startswith('MINOR='): | 57 elif line.startswith('MINOR='): |
68 minor = line[6:] | 58 minor = line[6:] |
69 elif line.startswith('BUILD='): | 59 elif line.startswith('BUILD='): |
70 build = line[6:] | 60 build = line[6:] |
71 elif line.startswith('PATCH='): | 61 elif line.startswith('PATCH='): |
72 patch = line[6:] | 62 patch = line[6:] |
73 return '%s.%s.%s.%s' % (major, minor, build, patch) | 63 return '%s.%s.%s.%s' % (major, minor, build, patch) |
74 | 64 |
75 def CompressUsingLZMA(output_dir, compressed_file, input_file): | 65 |
76 lzma_exec = GetLZMAExec(output_dir) | 66 def CompressUsingLZMA(build_dir, compressed_file, input_file): |
77 cmd = ('%s a -t7z ' | 67 lzma_exec = GetLZMAExec(build_dir) |
68 cmd = [lzma_exec, | |
69 'a', '-t7z', | |
78 # Flags equivalent to -mx9 (ultra) but with the bcj2 turned on (exe | 70 # Flags equivalent to -mx9 (ultra) but with the bcj2 turned on (exe |
79 # pre-filter). This results in a ~2.3MB decrease in installer size on | 71 # pre-filter). This results in a ~2.3MB decrease in installer size on |
80 # a 24MB installer. | 72 # a 24MB installer. |
81 # Additionally, these settings reflect a 7zip 4.42 and up change in | 73 # Additionally, these settings reflect a 7zip 4.42 and up change in |
82 # the definition of -mx9, increasting the dicionary size moving to | 74 # the definition of -mx9, increasting the dicionary size moving to |
83 # 26bit = 64MB. This results in an additional ~3.5MB decrease. | 75 # 26bit = 64MB. This results in an additional ~3.5MB decrease. |
84 # Older 7zip versions can support these settings, as these changes | 76 # Older 7zip versions can support these settings, as these changes |
85 # rely on existing functionality in the lzma format. | 77 # rely on existing functionality in the lzma format. |
86 '-m0=BCJ2 ' | 78 '-m0=BCJ2', |
87 '-m1=LZMA:d26:fb64 ' | 79 '-m1=LZMA:d26:fb64', |
88 '-m2=LZMA:d20:fb64:mf=bt2 ' | 80 '-m2=LZMA:d20:fb64:mf=bt2', |
89 '-m3=LZMA:d20:fb64:mf=bt2 ' | 81 '-m3=LZMA:d20:fb64:mf=bt2', |
90 '-mb0:1 -mb0s1:2 ' | 82 '-mb0:1', |
91 '-mb0s2:3 ' | 83 '-mb0s1:2', |
92 '"%s" "%s"') % (lzma_exec, compressed_file, input_file) | 84 '-mb0s2:3', |
85 compressed_file, | |
86 input_file,] | |
93 if os.path.exists(compressed_file): | 87 if os.path.exists(compressed_file): |
94 os.remove(compressed_file) | 88 os.remove(compressed_file) |
95 RunSystemCommand(cmd) | 89 RunSystemCommand(cmd) |
96 | 90 |
97 def CopyAllFilesToStagingDir(config, distribution, staging_dir, output_dir): | 91 |
92 def CopyAllFilesToStagingDir(config, distribution, staging_dir, build_dir): | |
98 """Copies the files required for installer archive. | 93 """Copies the files required for installer archive. |
99 Copies all common files required for various distributions of Chromium and | 94 Copies all common files required for various distributions of Chromium and |
100 also files for the specific Chromium build specified by distribution. | 95 also files for the specific Chromium build specified by distribution. |
101 """ | 96 """ |
102 CopySectionFilesToStagingDir(config, 'GENERAL', staging_dir, output_dir) | 97 CopySectionFilesToStagingDir(config, 'GENERAL', staging_dir, build_dir) |
103 if distribution: | 98 if distribution: |
104 if len(distribution) > 1 and distribution[0] == '_': | 99 if len(distribution) > 1 and distribution[0] == '_': |
105 distribution = distribution[1:] | 100 distribution = distribution[1:] |
106 CopySectionFilesToStagingDir(config, distribution.upper(), | 101 CopySectionFilesToStagingDir(config, distribution.upper(), |
107 staging_dir, output_dir) | 102 staging_dir, build_dir) |
108 | 103 |
109 def IsChromeFrameFile(file): | |
110 for cf_file in ['npchrome_frame', 'chrome_launcher']: | |
111 if file.lower().find(cf_file) != -1: | |
112 return True | |
113 return False | |
114 | 104 |
115 def CopySectionFilesToStagingDir(config, section, staging_dir, output_dir): | 105 def CopySectionFilesToStagingDir(config, section, staging_dir, build_dir): |
116 """Copies installer archive files specified in section to staging dir. | 106 """Copies installer archive files specified in section to staging dir. |
117 This method copies reads section from config file and copies all the files | 107 This method copies reads section from config file and copies all the files |
118 specified to staging dir. | 108 specified to staging dir. |
119 """ | 109 """ |
120 for option in config.options(section): | 110 for option in config.options(section): |
121 if option.endswith('dir'): | 111 if option.endswith('dir'): |
122 continue | 112 continue |
123 | 113 |
124 dst = os.path.join(staging_dir, config.get(section, option)) | 114 dst = os.path.join(staging_dir, config.get(section, option)) |
125 if not os.path.exists(dst): | 115 if not os.path.exists(dst): |
126 os.makedirs(dst) | 116 os.makedirs(dst) |
127 for file in glob.glob(os.path.join(output_dir, option)): | 117 for file in glob.glob(os.path.join(build_dir, option)): |
128 if IsChromeFrameFile(file): | 118 shutil.copy(file, dst) |
129 try: | |
130 shutil.copy(file, dst) | |
131 except IOError: | |
132 # TODO(robertshield): Temporary hack to work around problems building | |
133 # Chrome Frame binaries on non-Chrome Frame builders. Remove this | |
134 # asap. | |
135 print 'Error attempting to copy ' + file + ' to ' + dst | |
136 else: | |
137 shutil.copy(file, dst) | |
138 | 119 |
139 def GenerateDiffPatch(options, orig_file, new_file, patch_file): | 120 def GenerateDiffPatch(options, orig_file, new_file, patch_file): |
140 if (options.diff_algorithm == "COURGETTE"): | 121 if (options.diff_algorithm == "COURGETTE"): |
141 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) | 122 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) |
142 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) | 123 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) |
143 else: | 124 else: |
144 exe_file = os.path.join(options.output_dir, BSDIFF_EXEC) | 125 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC) |
145 cmd = '%s "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) | 126 cmd = [exe_file, orig_file, new_file, patch_file,] |
146 RunSystemCommand(cmd) | 127 RunSystemCommand(cmd) |
147 | 128 |
148 def GetLZMAExec(output_dir): | 129 def GetLZMAExec(build_dir): |
149 lzma_exec = os.path.join(output_dir, "..", "..", "third_party", | 130 lzma_exec = os.path.join(build_dir, "..", "..", "third_party", |
150 "lzma_sdk", "Executable", "7za.exe") | 131 "lzma_sdk", "Executable", "7za.exe") |
151 return lzma_exec | 132 return lzma_exec |
152 | 133 |
153 def GetPrevVersion(output_dir, temp_dir, last_chrome_installer): | 134 def GetPrevVersion(build_dir, temp_dir, last_chrome_installer): |
154 if not last_chrome_installer: | 135 if not last_chrome_installer: |
155 return '' | 136 return '' |
156 | 137 |
157 lzma_exec = GetLZMAExec(options.output_dir) | 138 lzma_exec = GetLZMAExec(options.build_dir) |
158 prev_archive_file = os.path.join(options.last_chrome_installer, | 139 prev_archive_file = os.path.join(options.last_chrome_installer, |
159 options.output_name + ARCHIVE_SUFFIX) | 140 options.output_name + ARCHIVE_SUFFIX) |
160 cmd = '%s x -o"%s" "%s" Chrome-bin/*/chrome.dll' % (lzma_exec, temp_dir, | 141 cmd = [lzma_exec, |
161 prev_archive_file) | 142 'x', |
143 '-o"%s"' % temp_dir, | |
144 prev_archive_file, | |
145 'Chrome-bin/*/chrome.dll',] | |
162 RunSystemCommand(cmd) | 146 RunSystemCommand(cmd) |
163 dll_path = glob.glob(os.path.join(temp_dir, 'Chrome-bin', '*', 'chrome.dll')) | 147 dll_path = glob.glob(os.path.join(temp_dir, 'Chrome-bin', '*', 'chrome.dll')) |
164 return os.path.split(os.path.split(dll_path[0])[0])[1] | 148 return os.path.split(os.path.split(dll_path[0])[0])[1] |
165 | 149 |
166 def MakeStagingDirectories(output_dir): | 150 def MakeStagingDirectories(staging_dir): |
167 """Creates a staging path for installer archive. If directory exists already, | 151 """Creates a staging path for installer archive. If directory exists already, |
168 deletes the existing directory. | 152 deletes the existing directory. |
169 """ | 153 """ |
170 prefixed_archive_dir = (options.archive_prefix or "") + ARCHIVE_DIR | 154 file_path = os.path.join(staging_dir, TEMP_ARCHIVE_DIR) |
brucedawson
2016/04/16 00:08:59
I hate to do a drive-by code review 52 months afte
Nico
2017/09/05 17:37:02
I noticed the same thing 57 months after the fact.
Nico
2017/09/05 17:38:10
Ah, there's a reply on the toplevel issue here: ht
| |
171 file_path = os.path.join(output_dir, prefixed_archive_dir) | |
172 if os.path.exists(file_path): | 155 if os.path.exists(file_path): |
173 shutil.rmtree(file_path) | 156 shutil.rmtree(file_path) |
174 os.makedirs(file_path) | 157 os.makedirs(file_path) |
175 | 158 |
176 prefixed_temp_archive_dir = (options.archive_prefix or "") + TEMP_ARCHIVE_DIR | 159 temp_file_path = os.path.join(staging_dir, TEMP_ARCHIVE_DIR) |
177 temp_file_path = os.path.join(output_dir, prefixed_temp_archive_dir) | |
178 if os.path.exists(temp_file_path): | 160 if os.path.exists(temp_file_path): |
179 shutil.rmtree(temp_file_path) | 161 shutil.rmtree(temp_file_path) |
180 os.makedirs(temp_file_path) | 162 os.makedirs(temp_file_path) |
181 return (file_path, temp_file_path) | 163 return (file_path, temp_file_path) |
182 | 164 |
183 def Readconfig(output_dir, input_file, current_version): | 165 def Readconfig(build_dir, input_file, current_version): |
184 """Reads config information from input file after setting default value of | 166 """Reads config information from input file after setting default value of |
185 global variabes. | 167 global variabes. |
186 """ | 168 """ |
187 variables = {} | 169 variables = {} |
188 variables['ChromeDir'] = CHROME_DIR | 170 variables['ChromeDir'] = CHROME_DIR |
189 variables['VersionDir'] = os.path.join(variables['ChromeDir'], | 171 variables['VersionDir'] = os.path.join(variables['ChromeDir'], |
190 current_version) | 172 current_version) |
191 config = ConfigParser.SafeConfigParser(variables) | 173 config = ConfigParser.SafeConfigParser(variables) |
192 config.read(input_file) | 174 config.read(input_file) |
193 return config | 175 return config |
194 | 176 |
195 def RunSystemCommand(cmd): | 177 def RunSystemCommand(cmd): |
196 print 'Running [' + cmd + ']' | 178 print 'Running', cmd |
197 exit_code = os.system(cmd) | 179 exit_code = subprocess.call(cmd) |
198 if (exit_code != 0): | 180 if (exit_code != 0): |
199 raise Exception("Error while running cmd: %s, exit_code: %s" % | 181 raise Exception("Error while running cmd: %s, exit_code: %s" % |
200 (cmd, exit_code)) | 182 (cmd, exit_code)) |
201 | 183 |
202 def CreateArchiveFile(options, staging_dir, current_version, prev_version): | 184 def CreateArchiveFile(options, staging_dir, current_version, prev_version): |
203 """Creates a new installer archive file after deleting any existing old file. | 185 """Creates a new installer archive file after deleting any existing old file. |
204 """ | 186 """ |
205 # First create an uncompressed archive file for the current build (chrome.7z) | 187 # First create an uncompressed archive file for the current build (chrome.7z) |
206 lzma_exec = GetLZMAExec(options.output_dir) | 188 lzma_exec = GetLZMAExec(options.build_dir) |
207 archive_file = os.path.join(options.output_dir, | 189 archive_file = os.path.join(options.build_dir, |
208 options.output_name + ARCHIVE_SUFFIX) | 190 options.output_name + ARCHIVE_SUFFIX) |
209 cmd = '%s a -t7z "%s" "%s" -mx0' % (lzma_exec, archive_file, | 191 cmd = [lzma_exec, |
210 os.path.join(staging_dir, CHROME_DIR)) | 192 'a', |
193 '-t7z', | |
194 archive_file, | |
195 os.path.join(staging_dir, CHROME_DIR), | |
196 '-mx0',] | |
211 # There doesnt seem to be any way in 7za.exe to override existing file so | 197 # There doesnt seem to be any way in 7za.exe to override existing file so |
212 # we always delete before creating a new one. | 198 # we always delete before creating a new one. |
213 if not os.path.exists(archive_file): | 199 if not os.path.exists(archive_file): |
214 RunSystemCommand(cmd) | 200 RunSystemCommand(cmd) |
215 elif options.skip_rebuild_archive != "true": | 201 elif options.skip_rebuild_archive != "true": |
216 os.remove(archive_file) | 202 os.remove(archive_file) |
217 RunSystemCommand(cmd) | 203 RunSystemCommand(cmd) |
218 | 204 |
219 # If we are generating a patch, run bsdiff against previous build and | 205 # If we are generating a patch, run bsdiff against previous build and |
220 # compress the resulting patch file. If this is not a patch just compress the | 206 # compress the resulting patch file. If this is not a patch just compress the |
221 # uncompressed archive file. | 207 # uncompressed archive file. |
222 patch_name_prefix = options.output_name + CHROME_PATCH_FILE_SUFFIX | 208 patch_name_prefix = options.output_name + CHROME_PATCH_FILE_SUFFIX |
223 if options.last_chrome_installer: | 209 if options.last_chrome_installer: |
224 prev_archive_file = os.path.join(options.last_chrome_installer, | 210 prev_archive_file = os.path.join(options.last_chrome_installer, |
225 options.output_name + ARCHIVE_SUFFIX) | 211 options.output_name + ARCHIVE_SUFFIX) |
226 patch_file = os.path.join(options.output_dir, patch_name_prefix + | 212 patch_file = os.path.join(options.build_dir, patch_name_prefix + |
227 PATCH_FILE_EXT) | 213 PATCH_FILE_EXT) |
228 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) | 214 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) |
229 compressed_archive_file = patch_name_prefix + '_' + \ | 215 compressed_archive_file = patch_name_prefix + '_' + \ |
230 current_version + '_from_' + prev_version + \ | 216 current_version + '_from_' + prev_version + \ |
231 COMPRESSED_FILE_EXT | 217 COMPRESSED_FILE_EXT |
232 orig_file = patch_file | 218 orig_file = patch_file |
233 else: | 219 else: |
234 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX | 220 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX |
235 orig_file = archive_file | 221 orig_file = archive_file |
236 | 222 |
237 compressed_archive_file_path = os.path.join(options.output_dir, | 223 compressed_archive_file_path = os.path.join(options.build_dir, |
238 compressed_archive_file) | 224 compressed_archive_file) |
239 CompressUsingLZMA(options.output_dir, compressed_archive_file_path, orig_file) | 225 CompressUsingLZMA(options.build_dir, compressed_archive_file_path, orig_file) |
240 | 226 |
241 return compressed_archive_file | 227 return compressed_archive_file |
242 | 228 |
243 | 229 |
244 def PrepareSetupExec(options, staging_dir, current_version, prev_version): | 230 def PrepareSetupExec(options, staging_dir, current_version, prev_version): |
245 """Prepares setup.exe for bundling in mini_installer based on options.""" | 231 """Prepares setup.exe for bundling in mini_installer based on options.""" |
246 if options.setup_exe_format == "FULL": | 232 if options.setup_exe_format == "FULL": |
247 setup_file = SETUP_EXEC | 233 setup_file = SETUP_EXEC |
248 elif options.setup_exe_format == "DIFF": | 234 elif options.setup_exe_format == "DIFF": |
249 if not options.last_chrome_installer: | 235 if not options.last_chrome_installer: |
250 raise Exception( | 236 raise Exception( |
251 "To use DIFF for setup.exe, --last_chrome_installer is needed.") | 237 "To use DIFF for setup.exe, --last_chrome_installer is needed.") |
252 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) | 238 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) |
253 new_setup_file = os.path.join(options.output_dir, SETUP_EXEC) | 239 new_setup_file = os.path.join(options.build_dir, SETUP_EXEC) |
254 patch_file = os.path.join(options.output_dir, SETUP_PATCH_FILE_PREFIX + | 240 patch_file = os.path.join(options.build_dir, SETUP_PATCH_FILE_PREFIX + |
255 PATCH_FILE_EXT) | 241 PATCH_FILE_EXT) |
256 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) | 242 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) |
257 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ | 243 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ |
258 '_from_' + prev_version + COMPRESSED_FILE_EXT | 244 '_from_' + prev_version + COMPRESSED_FILE_EXT |
259 setup_file_path = os.path.join(options.output_dir, setup_file) | 245 setup_file_path = os.path.join(options.build_dir, setup_file) |
260 CompressUsingLZMA(options.output_dir, setup_file_path, patch_file) | 246 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file) |
261 else: | 247 else: |
262 cmd = 'makecab.exe /D CompressionType=LZX /V1 /L "%s" "%s"' % ( | 248 cmd = ['makecab.exe', |
263 options.output_dir, os.path.join(options.output_dir, SETUP_EXEC)) | 249 '/D', 'CompressionType=LZX', |
250 '/V1', | |
251 '/L', options.build_dir, | |
252 os.path.join(options.build_dir, SETUP_EXEC),] | |
264 RunSystemCommand(cmd) | 253 RunSystemCommand(cmd) |
265 setup_file = SETUP_EXEC[:len(SETUP_EXEC) - 1] + "_" | 254 setup_file = SETUP_EXEC[:-1] + "_" |
266 return setup_file | 255 return setup_file |
267 | 256 |
268 | 257 |
269 def CreateResourceInputFile(output_dir, setup_format, archive_file, setup_file): | 258 _RESOURCE_FILE_TEMPLATE = """\ |
259 // This file is automatically generated by create_installer_archive.py. | |
260 // It contains the resource entries that are going to be linked inside | |
261 // mini_installer.exe. For each file to be linked there should be two | |
262 // lines: | |
263 // - The first line contains the output filename (without path) and the | |
264 // type of the resource ('BN' - not compressed , 'BL' - LZ compressed, | |
265 // 'B7' - LZMA compressed) | |
266 // - The second line contains the path to the input file. Uses '/' to | |
267 // separate path components. | |
268 | |
269 %(setup_file)s %(setup_file_resource_type)s | |
270 "%(setup_file_path)s" | |
271 | |
272 %(archive_file)s B7 | |
273 "%(archive_file_path)s" | |
274 """ | |
275 | |
276 | |
277 def CreateResourceInputFile( | |
278 build_dir, setup_format, archive_file, setup_file, resource_file_path): | |
270 """Creates resource input file (packed_files.txt) for mini_installer project. | 279 """Creates resource input file (packed_files.txt) for mini_installer project. |
271 | 280 |
272 This method checks the format of setup.exe being used and according sets | 281 This method checks the format of setup.exe being used and according sets |
273 its resource type. | 282 its resource type. |
274 """ | 283 """ |
275 setup_resource_type = "BL" | 284 setup_resource_type = "BL" |
276 if (options.setup_exe_format == "FULL"): | 285 if (setup_format == "FULL"): |
277 setup_resource_type = "BN" | 286 setup_resource_type = "BN" |
278 elif (options.setup_exe_format == "DIFF"): | 287 elif (setup_format == "DIFF"): |
279 setup_resource_type = "B7" | 288 setup_resource_type = "B7" |
280 setup_file_entry = "%s\t\t%s\n\"%s\"" % (setup_file, setup_resource_type, | |
281 os.path.join(output_dir, setup_file).replace("\\","/")) | |
282 | 289 |
283 archive_file_entry = "\n%s\t\tB7\n\"%s\"\n" % (archive_file, | 290 # Expand the resource file template. |
284 os.path.join(output_dir, archive_file).replace("\\","/")) | 291 args = { |
285 output_file = os.path.join(output_dir, MINI_INSTALLER_INPUT_FILE) | 292 'setup_file': setup_file, |
286 f = open(output_file, 'w') | 293 'setup_file_resource_type': setup_resource_type, |
287 try: | 294 'setup_file_path': |
288 f.write(PACKED_FILE_COMMENTS) | 295 os.path.join(build_dir, setup_file).replace("\\","/"), |
289 f.write(setup_file_entry) | 296 'archive_file': archive_file, |
290 f.write(archive_file_entry) | 297 'archive_file_path': |
291 finally: | 298 os.path.join(build_dir, archive_file).replace("\\","/"), |
292 f.close() | 299 } |
300 resource_file = _RESOURCE_FILE_TEMPLATE % args | |
301 | |
302 with open(resource_file_path, 'w') as f: | |
303 f.write(resource_file) | |
293 | 304 |
294 | 305 |
295 def main(options): | 306 def main(options): |
296 """Main method that reads input file, creates archive file and write | 307 """Main method that reads input file, creates archive file and write |
297 resource input file. | 308 resource input file. |
298 """ | 309 """ |
299 current_version = BuildVersion(options.output_dir) | 310 current_version = BuildVersion(options.build_dir) |
300 | 311 |
301 config = Readconfig(options.output_dir, options.input_file, current_version) | 312 config = Readconfig(options.build_dir, options.input_file, current_version) |
302 | 313 |
303 (staging_dir, temp_dir) = MakeStagingDirectories(options.output_dir) | 314 (staging_dir, temp_dir) = MakeStagingDirectories(options.staging_dir) |
304 | 315 |
305 prev_version = GetPrevVersion(options.output_dir, temp_dir, | 316 prev_version = GetPrevVersion(options.build_dir, temp_dir, |
306 options.last_chrome_installer) | 317 options.last_chrome_installer) |
307 | 318 |
308 CopyAllFilesToStagingDir(config, options.distribution, | 319 CopyAllFilesToStagingDir(config, options.distribution, |
309 staging_dir, options.output_dir) | 320 staging_dir, options.build_dir) |
310 | 321 |
311 version_numbers = current_version.split('.') | 322 version_numbers = current_version.split('.') |
312 current_build_number = version_numbers[2] + '.' + version_numbers[3] | 323 current_build_number = version_numbers[2] + '.' + version_numbers[3] |
313 prev_build_number = '' | 324 prev_build_number = '' |
314 if prev_version: | 325 if prev_version: |
315 version_numbers = prev_version.split('.') | 326 version_numbers = prev_version.split('.') |
316 prev_build_number = version_numbers[2] + '.' + version_numbers[3] | 327 prev_build_number = version_numbers[2] + '.' + version_numbers[3] |
317 | 328 |
318 # Name of the archive file built (for example - chrome.7z or | 329 # Name of the archive file built (for example - chrome.7z or |
319 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z | 330 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z |
320 archive_file = CreateArchiveFile(options, staging_dir, | 331 archive_file = CreateArchiveFile(options, staging_dir, |
321 current_build_number, prev_build_number) | 332 current_build_number, prev_build_number) |
322 | 333 |
323 setup_file = PrepareSetupExec(options, staging_dir, | 334 setup_file = PrepareSetupExec(options, staging_dir, |
324 current_build_number, prev_build_number) | 335 current_build_number, prev_build_number) |
325 | 336 |
326 CreateResourceInputFile(options.output_dir, options.setup_exe_format, | 337 CreateResourceInputFile(options.build_dir, options.setup_exe_format, |
327 archive_file, setup_file) | 338 archive_file, setup_file, options.resource_file_path) |
339 | |
340 def _ParseOptions(): | |
341 parser = optparse.OptionParser() | |
342 parser.add_option('-i', '--input_file', | |
343 help='Input file describing which files to archive.') | |
344 parser.add_option('-o', '--build_dir', | |
345 help='Build directory. The paths in input_file are relative to this.') | |
346 parser.add_option('--staging_dir', | |
347 help='Staging directory where intermediate files and directories ' | |
348 'will be created'), | |
349 parser.add_option('--resource_file_path', | |
350 help='The path where the resource file will be output. ' | |
351 'Defaults to %s in the build directory.' % | |
352 MINI_INSTALLER_INPUT_FILE), | |
353 parser.add_option('-d', '--distribution', | |
354 help='Name of Chromium Distribution. Optional.') | |
355 parser.add_option('-s', '--skip_rebuild_archive', | |
356 default="False", help='Skip re-building Chrome.7z archive if it exists.') | |
357 parser.add_option('-l', '--last_chrome_installer', | |
358 help='Generate differential installer. The value of this parameter ' | |
359 'specifies the directory that contains base versions of ' | |
360 'setup.exe, courgette.exe (if --diff_algorithm is COURGETTE) ' | |
361 '& chrome.7z.') | |
362 parser.add_option('-f', '--setup_exe_format', default='COMPRESSED', | |
363 help='How setup.exe should be included {COMPRESSED|DIFF|FULL}.') | |
364 parser.add_option('-a', '--diff_algorithm', default='BSDIFF', | |
365 help='Diff algorithm to use when generating differential patches ' | |
366 '{BSDIFF|COURGETTE}.') | |
367 parser.add_option('-n', '--output_name', default='chrome', | |
368 help='Name used to prefix names of generated archives.') | |
369 | |
370 options, args = parser.parse_args() | |
371 | |
372 if not options.build_dir: | |
373 parser.error('You must provide a build dir.') | |
374 | |
375 if not options.staging_dir: | |
376 parser.error('You must provide a staging dir.') | |
377 | |
378 if not options.resource_file_path: | |
379 options.options.resource_file_path = os.path.join(options.build_dir, | |
380 MINI_INSTALLER_INPUT_FILE) | |
381 | |
382 print sys.argv | |
383 return options | |
328 | 384 |
329 | 385 |
330 if '__main__' == __name__: | 386 if '__main__' == __name__: |
331 option_parser = optparse.OptionParser() | 387 sys.exit(main(_ParseOptions())) |
332 option_parser.add_option('-o', '--output_dir', help='Output directory') | |
333 option_parser.add_option('-i', '--input_file', help='Input file') | |
334 option_parser.add_option('-d', '--distribution', | |
335 help='Name of Chromium Distribution. Optional.') | |
336 option_parser.add_option('-s', '--skip_rebuild_archive', | |
337 default="False", help='Skip re-building Chrome.7z archive if it exists.') | |
338 option_parser.add_option('-l', '--last_chrome_installer', | |
339 help='Generate differential installer. The value of this parameter ' + | |
340 'specifies the directory that contains base versions of ' + | |
341 'setup.exe, courgette.exe (if --diff_algorithm is COURGETTE) ' + | |
342 '& chrome.7z.') | |
343 option_parser.add_option('-p', '--archive_prefix', | |
344 help='Specifies a prefix to the archive path. Useful if building ' + | |
345 'multiple installer archives.') | |
346 option_parser.add_option('-f', '--setup_exe_format', default='COMPRESSED', | |
347 help='How setup.exe should be included {COMPRESSED|DIFF|FULL}.') | |
348 option_parser.add_option('-a', '--diff_algorithm', default='BSDIFF', | |
349 help='Diff algorithm to use when generating differential patches ' + | |
350 '{BSDIFF|COURGETTE}.') | |
351 option_parser.add_option('-n', '--output_name', default='chrome', | |
352 help='Name used to prefix names of generated archives.') | |
353 | |
354 options, args = option_parser.parse_args() | |
355 print sys.argv | |
356 sys.exit(main(options)) | |
OLD | NEW |