| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/python2.4 | |
| 2 # | |
| 3 # Copyright 2005-2009 Google Inc. | |
| 4 # | |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 # you may not use this file except in compliance with the License. | |
| 7 # You may obtain a copy of the License at | |
| 8 # | |
| 9 # http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 # | |
| 11 # Unless required by applicable law or agreed to in writing, software | |
| 12 # distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 # See the License for the specific language governing permissions and | |
| 15 # limitations under the License. | |
| 16 # ======================================================================== | |
| 17 | |
| 18 """Creates application specific meta-installers. | |
| 19 | |
| 20 Run this script with the directory that contains the build files, | |
| 21 GoogleupdateSetup_<lang>.exe and pass it the file that contains the application | |
| 22 information to be stamped inside the binary. | |
| 23 | |
| 24 """ | |
| 25 | |
| 26 import codecs | |
| 27 import os | |
| 28 import sys | |
| 29 import re | |
| 30 import urllib | |
| 31 | |
| 32 class Bundle: | |
| 33 """Represents the information for a bundle""" | |
| 34 def __init__(self, exe_name, admin, language, | |
| 35 browser_type, stats, installers_txt_filename, applications): | |
| 36 self.applications = applications | |
| 37 self.name = exe_name | |
| 38 self.needs_admin = admin | |
| 39 self.lang = language | |
| 40 self.browser = browser_type | |
| 41 self.usage_stats = stats | |
| 42 self.installers_txt_filename = installers_txt_filename | |
| 43 self.output_file_name = "" | |
| 44 | |
| 45 def UrlEncodeString(name): | |
| 46 """Converts the name into utf8 encoded and then urlencodes it. | |
| 47 | |
| 48 Args: | |
| 49 name: The string to utf8 convert. | |
| 50 | |
| 51 Returns: | |
| 52 The utf8 converted urlencoded string. | |
| 53 """ | |
| 54 utf8_str = name.encode('utf8') | |
| 55 return urllib.quote(utf8_str) | |
| 56 | |
| 57 def ReadBundleInstallerFile(installers_txt_filename): | |
| 58 """Read the installation file and return a list of the values. | |
| 59 Only reads information from bundle installer files. The filename | |
| 60 should contain the "bundle" word. | |
| 61 Args: | |
| 62 installers_txt_filename: The file which contains application specific | |
| 63 values, of guid, name, exe_name, needs_admin and | |
| 64 language. | |
| 65 | |
| 66 Returns: | |
| 67 A dictionary of Bundles key=language, value=[Bundle] | |
| 68 """ | |
| 69 bundles = {} | |
| 70 installers_txt_file = codecs.open(installers_txt_filename, 'r', 'utf16') | |
| 71 for line in installers_txt_file.readlines(): | |
| 72 line = line.strip() | |
| 73 if len(line) and not line.startswith('#'): | |
| 74 (exe_name, needs_admin, language, browser, usage, bundle_apps) =\ | |
| 75 eval(line) | |
| 76 bundle = Bundle(exe_name, needs_admin, language, | |
| 77 browser, usage, | |
| 78 installers_txt_filename, bundle_apps) | |
| 79 if (not bundles.has_key(language)): | |
| 80 bundles[language] = [bundle] | |
| 81 else: | |
| 82 bundles[language] .append(bundle) | |
| 83 return bundles | |
| 84 | |
| 85 def BuildOutputDirectory(output_dir, lang, app): | |
| 86 """Returns the output directory for the app. | |
| 87 | |
| 88 Args: | |
| 89 app: The application for which to generate the path. | |
| 90 lang: The language of the applicaiton. | |
| 91 output_dir: The output directory. | |
| 92 | |
| 93 Returns: | |
| 94 The path of the output file. | |
| 95 """ | |
| 96 installers_txt_filename = app.installers_txt_filename | |
| 97 | |
| 98 end_idx = installers_txt_filename.find('_installers.txt') | |
| 99 app_dirname = installers_txt_filename[:end_idx] | |
| 100 | |
| 101 app_path = os.path.join(output_dir, app_dirname) | |
| 102 lang_path = os.path.join(app_path, lang) | |
| 103 return lang_path | |
| 104 | |
| 105 | |
| 106 def SetOutputFileNames(file_name, apps, output_dir): | |
| 107 """Sets the output file names inside the Application. | |
| 108 | |
| 109 Args: | |
| 110 file_name: The input file name that needs to be stamped. This | |
| 111 is used for deciding whether to use TEST in the name, | |
| 112 and the directory. The names of this file is expected | |
| 113 to be either TEST_GoogleUpdateSetup.exe or | |
| 114 GoogleUpdateSetup.exe | |
| 115 apps: Dictionary of applications keyed by language. | |
| 116 output_dir: The output directory. | |
| 117 | |
| 118 Returns: | |
| 119 All the applications for a particular language. | |
| 120 """ | |
| 121 | |
| 122 # Determine the language. | |
| 123 file = os.path.basename(file_name) | |
| 124 if file.startswith('TEST_'): | |
| 125 test = True | |
| 126 else: | |
| 127 test = False | |
| 128 | |
| 129 for (lang, apps_lang) in apps.iteritems(): | |
| 130 # Get the output filename and set it on the application. | |
| 131 for app in apps_lang: | |
| 132 output_path = BuildOutputDirectory(output_dir, lang, app) | |
| 133 path = os.path.join(output_path, GetOutputFileName(test, app.name, lang)) | |
| 134 app.output_file_name = path | |
| 135 | |
| 136 def GetOutputFileName(test, name, lang): | |
| 137 """Creates the output file name based on the language and the name of the app. | |
| 138 Args: | |
| 139 test: Whether the input file name starts with TEST. | |
| 140 name: The name of the application. I.e. Chrome, GoogleGears. | |
| 141 lang: The language of the installer. | |
| 142 Returns: | |
| 143 The output filename | |
| 144 """ | |
| 145 if test: | |
| 146 file_name = 'Tagged_TEST_%sSetup_%s.exe' % (name, lang) | |
| 147 else: | |
| 148 file_name = 'Tagged_%sSetup_%s.exe' % (name, lang) | |
| 149 return file_name | |
| 150 | |
| 151 def BuildTagStringForBundle(bundle): | |
| 152 """Builds the string to be tagged into the binary for a bundle. | |
| 153 Args: | |
| 154 bundle: Contains all information about a bundle. | |
| 155 Returns: | |
| 156 The string to be tagged into the installer. | |
| 157 """ | |
| 158 args = '\"' | |
| 159 first_app = True | |
| 160 for app in bundle.applications: | |
| 161 if not first_app: | |
| 162 args += '&' | |
| 163 first_app = False | |
| 164 (guid, name, ap) = app | |
| 165 display_name = UrlEncodeString(name) | |
| 166 args += 'appguid=%s&appname=%s&needsadmin=%s' % \ | |
| 167 (guid, display_name, bundle.needs_admin) | |
| 168 if ap: | |
| 169 args += '&ap=%s' % ap | |
| 170 | |
| 171 if bundle.usage_stats: | |
| 172 args += '&usagestats=%s' % bundle.usage_stats | |
| 173 if bundle.browser: | |
| 174 args += '&browser=%s' % bundle.browser | |
| 175 if bundle.lang: | |
| 176 args += '&lang=%s' % bundle.lang | |
| 177 args += '\"' | |
| 178 return args | |
| 179 | |
| 180 def TagOneFile(file, app, applytag_exe_name): | |
| 181 """Tags one file with the information contained inside the application. | |
| 182 Args: | |
| 183 file: The input file to be stamped. | |
| 184 app: Contains all the application data. | |
| 185 applytag_exe_name: The full path of applytag.exe. | |
| 186 """ | |
| 187 tag_string = BuildTagStringForBundle(app) | |
| 188 | |
| 189 output_path = app.output_file_name | |
| 190 if not os.path.exists(file): | |
| 191 print 'Could not find file %s required for creating %s' % \ | |
| 192 (file, output_path) | |
| 193 return False | |
| 194 | |
| 195 arguments = [applytag_exe_name, | |
| 196 file, | |
| 197 output_path, | |
| 198 tag_string | |
| 199 ] | |
| 200 print 'Building %s with tag %s' % (output_path, tag_string) | |
| 201 os.spawnv(os.P_WAIT, applytag_exe_name, arguments) | |
| 202 return True | |
| 203 | |
| 204 def GetAllSetupExeInDirectory(dir): | |
| 205 """Creates a number of application specific binaries for the | |
| 206 passed in binary. | |
| 207 Args: | |
| 208 dir: The input directory. | |
| 209 Returns: | |
| 210 A list of files that are match the regex: | |
| 211 TEST_GoogleUpdateSetup_.*.exe$|^GoogleUpdateSetup_.*.exe$ | |
| 212 """ | |
| 213 ret_files = [] | |
| 214 files = os.listdir(dir) | |
| 215 for file in files: | |
| 216 regex = re.compile('^TEST_GoogleUpdateSetup_.*.exe$|' | |
| 217 '^GoogleUpdateSetup_.*.exe$') | |
| 218 if not regex.match(file): | |
| 219 continue | |
| 220 ret_files.append(file) | |
| 221 return ret_files | |
| 222 | |
| 223 def TagBinary(apps, file, applytag_exe_name): | |
| 224 """Creates a number of application specific binaries for the | |
| 225 passed in binary. | |
| 226 Args: | |
| 227 apps: Dictionary of key=lang, value=[Application]. | |
| 228 file: The input file to be stamped. | |
| 229 applytag_exe_name: The full path to applytag_exe_name. | |
| 230 """ | |
| 231 if not apps: | |
| 232 return | |
| 233 for apps_lang in apps: | |
| 234 for app in apps[apps_lang]: | |
| 235 TagOneFile(file, app, applytag_exe_name) | |
| 236 | |
| 237 def PrintUsage(): | |
| 238 print '' | |
| 239 print 'Tool to stamp the Guid, Application name, needs admin into the' | |
| 240 print 'meta-installer.' | |
| 241 print 'Reads <installer file> which contains the application name,' | |
| 242 print 'guid, needs_admin and stamps the meta-installer <file> with' | |
| 243 print 'these values.' | |
| 244 print 'For an example of the <installer file> take a look at' | |
| 245 print '#/installers/googlegears_installer.txt' | |
| 246 print '' | |
| 247 print 'tag_meta_installers.py <applytag> <input file> <installer file>\ | |
| 248 <output file>' | |
| 249 | |
| 250 def main(): | |
| 251 if len(sys.argv) != 5: | |
| 252 PrintUsage() | |
| 253 return | |
| 254 | |
| 255 apply_tag_exe = sys.argv[1] | |
| 256 input_file = sys.argv[2] | |
| 257 file_name = sys.argv[3] | |
| 258 output_dir = sys.argv[4] | |
| 259 | |
| 260 if not os.path.exists(apply_tag_exe): | |
| 261 print "Could not find applytag.exe" | |
| 262 PrintUsage() | |
| 263 return | |
| 264 | |
| 265 if not os.path.exists(file_name): | |
| 266 print "Invalid filename %s" % file_name | |
| 267 PrintUsage() | |
| 268 return | |
| 269 | |
| 270 if not os.path.exists(input_file): | |
| 271 print "Invalid directory %s" % input_file | |
| 272 PrintUsage() | |
| 273 return | |
| 274 | |
| 275 if not os.path.exists(output_dir): | |
| 276 os.mkdir(output_dir) | |
| 277 | |
| 278 # Read in the installers.txt file. | |
| 279 apps = ReadBundleInstallerFile(file_name) | |
| 280 | |
| 281 SetOutputFileNames(input_file, apps, output_dir) | |
| 282 TagBinary(apps, input_file, apply_tag_exe) | |
| 283 | |
| 284 if __name__ == '__main__': | |
| 285 main() | |
| OLD | NEW |