| 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 """Creates a directory with with the unpacked contents of the remoting webapp. | 6 """Creates a directory with with the unpacked contents of the remoting webapp. |
| 7 | 7 |
| 8 The directory will contain a copy-of or a link-to to all remoting webapp | 8 The directory will contain a copy-of or a link-to to all remoting webapp |
| 9 resources. This includes HTML/JS and any plugin binaries. The script also | 9 resources. This includes HTML/JS and any plugin binaries. The script also |
| 10 massages resulting files appropriately with host plugin data. Finally, | 10 massages resulting files appropriately with host plugin data. Finally, |
| 11 a zip archive for all of the above is produced. | 11 a zip archive for all of the above is produced. |
| 12 """ | 12 """ |
| 13 | 13 |
| 14 # Python 2.5 compatibility | 14 # Python 2.5 compatibility |
| 15 from __future__ import with_statement | 15 from __future__ import with_statement |
| 16 | 16 |
| 17 import argparse |
| 17 import io | 18 import io |
| 18 import os | 19 import os |
| 19 import platform | 20 import platform |
| 20 import re | 21 import re |
| 21 import shutil | 22 import shutil |
| 22 import subprocess | 23 import subprocess |
| 23 import sys | 24 import sys |
| 24 import time | 25 import time |
| 25 import zipfile | 26 import zipfile |
| 26 | 27 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 55 rel_path = os.path.relpath(full_path, directory) | 56 rel_path = os.path.relpath(full_path, directory) |
| 56 zip.write(full_path, os.path.join(zipfile_base, rel_path)) | 57 zip.write(full_path, os.path.join(zipfile_base, rel_path)) |
| 57 zip.close() | 58 zip.close() |
| 58 | 59 |
| 59 | 60 |
| 60 def replaceString(destination, placeholder, value): | 61 def replaceString(destination, placeholder, value): |
| 61 findAndReplace(os.path.join(destination, 'plugin_settings.js'), | 62 findAndReplace(os.path.join(destination, 'plugin_settings.js'), |
| 62 "'" + placeholder + "'", "'" + value + "'") | 63 "'" + placeholder + "'", "'" + value + "'") |
| 63 | 64 |
| 64 | 65 |
| 66 def replaceBool(destination, placeholder, value): |
| 67 # Look for a "!!" in the source code so the expession we're |
| 68 # replacing looks like a boolean to the compiler. A single "!" |
| 69 # would satisfy the compiler but might confused human readers. |
| 70 findAndReplace(os.path.join(destination, 'plugin_settings.js'), |
| 71 "!!'" + placeholder + "'", 'true' if value else 'false') |
| 72 |
| 73 |
| 74 def parseBool(boolStr): |
| 75 """Tries to parse a string as a boolean value. |
| 76 |
| 77 Returns a bool on success; raises ValueError on failure. |
| 78 """ |
| 79 lower = boolStr.tolower() |
| 80 if lower in ['0', 'false']: return False |
| 81 if lower in ['1', 'true']: return True |
| 82 raise ValueError('not a boolean string {!r}'.format(boolStr)) |
| 83 |
| 84 |
| 85 def getenvBool(name, defaultValue): |
| 86 """Gets an environment value as a boolean.""" |
| 87 rawValue = os.environ.get(name) |
| 88 if rawValue is None: |
| 89 return defaultValue |
| 90 try: |
| 91 return parseBool(rawValue) |
| 92 except ValueError: |
| 93 raise Exception('Value of ${} must be boolean!'.format(name)) |
| 94 |
| 95 |
| 65 def processJinjaTemplate(input_file, include_paths, output_file, context): | 96 def processJinjaTemplate(input_file, include_paths, output_file, context): |
| 66 jinja2_path = os.path.normpath( | 97 jinja2_path = os.path.normpath( |
| 67 os.path.join(os.path.abspath(__file__), | 98 os.path.join(os.path.abspath(__file__), |
| 68 '../../../third_party/jinja2')) | 99 '../../../third_party/jinja2')) |
| 69 sys.path.append(os.path.split(jinja2_path)[0]) | 100 sys.path.append(os.path.split(jinja2_path)[0]) |
| 70 import jinja2 | 101 import jinja2 |
| 71 (template_path, template_name) = os.path.split(input_file) | 102 (template_path, template_name) = os.path.split(input_file) |
| 72 include_paths = [template_path] + include_paths | 103 include_paths = [template_path] + include_paths |
| 73 env = jinja2.Environment(loader=jinja2.FileSystemLoader(include_paths)) | 104 env = jinja2.Environment(loader=jinja2.FileSystemLoader(include_paths)) |
| 74 template = env.get_template(template_name) | 105 template = env.get_template(template_name) |
| 75 rendered = template.render(context) | 106 rendered = template.render(context) |
| 76 io.open(output_file, 'w', encoding='utf-8').write(rendered) | 107 io.open(output_file, 'w', encoding='utf-8').write(rendered) |
| 77 | 108 |
| 78 def buildWebApp(buildtype, version, destination, zip_path, | 109 def buildWebApp(buildtype, version, destination, zip_path, |
| 79 manifest_template, webapp_type, app_id, app_name, | 110 manifest_template, webapp_type, appid, app_name, |
| 80 app_description, app_capabilities, files, locales, jinja_paths, | 111 app_description, app_capabilities, files, locales_listfile, |
| 81 service_environment): | 112 jinja_paths, service_environment, use_gcd): |
| 82 """Does the main work of building the webapp directory and zipfile. | 113 """Does the main work of building the webapp directory and zipfile. |
| 83 | 114 |
| 84 Args: | 115 Args: |
| 85 buildtype: the type of build ("Official", "Release" or "Dev"). | 116 buildtype: the type of build ("Official", "Release" or "Dev"). |
| 86 destination: A string with path to directory where the webapp will be | 117 destination: A string with path to directory where the webapp will be |
| 87 written. | 118 written. |
| 88 zipfile: A string with path to the zipfile to create containing the | 119 zipfile: A string with path to the zipfile to create containing the |
| 89 contents of |destination|. | 120 contents of |destination|. |
| 90 manifest_template: jinja2 template file for manifest. | 121 manifest_template: jinja2 template file for manifest. |
| 91 webapp_type: webapp type ("v1", "v2", "v2_pnacl" or "app_remoting"). | 122 webapp_type: webapp type ("v1", "v2", "v2_pnacl" or "app_remoting"). |
| 92 app_id: A string with the Remoting Application Id (only used for app | 123 appid: A string with the Remoting Application Id (only used for app |
| 93 remoting webapps). If supplied, it defaults to using the | 124 remoting webapps). If supplied, it defaults to using the |
| 94 test API server. | 125 test API server. |
| 95 app_name: A string with the name of the application. | 126 app_name: A string with the name of the application. |
| 96 app_description: A string with the description of the application. | 127 app_description: A string with the description of the application. |
| 97 app_capabilities: A set of strings naming the capabilities that should be | 128 app_capabilities: A set of strings naming the capabilities that should be |
| 98 enabled for this application. | 129 enabled for this application. |
| 99 files: An array of strings listing the paths for resources to include | 130 files: An array of strings listing the paths for resources to include |
| 100 in this webapp. | 131 in this webapp. |
| 101 locales: An array of strings listing locales, which are copied, along | 132 locales_listfile: The name of a file containing a list of locales, one per |
| 102 with their directory structure from the _locales directory down. | 133 line, which are copied, along with their directory structure, from |
| 134 the _locales directory down. |
| 103 jinja_paths: An array of paths to search for {%include} directives in | 135 jinja_paths: An array of paths to search for {%include} directives in |
| 104 addition to the directory containing the manifest template. | 136 addition to the directory containing the manifest template. |
| 105 service_environment: Used to point the webApp to one of the | 137 service_environment: Used to point the webApp to one of the |
| 106 dev/test/staging/prod environments | 138 dev/test/staging/prod environments |
| 139 use_gcd: True if GCD support should be enabled. |
| 107 """ | 140 """ |
| 141 |
| 142 # Load the locales files from the locales_listfile. |
| 143 if not locales_listfile: |
| 144 raise Exception('You must specify a locales_listfile') |
| 145 locales = [] |
| 146 with open(locales_listfile) as input: |
| 147 for s in input: |
| 148 locales.append(s.rstrip()) |
| 149 |
| 108 # Ensure a fresh directory. | 150 # Ensure a fresh directory. |
| 109 try: | 151 try: |
| 110 shutil.rmtree(destination) | 152 shutil.rmtree(destination) |
| 111 except OSError: | 153 except OSError: |
| 112 if os.path.exists(destination): | 154 if os.path.exists(destination): |
| 113 raise | 155 raise |
| 114 else: | 156 else: |
| 115 pass | 157 pass |
| 116 os.mkdir(destination, 0775) | 158 os.mkdir(destination, 0775) |
| 117 | 159 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 # apps for release (no impersonation) instead of dev. | 225 # apps for release (no impersonation) instead of dev. |
| 184 if service_environment == 'prod' and buildtype == 'Dev': | 226 if service_environment == 'prod' and buildtype == 'Dev': |
| 185 raise Exception("Prod environment cannot be built for 'dev' builds") | 227 raise Exception("Prod environment cannot be built for 'dev' builds") |
| 186 | 228 |
| 187 if buildtype != 'Dev': | 229 if buildtype != 'Dev': |
| 188 if service_environment != 'prod': | 230 if service_environment != 'prod': |
| 189 raise Exception('Invalid service_environment targeted for ' | 231 raise Exception('Invalid service_environment targeted for ' |
| 190 + buildtype + ': ' + service_environment) | 232 + buildtype + ': ' + service_environment) |
| 191 if 'out/Release' not in destination and 'out\Release' not in destination: | 233 if 'out/Release' not in destination and 'out\Release' not in destination: |
| 192 raise Exception('Prod builds must be placed in the out/Release folder') | 234 raise Exception('Prod builds must be placed in the out/Release folder') |
| 193 if app_id != None: | 235 if appid != None: |
| 194 raise Exception('Cannot pass in an app_id for ' | 236 raise Exception('Cannot pass in an appid for ' |
| 195 + buildtype + ' builds: ' + service_environment) | 237 + buildtype + ' builds: ' + service_environment) |
| 196 if appRemotingApiHost != None: | 238 if appRemotingApiHost != None: |
| 197 raise Exception('Cannot set APP_REMOTING_API_HOST env var for ' | 239 raise Exception('Cannot set APP_REMOTING_API_HOST env var for ' |
| 198 + buildtype + ' builds') | 240 + buildtype + ' builds') |
| 199 if appRemotingApplicationId != None: | 241 if appRemotingApplicationId != None: |
| 200 raise Exception('Cannot set APP_REMOTING_APPLICATION_ID env var for ' | 242 raise Exception('Cannot set APP_REMOTING_APPLICATION_ID env var for ' |
| 201 + buildtype + ' builds') | 243 + buildtype + ' builds') |
| 202 | 244 |
| 203 # If an Application ID was set (either from service_environment variable or | 245 # If an Application ID was set (either from service_environment variable or |
| 204 # from a command line argument), hardcode it, otherwise get it at runtime. | 246 # from a command line argument), hardcode it, otherwise get it at runtime. |
| 205 effectiveAppId = appRemotingApplicationId or app_id | 247 effectiveAppId = appRemotingApplicationId or appid |
| 206 if effectiveAppId: | 248 if effectiveAppId: |
| 207 appRemotingApplicationId = "'" + effectiveAppId + "'" | 249 appRemotingApplicationId = "'" + effectiveAppId + "'" |
| 208 else: | 250 else: |
| 209 appRemotingApplicationId = "chrome.i18n.getMessage('@@extension_id')" | 251 appRemotingApplicationId = "chrome.i18n.getMessage('@@extension_id')" |
| 210 findAndReplace(os.path.join(destination, 'plugin_settings.js'), | 252 findAndReplace(os.path.join(destination, 'plugin_settings.js'), |
| 211 "'APP_REMOTING_APPLICATION_ID'", appRemotingApplicationId) | 253 "'APP_REMOTING_APPLICATION_ID'", appRemotingApplicationId) |
| 212 | 254 |
| 213 oauth2BaseUrl = oauth2AccountsHost + '/o/oauth2' | 255 oauth2BaseUrl = oauth2AccountsHost + '/o/oauth2' |
| 214 oauth2ApiBaseUrl = oauth2ApiHost + '/oauth2' | 256 oauth2ApiBaseUrl = oauth2ApiHost + '/oauth2' |
| 215 directoryApiBaseUrl = directoryApiHost + '/chromoting/v1' | 257 directoryApiBaseUrl = directoryApiHost + '/chromoting/v1' |
| (...skipping 13 matching lines...) Expand all Loading... |
| 229 elif service_environment == 'staging': | 271 elif service_environment == 'staging': |
| 230 appRemotingServicePath = '/appremoting/v1beta1_staging' | 272 appRemotingServicePath = '/appremoting/v1beta1_staging' |
| 231 elif service_environment == 'prod': | 273 elif service_environment == 'prod': |
| 232 appRemotingServicePath = '/appremoting/v1beta1' | 274 appRemotingServicePath = '/appremoting/v1beta1' |
| 233 else: | 275 else: |
| 234 raise Exception('Unknown service environment: ' + service_environment) | 276 raise Exception('Unknown service environment: ' + service_environment) |
| 235 appRemotingApiBaseUrl = appRemotingApiHost + appRemotingServicePath | 277 appRemotingApiBaseUrl = appRemotingApiHost + appRemotingServicePath |
| 236 else: | 278 else: |
| 237 appRemotingApiBaseUrl = '' | 279 appRemotingApiBaseUrl = '' |
| 238 | 280 |
| 281 replaceBool(destination, 'USE_GCD', use_gcd) |
| 239 replaceString(destination, 'OAUTH2_BASE_URL', oauth2BaseUrl) | 282 replaceString(destination, 'OAUTH2_BASE_URL', oauth2BaseUrl) |
| 240 replaceString(destination, 'OAUTH2_API_BASE_URL', oauth2ApiBaseUrl) | 283 replaceString(destination, 'OAUTH2_API_BASE_URL', oauth2ApiBaseUrl) |
| 241 replaceString(destination, 'DIRECTORY_API_BASE_URL', directoryApiBaseUrl) | 284 replaceString(destination, 'DIRECTORY_API_BASE_URL', directoryApiBaseUrl) |
| 242 if webapp_type == 'app_remoting': | 285 if webapp_type == 'app_remoting': |
| 243 replaceString(destination, 'APP_REMOTING_API_BASE_URL', | 286 replaceString(destination, 'APP_REMOTING_API_BASE_URL', |
| 244 appRemotingApiBaseUrl) | 287 appRemotingApiBaseUrl) |
| 245 | 288 |
| 246 # Substitute hosts in the manifest's CSP list. | 289 # Substitute hosts in the manifest's CSP list. |
| 247 # Ensure we list the API host only once if it's the same for multiple APIs. | 290 # Ensure we list the API host only once if it's the same for multiple APIs. |
| 248 googleApiHosts = ' '.join(set([oauth2ApiHost, directoryApiHost])) | 291 googleApiHosts = ' '.join(set([oauth2ApiHost, directoryApiHost])) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 277 else: | 320 else: |
| 278 oauth2RedirectUrlJs = "'" + oauth2RedirectBaseUrlJs + "/dev'" | 321 oauth2RedirectUrlJs = "'" + oauth2RedirectBaseUrlJs + "/dev'" |
| 279 oauth2RedirectUrlJson = oauth2RedirectBaseUrlJson + '/dev*' | 322 oauth2RedirectUrlJson = oauth2RedirectBaseUrlJson + '/dev*' |
| 280 thirdPartyAuthUrlJs = oauth2RedirectBaseUrlJs + '/thirdpartyauth' | 323 thirdPartyAuthUrlJs = oauth2RedirectBaseUrlJs + '/thirdpartyauth' |
| 281 thirdPartyAuthUrlJson = oauth2RedirectBaseUrlJson + '/thirdpartyauth*' | 324 thirdPartyAuthUrlJson = oauth2RedirectBaseUrlJson + '/thirdpartyauth*' |
| 282 replaceString(destination, 'TALK_GADGET_URL', talkGadgetBaseUrl) | 325 replaceString(destination, 'TALK_GADGET_URL', talkGadgetBaseUrl) |
| 283 findAndReplace(os.path.join(destination, 'plugin_settings.js'), | 326 findAndReplace(os.path.join(destination, 'plugin_settings.js'), |
| 284 "'OAUTH2_REDIRECT_URL'", oauth2RedirectUrlJs) | 327 "'OAUTH2_REDIRECT_URL'", oauth2RedirectUrlJs) |
| 285 | 328 |
| 286 # Configure xmpp server and directory bot settings in the plugin. | 329 # Configure xmpp server and directory bot settings in the plugin. |
| 287 findAndReplace(os.path.join(destination, 'plugin_settings.js'), | 330 replaceBool( |
| 288 "Boolean('XMPP_SERVER_USE_TLS')", | 331 destination, 'XMPP_SERVER_USE_TLS', |
| 289 os.environ.get('XMPP_SERVER_USE_TLS', 'true')) | 332 getenvBool('XMPP_SERVER_USE_TLS', True)) |
| 290 | |
| 291 xmppServer = os.environ.get('XMPP_SERVER', | 333 xmppServer = os.environ.get('XMPP_SERVER', |
| 292 'talk.google.com:443') | 334 'talk.google.com:443') |
| 293 replaceString(destination, 'XMPP_SERVER', xmppServer) | 335 replaceString(destination, 'XMPP_SERVER', xmppServer) |
| 294 replaceString(destination, 'DIRECTORY_BOT_JID', | 336 replaceString(destination, 'DIRECTORY_BOT_JID', |
| 295 os.environ.get('DIRECTORY_BOT_JID', | 337 os.environ.get('DIRECTORY_BOT_JID', |
| 296 'remoting@bot.talk.google.com')) | 338 'remoting@bot.talk.google.com')) |
| 297 replaceString(destination, 'THIRD_PARTY_AUTH_REDIRECT_URL', | 339 replaceString(destination, 'THIRD_PARTY_AUTH_REDIRECT_URL', |
| 298 thirdPartyAuthUrlJs) | 340 thirdPartyAuthUrlJs) |
| 299 | 341 |
| 300 # Set the correct API keys. | 342 # Set the correct API keys. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 'REMOTING_IDENTITY_API_CLIENT_ID': apiClientIdV2, | 374 'REMOTING_IDENTITY_API_CLIENT_ID': apiClientIdV2, |
| 333 'OAUTH2_BASE_URL': oauth2BaseUrl, | 375 'OAUTH2_BASE_URL': oauth2BaseUrl, |
| 334 'OAUTH2_API_BASE_URL': oauth2ApiBaseUrl, | 376 'OAUTH2_API_BASE_URL': oauth2ApiBaseUrl, |
| 335 'DIRECTORY_API_BASE_URL': directoryApiBaseUrl, | 377 'DIRECTORY_API_BASE_URL': directoryApiBaseUrl, |
| 336 'APP_REMOTING_API_BASE_URL': appRemotingApiBaseUrl, | 378 'APP_REMOTING_API_BASE_URL': appRemotingApiBaseUrl, |
| 337 'OAUTH2_ACCOUNTS_HOST': oauth2AccountsHost, | 379 'OAUTH2_ACCOUNTS_HOST': oauth2AccountsHost, |
| 338 'GOOGLE_API_HOSTS': googleApiHosts, | 380 'GOOGLE_API_HOSTS': googleApiHosts, |
| 339 'APP_NAME': app_name, | 381 'APP_NAME': app_name, |
| 340 'APP_DESCRIPTION': app_description, | 382 'APP_DESCRIPTION': app_description, |
| 341 'OAUTH_GDRIVE_SCOPE': '', | 383 'OAUTH_GDRIVE_SCOPE': '', |
| 384 'USE_GCD': use_gcd, |
| 342 'XMPP_SERVER': xmppServer, | 385 'XMPP_SERVER': xmppServer, |
| 343 } | 386 } |
| 344 if 'GOOGLE_DRIVE' in app_capabilities: | 387 if 'GOOGLE_DRIVE' in app_capabilities: |
| 345 context['OAUTH_GDRIVE_SCOPE'] = ('https://docs.google.com/feeds/ ' | 388 context['OAUTH_GDRIVE_SCOPE'] = ('https://docs.google.com/feeds/ ' |
| 346 'https://www.googleapis.com/auth/drive') | 389 'https://www.googleapis.com/auth/drive') |
| 347 processJinjaTemplate(manifest_template, | 390 processJinjaTemplate(manifest_template, |
| 348 jinja_paths, | 391 jinja_paths, |
| 349 os.path.join(destination, 'manifest.json'), | 392 os.path.join(destination, 'manifest.json'), |
| 350 context) | 393 context) |
| 351 | 394 |
| 352 # Make the zipfile. | 395 # Make the zipfile. |
| 353 createZip(zip_path, destination) | 396 createZip(zip_path, destination) |
| 354 | 397 |
| 355 return 0 | 398 return 0 |
| 356 | 399 |
| 357 | 400 |
| 358 def main(): | 401 def main(): |
| 359 if len(sys.argv) < 6: | 402 parser = argparse.ArgumentParser() |
| 360 print ('Usage: build-webapp.py ' | 403 parser.add_argument('buildtype') |
| 361 '<build-type> <version> <dst> <zip-path> <manifest_template> ' | 404 parser.add_argument('version') |
| 362 '<webapp_type> <other files...> ' | 405 parser.add_argument('destination') |
| 363 '--app_name <name> ' | 406 parser.add_argument('zip_path') |
| 364 '--app_description <description> ' | 407 parser.add_argument('manifest_template') |
| 365 '--app_capabilities <capabilities...> ' | 408 parser.add_argument('webapp_type') |
| 366 '[--appid <appid>] ' | 409 parser.add_argument('files', nargs='*', metavar='file', default=[]) |
| 367 '[--locales_listfile <locales-listfile-name>] ' | 410 parser.add_argument('--app_name', metavar='NAME') |
| 368 '[--jinja_paths <paths...>] ' | 411 parser.add_argument('--app_description', metavar='TEXT') |
| 369 '[--service_environment <service_environment>]') | 412 parser.add_argument('--app_capabilities', |
| 370 return 1 | 413 nargs='*', default=[], metavar='CAPABILITY') |
| 414 parser.add_argument('--appid') |
| 415 parser.add_argument('--locales_listfile', default='', metavar='PATH') |
| 416 parser.add_argument('--jinja_paths', nargs='*', default=[], metavar='PATH') |
| 417 parser.add_argument('--service_environment', default='', metavar='ENV') |
| 418 parser.add_argument('--use_gcd', choices=['0', '1'], default='0') |
| 371 | 419 |
| 372 arg_type = '' | 420 args = parser.parse_args() |
| 373 files = [] | 421 args.use_gcd = (args.use_gcd != '0') |
| 374 locales_listfile = '' | 422 args.app_capabilities = set(args.app_capabilities) |
| 375 jinja_paths = [] | 423 return buildWebApp(**vars(args)) |
| 376 app_id = None | |
| 377 app_name = None | |
| 378 app_description = None | |
| 379 app_capabilities = set([]) | |
| 380 service_environment = '' | |
| 381 | |
| 382 for arg in sys.argv[7:]: | |
| 383 if arg in ['--locales_listfile', | |
| 384 '--jinja_paths', | |
| 385 '--appid', | |
| 386 '--app_name', | |
| 387 '--app_description', | |
| 388 '--app_capabilities', | |
| 389 '--service_environment']: | |
| 390 arg_type = arg | |
| 391 elif arg_type == '--locales_listfile': | |
| 392 locales_listfile = arg | |
| 393 arg_type = '' | |
| 394 elif arg_type == '--jinja_paths': | |
| 395 jinja_paths.append(arg) | |
| 396 elif arg_type == '--appid': | |
| 397 app_id = arg | |
| 398 arg_type = '' | |
| 399 elif arg_type == '--app_name': | |
| 400 app_name = arg | |
| 401 arg_type = '' | |
| 402 elif arg_type == '--app_description': | |
| 403 app_description = arg | |
| 404 arg_type = '' | |
| 405 elif arg_type == '--app_capabilities': | |
| 406 app_capabilities.add(arg) | |
| 407 elif arg_type == '--service_environment': | |
| 408 service_environment = arg | |
| 409 arg_type = '' | |
| 410 else: | |
| 411 files.append(arg) | |
| 412 | |
| 413 # Load the locales files from the locales_listfile. | |
| 414 if not locales_listfile: | |
| 415 raise Exception('You must specify a locales_listfile') | |
| 416 locales = [] | |
| 417 with open(locales_listfile) as input: | |
| 418 for s in input: | |
| 419 locales.append(s.rstrip()) | |
| 420 | |
| 421 return buildWebApp(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], | |
| 422 sys.argv[5], sys.argv[6], app_id, app_name, | |
| 423 app_description, app_capabilities, files, locales, | |
| 424 jinja_paths, service_environment) | |
| 425 | 424 |
| 426 | 425 |
| 427 if __name__ == '__main__': | 426 if __name__ == '__main__': |
| 428 sys.exit(main()) | 427 sys.exit(main()) |
| OLD | NEW |