Chromium Code Reviews| 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 |