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 |
17 import optparse | 18 import optparse |
18 import os | 19 import os |
19 import shutil | 20 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 """ |
38 PATCH_FILE_EXT = '.diff' | 49 PATCH_FILE_EXT = '.diff' |
39 SETUP_EXEC = "setup.exe" | 50 SETUP_EXEC = "setup.exe" |
40 SETUP_PATCH_FILE_PREFIX = "setup_patch" | 51 SETUP_PATCH_FILE_PREFIX = "setup_patch" |
41 TEMP_ARCHIVE_DIR = "temp_installer_archive" | 52 TEMP_ARCHIVE_DIR = "temp_installer_archive" |
42 VERSION_FILE = "VERSION" | 53 VERSION_FILE = "VERSION" |
43 | 54 |
44 | 55 def BuildVersion(output_dir): |
45 def BuildVersion(build_dir): | |
46 """Returns the full build version string constructed from information in | 56 """Returns the full build version string constructed from information in |
47 VERSION_FILE. Any segment not found in that file will default to '0'. | 57 VERSION_FILE. Any segment not found in that file will default to '0'. |
48 """ | 58 """ |
49 major = 0 | 59 major = 0 |
50 minor = 0 | 60 minor = 0 |
51 build = 0 | 61 build = 0 |
52 patch = 0 | 62 patch = 0 |
53 for line in open(os.path.join(build_dir, '../../chrome', VERSION_FILE), 'r'): | 63 for line in open(os.path.join(output_dir, "..", "..", "chrome", VERSION_FILE),
'r'): |
54 line = line.rstrip() | 64 line = line.rstrip() |
55 if line.startswith('MAJOR='): | 65 if line.startswith('MAJOR='): |
56 major = line[6:] | 66 major = line[6:] |
57 elif line.startswith('MINOR='): | 67 elif line.startswith('MINOR='): |
58 minor = line[6:] | 68 minor = line[6:] |
59 elif line.startswith('BUILD='): | 69 elif line.startswith('BUILD='): |
60 build = line[6:] | 70 build = line[6:] |
61 elif line.startswith('PATCH='): | 71 elif line.startswith('PATCH='): |
62 patch = line[6:] | 72 patch = line[6:] |
63 return '%s.%s.%s.%s' % (major, minor, build, patch) | 73 return '%s.%s.%s.%s' % (major, minor, build, patch) |
64 | 74 |
65 | 75 def CompressUsingLZMA(output_dir, compressed_file, input_file): |
66 def CompressUsingLZMA(build_dir, compressed_file, input_file): | 76 lzma_exec = GetLZMAExec(output_dir) |
67 lzma_exec = GetLZMAExec(build_dir) | 77 cmd = ('%s a -t7z ' |
68 cmd = [lzma_exec, | |
69 'a', '-t7z', | |
70 # Flags equivalent to -mx9 (ultra) but with the bcj2 turned on (exe | 78 # Flags equivalent to -mx9 (ultra) but with the bcj2 turned on (exe |
71 # pre-filter). This results in a ~2.3MB decrease in installer size on | 79 # pre-filter). This results in a ~2.3MB decrease in installer size on |
72 # a 24MB installer. | 80 # a 24MB installer. |
73 # Additionally, these settings reflect a 7zip 4.42 and up change in | 81 # Additionally, these settings reflect a 7zip 4.42 and up change in |
74 # the definition of -mx9, increasting the dicionary size moving to | 82 # the definition of -mx9, increasting the dicionary size moving to |
75 # 26bit = 64MB. This results in an additional ~3.5MB decrease. | 83 # 26bit = 64MB. This results in an additional ~3.5MB decrease. |
76 # Older 7zip versions can support these settings, as these changes | 84 # Older 7zip versions can support these settings, as these changes |
77 # rely on existing functionality in the lzma format. | 85 # rely on existing functionality in the lzma format. |
78 '-m0=BCJ2', | 86 '-m0=BCJ2 ' |
79 '-m1=LZMA:d26:fb64', | 87 '-m1=LZMA:d26:fb64 ' |
80 '-m2=LZMA:d20:fb64:mf=bt2', | 88 '-m2=LZMA:d20:fb64:mf=bt2 ' |
81 '-m3=LZMA:d20:fb64:mf=bt2', | 89 '-m3=LZMA:d20:fb64:mf=bt2 ' |
82 '-mb0:1', | 90 '-mb0:1 -mb0s1:2 ' |
83 '-mb0s1:2', | 91 '-mb0s2:3 ' |
84 '-mb0s2:3', | 92 '"%s" "%s"') % (lzma_exec, compressed_file, input_file) |
85 compressed_file, | |
86 input_file,] | |
87 if os.path.exists(compressed_file): | 93 if os.path.exists(compressed_file): |
88 os.remove(compressed_file) | 94 os.remove(compressed_file) |
89 RunSystemCommand(cmd) | 95 RunSystemCommand(cmd) |
90 | 96 |
91 | 97 def CopyAllFilesToStagingDir(config, distribution, staging_dir, output_dir): |
92 def CopyAllFilesToStagingDir(config, distribution, staging_dir, build_dir): | |
93 """Copies the files required for installer archive. | 98 """Copies the files required for installer archive. |
94 Copies all common files required for various distributions of Chromium and | 99 Copies all common files required for various distributions of Chromium and |
95 also files for the specific Chromium build specified by distribution. | 100 also files for the specific Chromium build specified by distribution. |
96 """ | 101 """ |
97 CopySectionFilesToStagingDir(config, 'GENERAL', staging_dir, build_dir) | 102 CopySectionFilesToStagingDir(config, 'GENERAL', staging_dir, output_dir) |
98 if distribution: | 103 if distribution: |
99 if len(distribution) > 1 and distribution[0] == '_': | 104 if len(distribution) > 1 and distribution[0] == '_': |
100 distribution = distribution[1:] | 105 distribution = distribution[1:] |
101 CopySectionFilesToStagingDir(config, distribution.upper(), | 106 CopySectionFilesToStagingDir(config, distribution.upper(), |
102 staging_dir, build_dir) | 107 staging_dir, output_dir) |
103 | 108 |
| 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 |
104 | 114 |
105 def CopySectionFilesToStagingDir(config, section, staging_dir, build_dir): | 115 def CopySectionFilesToStagingDir(config, section, staging_dir, output_dir): |
106 """Copies installer archive files specified in section to staging dir. | 116 """Copies installer archive files specified in section to staging dir. |
107 This method copies reads section from config file and copies all the files | 117 This method copies reads section from config file and copies all the files |
108 specified to staging dir. | 118 specified to staging dir. |
109 """ | 119 """ |
110 for option in config.options(section): | 120 for option in config.options(section): |
111 if option.endswith('dir'): | 121 if option.endswith('dir'): |
112 continue | 122 continue |
113 | 123 |
114 dst = os.path.join(staging_dir, config.get(section, option)) | 124 dst = os.path.join(staging_dir, config.get(section, option)) |
115 if not os.path.exists(dst): | 125 if not os.path.exists(dst): |
116 os.makedirs(dst) | 126 os.makedirs(dst) |
117 for file in glob.glob(os.path.join(build_dir, option)): | 127 for file in glob.glob(os.path.join(output_dir, option)): |
118 shutil.copy(file, dst) | 128 if IsChromeFrameFile(file): |
| 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) |
119 | 138 |
120 def GenerateDiffPatch(options, orig_file, new_file, patch_file): | 139 def GenerateDiffPatch(options, orig_file, new_file, patch_file): |
121 if (options.diff_algorithm == "COURGETTE"): | 140 if (options.diff_algorithm == "COURGETTE"): |
122 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) | 141 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) |
123 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) | 142 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) |
124 else: | 143 else: |
125 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC) | 144 exe_file = os.path.join(options.output_dir, BSDIFF_EXEC) |
126 cmd = [exe_file, orig_file, new_file, patch_file,] | 145 cmd = '%s "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) |
127 RunSystemCommand(cmd) | 146 RunSystemCommand(cmd) |
128 | 147 |
129 def GetLZMAExec(build_dir): | 148 def GetLZMAExec(output_dir): |
130 lzma_exec = os.path.join(build_dir, "..", "..", "third_party", | 149 lzma_exec = os.path.join(output_dir, "..", "..", "third_party", |
131 "lzma_sdk", "Executable", "7za.exe") | 150 "lzma_sdk", "Executable", "7za.exe") |
132 return lzma_exec | 151 return lzma_exec |
133 | 152 |
134 def GetPrevVersion(build_dir, temp_dir, last_chrome_installer): | 153 def GetPrevVersion(output_dir, temp_dir, last_chrome_installer): |
135 if not last_chrome_installer: | 154 if not last_chrome_installer: |
136 return '' | 155 return '' |
137 | 156 |
138 lzma_exec = GetLZMAExec(options.build_dir) | 157 lzma_exec = GetLZMAExec(options.output_dir) |
139 prev_archive_file = os.path.join(options.last_chrome_installer, | 158 prev_archive_file = os.path.join(options.last_chrome_installer, |
140 options.output_name + ARCHIVE_SUFFIX) | 159 options.output_name + ARCHIVE_SUFFIX) |
141 cmd = [lzma_exec, | 160 cmd = '%s x -o"%s" "%s" Chrome-bin/*/chrome.dll' % (lzma_exec, temp_dir, |
142 'x', | 161 prev_archive_file) |
143 '-o"%s"' % temp_dir, | |
144 prev_archive_file, | |
145 'Chrome-bin/*/chrome.dll',] | |
146 RunSystemCommand(cmd) | 162 RunSystemCommand(cmd) |
147 dll_path = glob.glob(os.path.join(temp_dir, 'Chrome-bin', '*', 'chrome.dll')) | 163 dll_path = glob.glob(os.path.join(temp_dir, 'Chrome-bin', '*', 'chrome.dll')) |
148 return os.path.split(os.path.split(dll_path[0])[0])[1] | 164 return os.path.split(os.path.split(dll_path[0])[0])[1] |
149 | 165 |
150 def MakeStagingDirectories(staging_dir): | 166 def MakeStagingDirectories(output_dir): |
151 """Creates a staging path for installer archive. If directory exists already, | 167 """Creates a staging path for installer archive. If directory exists already, |
152 deletes the existing directory. | 168 deletes the existing directory. |
153 """ | 169 """ |
154 file_path = os.path.join(staging_dir, TEMP_ARCHIVE_DIR) | 170 prefixed_archive_dir = (options.archive_prefix or "") + ARCHIVE_DIR |
| 171 file_path = os.path.join(output_dir, prefixed_archive_dir) |
155 if os.path.exists(file_path): | 172 if os.path.exists(file_path): |
156 shutil.rmtree(file_path) | 173 shutil.rmtree(file_path) |
157 os.makedirs(file_path) | 174 os.makedirs(file_path) |
158 | 175 |
159 temp_file_path = os.path.join(staging_dir, TEMP_ARCHIVE_DIR) | 176 prefixed_temp_archive_dir = (options.archive_prefix or "") + TEMP_ARCHIVE_DIR |
| 177 temp_file_path = os.path.join(output_dir, prefixed_temp_archive_dir) |
160 if os.path.exists(temp_file_path): | 178 if os.path.exists(temp_file_path): |
161 shutil.rmtree(temp_file_path) | 179 shutil.rmtree(temp_file_path) |
162 os.makedirs(temp_file_path) | 180 os.makedirs(temp_file_path) |
163 return (file_path, temp_file_path) | 181 return (file_path, temp_file_path) |
164 | 182 |
165 def Readconfig(build_dir, input_file, current_version): | 183 def Readconfig(output_dir, input_file, current_version): |
166 """Reads config information from input file after setting default value of | 184 """Reads config information from input file after setting default value of |
167 global variabes. | 185 global variabes. |
168 """ | 186 """ |
169 variables = {} | 187 variables = {} |
170 variables['ChromeDir'] = CHROME_DIR | 188 variables['ChromeDir'] = CHROME_DIR |
171 variables['VersionDir'] = os.path.join(variables['ChromeDir'], | 189 variables['VersionDir'] = os.path.join(variables['ChromeDir'], |
172 current_version) | 190 current_version) |
173 config = ConfigParser.SafeConfigParser(variables) | 191 config = ConfigParser.SafeConfigParser(variables) |
174 config.read(input_file) | 192 config.read(input_file) |
175 return config | 193 return config |
176 | 194 |
177 def RunSystemCommand(cmd): | 195 def RunSystemCommand(cmd): |
178 print 'Running', cmd | 196 print 'Running [' + cmd + ']' |
179 exit_code = subprocess.call(cmd) | 197 exit_code = os.system(cmd) |
180 if (exit_code != 0): | 198 if (exit_code != 0): |
181 raise Exception("Error while running cmd: %s, exit_code: %s" % | 199 raise Exception("Error while running cmd: %s, exit_code: %s" % |
182 (cmd, exit_code)) | 200 (cmd, exit_code)) |
183 | 201 |
184 def CreateArchiveFile(options, staging_dir, current_version, prev_version): | 202 def CreateArchiveFile(options, staging_dir, current_version, prev_version): |
185 """Creates a new installer archive file after deleting any existing old file. | 203 """Creates a new installer archive file after deleting any existing old file. |
186 """ | 204 """ |
187 # First create an uncompressed archive file for the current build (chrome.7z) | 205 # First create an uncompressed archive file for the current build (chrome.7z) |
188 lzma_exec = GetLZMAExec(options.build_dir) | 206 lzma_exec = GetLZMAExec(options.output_dir) |
189 archive_file = os.path.join(options.build_dir, | 207 archive_file = os.path.join(options.output_dir, |
190 options.output_name + ARCHIVE_SUFFIX) | 208 options.output_name + ARCHIVE_SUFFIX) |
191 cmd = [lzma_exec, | 209 cmd = '%s a -t7z "%s" "%s" -mx0' % (lzma_exec, archive_file, |
192 'a', | 210 os.path.join(staging_dir, CHROME_DIR)) |
193 '-t7z', | |
194 archive_file, | |
195 os.path.join(staging_dir, CHROME_DIR), | |
196 '-mx0',] | |
197 # There doesnt seem to be any way in 7za.exe to override existing file so | 211 # There doesnt seem to be any way in 7za.exe to override existing file so |
198 # we always delete before creating a new one. | 212 # we always delete before creating a new one. |
199 if not os.path.exists(archive_file): | 213 if not os.path.exists(archive_file): |
200 RunSystemCommand(cmd) | 214 RunSystemCommand(cmd) |
201 elif options.skip_rebuild_archive != "true": | 215 elif options.skip_rebuild_archive != "true": |
202 os.remove(archive_file) | 216 os.remove(archive_file) |
203 RunSystemCommand(cmd) | 217 RunSystemCommand(cmd) |
204 | 218 |
205 # If we are generating a patch, run bsdiff against previous build and | 219 # If we are generating a patch, run bsdiff against previous build and |
206 # compress the resulting patch file. If this is not a patch just compress the | 220 # compress the resulting patch file. If this is not a patch just compress the |
207 # uncompressed archive file. | 221 # uncompressed archive file. |
208 patch_name_prefix = options.output_name + CHROME_PATCH_FILE_SUFFIX | 222 patch_name_prefix = options.output_name + CHROME_PATCH_FILE_SUFFIX |
209 if options.last_chrome_installer: | 223 if options.last_chrome_installer: |
210 prev_archive_file = os.path.join(options.last_chrome_installer, | 224 prev_archive_file = os.path.join(options.last_chrome_installer, |
211 options.output_name + ARCHIVE_SUFFIX) | 225 options.output_name + ARCHIVE_SUFFIX) |
212 patch_file = os.path.join(options.build_dir, patch_name_prefix + | 226 patch_file = os.path.join(options.output_dir, patch_name_prefix + |
213 PATCH_FILE_EXT) | 227 PATCH_FILE_EXT) |
214 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) | 228 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) |
215 compressed_archive_file = patch_name_prefix + '_' + \ | 229 compressed_archive_file = patch_name_prefix + '_' + \ |
216 current_version + '_from_' + prev_version + \ | 230 current_version + '_from_' + prev_version + \ |
217 COMPRESSED_FILE_EXT | 231 COMPRESSED_FILE_EXT |
218 orig_file = patch_file | 232 orig_file = patch_file |
219 else: | 233 else: |
220 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX | 234 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX |
221 orig_file = archive_file | 235 orig_file = archive_file |
222 | 236 |
223 compressed_archive_file_path = os.path.join(options.build_dir, | 237 compressed_archive_file_path = os.path.join(options.output_dir, |
224 compressed_archive_file) | 238 compressed_archive_file) |
225 CompressUsingLZMA(options.build_dir, compressed_archive_file_path, orig_file) | 239 CompressUsingLZMA(options.output_dir, compressed_archive_file_path, orig_file) |
226 | 240 |
227 return compressed_archive_file | 241 return compressed_archive_file |
228 | 242 |
229 | 243 |
230 def PrepareSetupExec(options, staging_dir, current_version, prev_version): | 244 def PrepareSetupExec(options, staging_dir, current_version, prev_version): |
231 """Prepares setup.exe for bundling in mini_installer based on options.""" | 245 """Prepares setup.exe for bundling in mini_installer based on options.""" |
232 if options.setup_exe_format == "FULL": | 246 if options.setup_exe_format == "FULL": |
233 setup_file = SETUP_EXEC | 247 setup_file = SETUP_EXEC |
234 elif options.setup_exe_format == "DIFF": | 248 elif options.setup_exe_format == "DIFF": |
235 if not options.last_chrome_installer: | 249 if not options.last_chrome_installer: |
236 raise Exception( | 250 raise Exception( |
237 "To use DIFF for setup.exe, --last_chrome_installer is needed.") | 251 "To use DIFF for setup.exe, --last_chrome_installer is needed.") |
238 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) | 252 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) |
239 new_setup_file = os.path.join(options.build_dir, SETUP_EXEC) | 253 new_setup_file = os.path.join(options.output_dir, SETUP_EXEC) |
240 patch_file = os.path.join(options.build_dir, SETUP_PATCH_FILE_PREFIX + | 254 patch_file = os.path.join(options.output_dir, SETUP_PATCH_FILE_PREFIX + |
241 PATCH_FILE_EXT) | 255 PATCH_FILE_EXT) |
242 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) | 256 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) |
243 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ | 257 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ |
244 '_from_' + prev_version + COMPRESSED_FILE_EXT | 258 '_from_' + prev_version + COMPRESSED_FILE_EXT |
245 setup_file_path = os.path.join(options.build_dir, setup_file) | 259 setup_file_path = os.path.join(options.output_dir, setup_file) |
246 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file) | 260 CompressUsingLZMA(options.output_dir, setup_file_path, patch_file) |
247 else: | 261 else: |
248 cmd = ['makecab.exe', | 262 cmd = 'makecab.exe /D CompressionType=LZX /V1 /L "%s" "%s"' % ( |
249 '/D', 'CompressionType=LZX', | 263 options.output_dir, os.path.join(options.output_dir, SETUP_EXEC)) |
250 '/V1', | |
251 '/L', options.build_dir, | |
252 os.path.join(options.build_dir, SETUP_EXEC),] | |
253 RunSystemCommand(cmd) | 264 RunSystemCommand(cmd) |
254 setup_file = SETUP_EXEC[:-1] + "_" | 265 setup_file = SETUP_EXEC[:len(SETUP_EXEC) - 1] + "_" |
255 return setup_file | 266 return setup_file |
256 | 267 |
257 | 268 |
258 _RESOURCE_FILE_TEMPLATE = """ | 269 def CreateResourceInputFile(output_dir, setup_format, archive_file, setup_file): |
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): | |
279 """Creates resource input file (packed_files.txt) for mini_installer project. | 270 """Creates resource input file (packed_files.txt) for mini_installer project. |
280 | 271 |
281 This method checks the format of setup.exe being used and according sets | 272 This method checks the format of setup.exe being used and according sets |
282 its resource type. | 273 its resource type. |
283 """ | 274 """ |
284 setup_resource_type = "BL" | 275 setup_resource_type = "BL" |
285 if (setup_format == "FULL"): | 276 if (options.setup_exe_format == "FULL"): |
286 setup_resource_type = "BN" | 277 setup_resource_type = "BN" |
287 elif (setup_format == "DIFF"): | 278 elif (options.setup_exe_format == "DIFF"): |
288 setup_resource_type = "B7" | 279 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("\\","/")) |
289 | 282 |
290 # Expand the resource file template. | 283 archive_file_entry = "\n%s\t\tB7\n\"%s\"\n" % (archive_file, |
291 args = { | 284 os.path.join(output_dir, archive_file).replace("\\","/")) |
292 'setup_file': setup_file, | 285 output_file = os.path.join(output_dir, MINI_INSTALLER_INPUT_FILE) |
293 'setup_file_resource_type': setup_resource_type, | 286 f = open(output_file, 'w') |
294 'setup_file_path': | 287 try: |
295 os.path.join(build_dir, setup_file).replace("\\","/"), | 288 f.write(PACKED_FILE_COMMENTS) |
296 'archive_file': archive_file, | 289 f.write(setup_file_entry) |
297 'archive_file_path': | 290 f.write(archive_file_entry) |
298 os.path.join(build_dir, archive_file).replace("\\","/"), | 291 finally: |
299 } | 292 f.close() |
300 resource_file = _RESOURCE_FILE_TEMPLATE % args | |
301 | |
302 with open(resource_file_path, 'w') as f: | |
303 f.write(resource_file) | |
304 | 293 |
305 | 294 |
306 def main(options): | 295 def main(options): |
307 """Main method that reads input file, creates archive file and write | 296 """Main method that reads input file, creates archive file and write |
308 resource input file. | 297 resource input file. |
309 """ | 298 """ |
310 current_version = BuildVersion(options.build_dir) | 299 current_version = BuildVersion(options.output_dir) |
311 | 300 |
312 config = Readconfig(options.build_dir, options.input_file, current_version) | 301 config = Readconfig(options.output_dir, options.input_file, current_version) |
313 | 302 |
314 (staging_dir, temp_dir) = MakeStagingDirectories(options.staging_dir) | 303 (staging_dir, temp_dir) = MakeStagingDirectories(options.output_dir) |
315 | 304 |
316 prev_version = GetPrevVersion(options.build_dir, temp_dir, | 305 prev_version = GetPrevVersion(options.output_dir, temp_dir, |
317 options.last_chrome_installer) | 306 options.last_chrome_installer) |
318 | 307 |
319 CopyAllFilesToStagingDir(config, options.distribution, | 308 CopyAllFilesToStagingDir(config, options.distribution, |
320 staging_dir, options.build_dir) | 309 staging_dir, options.output_dir) |
321 | 310 |
322 version_numbers = current_version.split('.') | 311 version_numbers = current_version.split('.') |
323 current_build_number = version_numbers[2] + '.' + version_numbers[3] | 312 current_build_number = version_numbers[2] + '.' + version_numbers[3] |
324 prev_build_number = '' | 313 prev_build_number = '' |
325 if prev_version: | 314 if prev_version: |
326 version_numbers = prev_version.split('.') | 315 version_numbers = prev_version.split('.') |
327 prev_build_number = version_numbers[2] + '.' + version_numbers[3] | 316 prev_build_number = version_numbers[2] + '.' + version_numbers[3] |
328 | 317 |
329 # Name of the archive file built (for example - chrome.7z or | 318 # Name of the archive file built (for example - chrome.7z or |
330 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z | 319 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z |
331 archive_file = CreateArchiveFile(options, staging_dir, | 320 archive_file = CreateArchiveFile(options, staging_dir, |
332 current_build_number, prev_build_number) | 321 current_build_number, prev_build_number) |
333 | 322 |
334 setup_file = PrepareSetupExec(options, staging_dir, | 323 setup_file = PrepareSetupExec(options, staging_dir, |
335 current_build_number, prev_build_number) | 324 current_build_number, prev_build_number) |
336 | 325 |
337 CreateResourceInputFile(options.build_dir, options.setup_exe_format, | 326 CreateResourceInputFile(options.output_dir, options.setup_exe_format, |
338 archive_file, setup_file, options.resource_file_path) | 327 archive_file, setup_file) |
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 | |
384 | 328 |
385 | 329 |
386 if '__main__' == __name__: | 330 if '__main__' == __name__: |
387 sys.exit(main(_ParseOptions())) | 331 option_parser = optparse.OptionParser() |
| 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 |