Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Takes the output of the build step and turns it into a compressed | 6 """Takes the output of the build step and turns it into a compressed |
| 7 archive ready for distribution. | 7 archive ready for distribution. |
| 8 | 8 |
| 9 This script assumes the build script has been run to compile the add-in. | 9 This script assumes the build script has been run to compile the add-in. |
| 10 It zips up all files required for the add-in installation and places the | 10 It zips up all files required for the add-in installation and places the |
| 11 result in out/vs_addin/vs_addin.tgz. | 11 result in out/vs_addin/vs_addin.tgz. |
| 12 """ | 12 """ |
| 13 from __future__ import print_function | |
| 13 | 14 |
| 14 import os | 15 import os |
| 15 import re | 16 import re |
| 16 import fileinput | 17 import fileinput |
| 17 import win32api | 18 import win32api |
| 18 import shutil | 19 import shutil |
| 19 import tarfile | 20 import tarfile |
| 20 import zipfile | 21 import zipfile |
| 21 import string | 22 import string |
| 22 import sys | 23 import sys |
| 23 from os.path import join | 24 from os.path import join |
| 24 | 25 |
| 25 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | 26 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 26 | 27 |
| 27 # Checkout root | 28 # Checkout root |
| 28 ROOT = os.path.dirname(os.path.dirname(SCRIPT_DIR)) | 29 ROOT = os.path.dirname(os.path.dirname(SCRIPT_DIR)) |
| 29 | 30 |
| 30 # Root output directory. | 31 # Root output directory. |
| 31 BUILD_DIR = join(ROOT, 'out', 'vs_addin') | 32 BUILD_DIR = join(ROOT, 'out', 'vs_addin') |
| 33 STAGING_DIR = join(BUILD_DIR, 'staging') | |
| 32 | 34 |
| 33 # Directory that contains the build assemblies. | 35 # Directory that contains the build assemblies. |
| 34 ASSEMBLY_DIRECTORY_2010 = join(BUILD_DIR, '2010', 'Debug') | 36 ASSEMBLY_DIRECTORY_2010 = join(BUILD_DIR, '2010', 'Debug') |
| 35 ASSEMBLY_DIRECTORY_2012 = join(BUILD_DIR, '2012', 'Debug') | 37 ASSEMBLY_DIRECTORY_2012 = join(BUILD_DIR, '2012', 'Debug') |
| 36 | 38 |
| 37 # Directory containing static installer resources. | 39 # Directory containing static installer resources. |
| 38 RESOURCE_DIRECTORY = join(SCRIPT_DIR, 'InstallerResources') | 40 RESOURCE_DIRECTORY = join(SCRIPT_DIR, 'InstallerResources') |
| 39 | 41 |
| 40 # Base name of the final zip file. | 42 # Base name of the final zip file. |
| 41 OUTPUT_NAME = join(BUILD_DIR, 'vs_addin.tgz') | 43 OUTPUT_NAME = join(BUILD_DIR, 'vs_addin.tgz') |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 68 | 70 |
| 69 # List of source/destination pairs to include in archive file. | 71 # List of source/destination pairs to include in archive file. |
| 70 FILE_LIST = [ | 72 FILE_LIST = [ |
| 71 (ADDIN_ASSEMBLY_2010, '2010'), | 73 (ADDIN_ASSEMBLY_2010, '2010'), |
| 72 (ADDIN_ASSEMBLY_2012, '2012'), | 74 (ADDIN_ASSEMBLY_2012, '2012'), |
| 73 (join(ASSEMBLY_DIRECTORY_2010, 'NativeClientVSAddIn.AddIn'), '2010'), | 75 (join(ASSEMBLY_DIRECTORY_2010, 'NativeClientVSAddIn.AddIn'), '2010'), |
| 74 (join(ASSEMBLY_DIRECTORY_2012, 'NativeClientVSAddIn.AddIn'), '2012'), | 76 (join(ASSEMBLY_DIRECTORY_2012, 'NativeClientVSAddIn.AddIn'), '2012'), |
| 75 (join(ASSEMBLY_DIRECTORY_2010, 'NaCl.Build.CPPTasks.dll'), 'NaCl')] | 77 (join(ASSEMBLY_DIRECTORY_2010, 'NaCl.Build.CPPTasks.dll'), 'NaCl')] |
| 76 | 78 |
| 77 | 79 |
| 78 def AddFolderToArchive(path, archive, root=""): | 80 def MakeDir(dirname): |
| 79 """Adds an entire folder and sub folders to an open archive object. | 81 """Create a directory if it doesn't already exist.""" |
| 82 if not os.path.isdir(dirname): | |
| 83 os.makedirs(dirname) | |
| 84 | |
| 85 | |
| 86 def StageDirectory(dir_to_copy): | |
| 87 """Recursively add a directory to the staging directory. | |
| 88 | |
| 89 Args: | |
| 90 dir_to_copy: Directory to add. | |
| 91 basedir: The directory with the staging direcotry. | |
| 92 """ | |
| 93 for root, _, files in os.walk(dir_to_copy): | |
| 94 for filename in files: | |
| 95 src_path = join(root, filename) | |
| 96 | |
| 97 # If the file path matches an exclude, don't include it. | |
| 98 if any(re.search(expr, src_path) for expr in EXCLUDES): | |
| 99 continue | |
| 100 | |
| 101 relative_root = os.path.relpath(root, dir_to_copy) | |
| 102 dest_path = join(STAGING_DIR, relative_root, filename) | |
| 103 | |
| 104 MakeDir(os.path.dirname(dest_path)) | |
| 105 assert(not os.path.exists(dest_path)) | |
| 106 shutil.copy(src_path, dest_path) | |
| 107 | |
| 108 | |
| 109 def AddFolderToArchive(path, archive): | |
| 110 """Recursively adds a direcotry to an open archive object. | |
|
binji
2014/09/24 17:41:58
sp: directory (below too)
| |
| 80 | 111 |
| 81 The archive must already be open and it is not closed by this function. | 112 The archive must already be open and it is not closed by this function. |
| 82 | 113 |
| 83 Args: | 114 Args: |
| 84 path: Folder to add. | 115 path: Direcotory to add. |
| 85 archive: Already open archive file. | 116 archive: Open archive file. |
| 86 | |
| 87 Returns: | |
| 88 Nothing. | |
| 89 """ | 117 """ |
| 90 # Ensure the path ends in trailing slash. | 118 for root, _, files in os.walk(path): |
| 91 path = path.rstrip("/\\") + "\\" | |
| 92 for dir_path, dir_names, files in os.walk(path): | |
| 93 for filename in files: | 119 for filename in files: |
| 94 read_path = join(dir_path, filename) | 120 src_path = join(root, filename) |
| 95 | 121 archive_dir = os.path.join('vs_addin', os.path.relpath(root, path)) |
| 96 # If the file path matches an exclude, don't include it. | 122 archive_name = join(archive_dir, filename) |
| 97 if any(re.search(expr, read_path) for expr in EXCLUDES): | 123 print('Archiving: %s' % archive_name) |
| 98 continue | 124 archive.add(src_path, archive_name) |
| 99 | |
| 100 zip_based_dir = dir_path[len(path):] | |
| 101 write_path = join(root, zip_based_dir, filename) | |
| 102 WriteFileToArchive(archive, read_path, write_path) | |
| 103 | 125 |
| 104 | 126 |
| 105 def CopyAddinFile(assembly, path, vs_version): | 127 def CopyAddinFile(assembly, path, vs_version): |
| 106 """Copy the .AddIn file to the given path while making the necessary | 128 """Copy the .AddIn file to the given path while making the necessary |
| 107 replacements. | 129 replacements. |
| 108 | 130 |
| 109 The version number is obtained from the NativeClientAddIn.dll assembly which | 131 The version number is obtained from the NativeClientAddIn.dll assembly which |
| 110 is built during the build process. | 132 is built during the build process. |
| 111 """ | 133 """ |
| 112 infopath = '\\VarFileInfo\\Translation' | 134 infopath = '\\VarFileInfo\\Translation' |
| 113 pairs = win32api.GetFileVersionInfo(assembly, infopath) | 135 pairs = win32api.GetFileVersionInfo(assembly, infopath) |
| 114 lang, codepage = pairs[0] | 136 lang, codepage = pairs[0] |
| 115 infopath = u'\\StringFileInfo\\%04X%04X\\ProductVersion' % (lang, codepage) | 137 infopath = u'\\StringFileInfo\\%04X%04X\\ProductVersion' % (lang, codepage) |
| 116 prodVersion = win32api.GetFileVersionInfo(assembly, infopath) | 138 prodVersion = win32api.GetFileVersionInfo(assembly, infopath) |
| 117 version = "[%s]" % prodVersion | 139 version = '[%s]' % prodVersion |
| 118 print "\nNaCl VS Add-in Build version: %s\n" % (version) | 140 print('NaCl VS Add-in %s version: %s' % (vs_version, version)) |
| 119 | 141 |
| 120 metadata_filename = os.path.basename(ADDIN_METADATA) | 142 metadata_filename = os.path.basename(ADDIN_METADATA) |
| 121 modified_file = join(path, metadata_filename) | 143 modified_file = join(path, metadata_filename) |
| 122 | 144 |
| 123 # Copy the metadata file to new location and modify the version info. | 145 # Copy the metadata file to new location and modify the version info. |
| 124 with open(ADDIN_METADATA, 'r') as source_file: | 146 with open(ADDIN_METADATA, 'r') as source_file: |
| 125 with open(modified_file, 'w') as dest_file: | 147 with open(modified_file, 'w') as dest_file: |
| 126 data = source_file.read() | 148 data = source_file.read() |
| 127 replacements = {'VS_VERSION': vs_version, 'ADDIN_VERSION': version} | 149 replacements = {'VS_VERSION': vs_version, 'ADDIN_VERSION': version} |
| 128 data = string.Template(data).substitute(replacements) | 150 data = string.Template(data).substitute(replacements) |
| 129 dest_file.write(data) | 151 dest_file.write(data) |
| 130 | 152 |
| 131 | 153 |
| 132 def Error(msg): | 154 def Error(msg): |
| 133 sys.stderr.write(msg + '\n') | 155 sys.stderr.write(msg + '\n') |
| 134 sys.exit(1) | 156 sys.exit(1) |
| 135 | 157 |
| 136 | 158 |
| 137 def WriteFileToArchive(archive, filename, archive_name): | |
| 138 archive_name = join('vs_addin', archive_name) | |
| 139 if archive_name.replace('\\', '/') in archive.getnames(): | |
| 140 print 'Skipping: %s' % archive_name | |
| 141 return | |
| 142 print 'Adding: %s' % archive_name | |
| 143 archive.add(filename, archive_name) | |
| 144 | |
| 145 | |
| 146 def CopyWithReplacement(src, dest, replacements): | 159 def CopyWithReplacement(src, dest, replacements): |
| 147 if os.path.exists(dest): | 160 MakeDir(dest) |
| 148 shutil.rmtree(dest) | |
| 149 os.makedirs(dest) | |
| 150 src_basename = os.path.basename(src) | 161 src_basename = os.path.basename(src) |
| 151 dest_basename = os.path.basename(dest) | 162 dest_basename = os.path.basename(dest) |
| 152 | 163 |
| 153 olddir = os.getcwd() | 164 olddir = os.getcwd() |
| 154 try: | 165 try: |
| 155 os.chdir(src) | 166 os.chdir(src) |
| 156 for root, dirs, filenames in os.walk('.'): | 167 for root, dirs, filenames in os.walk('.'): |
| 157 for filename in filenames: | 168 for filename in filenames: |
| 158 srcfile = join(root, filename) | 169 srcfile = join(root, filename) |
| 159 # skip non-files, in particular .svn folders. | 170 # skip non-files, in particular .svn folders. |
| 160 if not os.path.isfile(srcfile): | 171 if not os.path.isfile(srcfile): |
| 161 continue | 172 continue |
| 162 | 173 |
| 163 destdir = join(dest, root.replace(src_basename, dest_basename)) | 174 destdir = join(dest, root.replace(src_basename, dest_basename)) |
| 164 if not os.path.exists(destdir): | 175 destdir = os.path.normpath(destdir) |
| 165 os.makedirs(destdir) | 176 MakeDir(destdir) |
| 166 | 177 |
| 167 destfile = join(destdir, filename.replace(src_basename, dest_basename)) | 178 destfile = join(destdir, filename.replace(src_basename, dest_basename)) |
| 179 if os.path.exists(destfile): | |
| 180 print('Skipping: %s' % destfile) | |
| 181 continue | |
| 182 | |
| 168 with open(srcfile, "rb") as f: | 183 with open(srcfile, "rb") as f: |
| 169 data = f.read() | 184 data = f.read() |
| 170 for pat, subst in replacements.iteritems(): | 185 for pat, subst in replacements.iteritems(): |
| 171 data = data.replace(pat, subst) | 186 data = data.replace(pat, subst) |
| 187 | |
| 172 with open(destfile, "wb") as f: | 188 with open(destfile, "wb") as f: |
| 173 f.write(data) | 189 f.write(data) |
| 174 finally: | 190 finally: |
| 175 os.chdir(olddir) | 191 os.chdir(olddir) |
| 176 | 192 |
| 177 | 193 |
| 178 def main(): | 194 def main(args): |
| 179 if not os.path.exists(BUILD_DIR): | 195 if not os.path.exists(BUILD_DIR): |
| 180 Error("build dir not found: %s" % BUILD_DIR) | 196 Error("build dir not found: %s" % BUILD_DIR) |
| 181 | 197 |
| 182 CopyAddinFile(ADDIN_ASSEMBLY_2010, ASSEMBLY_DIRECTORY_2010, '10.0') | 198 CopyAddinFile(ADDIN_ASSEMBLY_2010, ASSEMBLY_DIRECTORY_2010, '10.0') |
| 183 CopyAddinFile(ADDIN_ASSEMBLY_2012, ASSEMBLY_DIRECTORY_2012, '11.0') | 199 CopyAddinFile(ADDIN_ASSEMBLY_2012, ASSEMBLY_DIRECTORY_2012, '11.0') |
| 184 | 200 |
| 185 archive = tarfile.open(OUTPUT_NAME, 'w:gz') | 201 print("Staging package in %s" % STAGING_DIR) |
| 202 if os.path.exists(STAGING_DIR): | |
| 203 shutil.rmtree(STAGING_DIR) | |
| 186 | 204 |
| 187 for source_dest in FILE_LIST: | 205 # Start by staging the entire resource tree |
| 188 file_name = os.path.basename(source_dest[0]) | 206 StageDirectory(RESOURCE_DIRECTORY) |
| 189 dest = join(source_dest[1], file_name) | |
| 190 WriteFileToArchive(archive, source_dest[0], dest) | |
| 191 | 207 |
| 192 AddFolderToArchive(RESOURCE_DIRECTORY, archive) | 208 # Then stage anything in the FILE_LIST |
| 209 for source, dest in FILE_LIST: | |
| 210 file_name = os.path.basename(source) | |
| 211 dest = join(STAGING_DIR, dest, file_name) | |
| 212 assert(not os.path.exists(dest)) | |
| 213 MakeDir(os.path.dirname(dest)) | |
| 214 shutil.copy(source, dest) | |
| 193 | 215 |
| 194 # Duplicate the NaCl64 platform but rename it to NaCl32 | 216 # Duplicate the NaCl64 platform but rename it to NaCl32 |
| 195 src = join(RESOURCE_DIRECTORY, 'NaCl64') | 217 src = join(RESOURCE_DIRECTORY, 'NaCl64') |
| 196 | 218 |
| 197 # Create NaCl32 | 219 # Create NaCl32 |
| 198 dest = join(BUILD_DIR, 'NaCl32') | 220 dest = join(STAGING_DIR, 'NaCl32') |
| 199 CopyWithReplacement(src, dest, {'x86_64': 'i686', '64': '32'}) | 221 CopyWithReplacement(src, dest, {'x86_64': 'i686', '64': '32'}) |
| 200 AddFolderToArchive(dest, archive, "NaCl32") | |
| 201 | 222 |
| 202 # Create NaClARM | 223 # Create NaClARM |
| 203 arm_replacements = { | 224 arm_replacements = { |
| 204 'x86_64': 'arm', | 225 'x86_64': 'arm', |
| 205 '64': 'arm', | 226 '64': 'arm', |
| 206 'win_x86': 'win_arm' | 227 'win_x86': 'win_arm' |
| 207 } | 228 } |
| 208 | 229 |
| 209 dest = join(BUILD_DIR, 'NaClARM') | 230 dest = join(STAGING_DIR, 'NaClARM') |
| 210 CopyWithReplacement(src, dest, arm_replacements) | 231 CopyWithReplacement(src, dest, arm_replacements) |
| 211 AddFolderToArchive(dest, archive, "NaClARM") | |
| 212 | 232 |
| 213 # Create PNaCl | 233 # Create PNaCl |
| 214 pnacl_replacements = { | 234 pnacl_replacements = { |
| 215 'NaCl64': 'PNaCl', | 235 'NaCl64': 'PNaCl', |
| 216 'x86_64': 'pnacl', | 236 'x86_64': 'pnacl', |
| 217 '64': '32', | 237 '64': '32', |
| 218 '.nexe': '.pexe', | 238 '.nexe': '.pexe', |
| 219 'nacl_link.xml': 'pnacl_link.xml', | 239 'nacl_link.xml': 'pnacl_link.xml', |
| 220 '$(ProjectName)_$(PlatformArchitecture)': '$(ProjectName)', | 240 '$(ProjectName)_$(PlatformArchitecture)': '$(ProjectName)', |
| 221 } | 241 } |
| 222 | 242 |
| 223 dest = join(BUILD_DIR, 'PNaCl') | 243 dest = join(STAGING_DIR, 'PNaCl') |
| 224 CopyWithReplacement(src, dest, pnacl_replacements) | 244 CopyWithReplacement(src, dest, pnacl_replacements) |
| 225 AddFolderToArchive(dest, archive, "PNaCl") | |
| 226 | 245 |
| 246 # Create archive | |
| 247 archive = tarfile.open(OUTPUT_NAME, 'w:gz') | |
| 248 AddFolderToArchive(STAGING_DIR, archive) | |
| 227 archive.close() | 249 archive.close() |
| 250 return 0 | |
| 228 | 251 |
| 229 | 252 |
| 230 if __name__ == '__main__': | 253 if __name__ == '__main__': |
| 231 main() | 254 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |