def output_app_shell(self, browser_code_dir, dev_mode, verbose=True): # first, determine the application name app_info = chromeless.AppInfo(dir=browser_code_dir) output_dir = os.path.join(self.dirs.build_dir, app_info.name) if verbose: print "Building application in >%s< ..." % output_dir # obliterate old directory if present if os.path.exists(output_dir): if verbose: print " ... removing previous application" shutil.rmtree(output_dir) os.makedirs(output_dir) # create the current version dir xul_src = os.path.join(self.dirs.build_dir, "xulrunner") xul_dst = os.path.join(output_dir, "xulrunner") # and recursivly copy in the bin/ directory out of the sdk if verbose: print " ... copying in xulrunner binaries" shutil.copytree(xul_src, xul_dst) # we'll copy over the xulrunner-stub binary to the top leve if verbose: print " ... placing xulrunner binary" xulrunner_stub_path = os.path.join(output_dir, "xulrunner", "xulrunner-stub") final_binary_path = os.path.join(output_dir, app_info.name) shutil.copy(xulrunner_stub_path, final_binary_path) return {"xulrunner_app_dir": output_dir, "output_dir": output_dir}
def output_app_shell(self, browser_code_dir, dev_mode, verbose=True): # first, determine the application name app_info = chromeless.AppInfo(dir=browser_code_dir) output_dir = os.path.join(self.dirs.build_dir, app_info.name) if verbose: print "Building application in >%s< ..." % output_dir # obliterate old directory if present if os.path.exists(output_dir): if verbose: print " ... removing previous application" shutil.rmtree(output_dir) os.makedirs(output_dir) # create the current version dir xul_src = os.path.join(self.dirs.build_dir, "xulrunner") xul_dst = os.path.join(output_dir, "xulrunner") # and recursivly copy in the bin/ directory out of the sdk if verbose: print " ... copying in xulrunner binaries" shutil.copytree(xul_src, xul_dst) # we'll copy over the xulrunner-stub.exe binary to the top leve if verbose: print " ... placing xulrunner binary" xulrunner_stub_path = os.path.join(output_dir, "xulrunner", "xulrunner-stub.exe") final_binary_path = os.path.join(output_dir, app_info.name + ".exe") shutil.copy(xulrunner_stub_path, final_binary_path) # With XULRunner 11.0 you may need to copy "gkmedias.dll" from the # xulrunner directory to the root directory # See https://developer.mozilla.org/en/XULRunner/Deploying_XULRunner_1.8 dllsrc = os.path.join(output_dir, "xulrunner", "gkmedias.dll") shutil.move(dllsrc, output_dir) return {"xulrunner_app_dir": output_dir, "output_dir": output_dir}
def output_xul_app(self, browser_code, harness_options, dev_mode, verbose=True, output_dir=None): browser_code_dir = browser_code browser_code_main = "index.html" if not os.path.isdir(browser_code_dir): browser_code_main = os.path.basename(browser_code) browser_code_dir = os.path.dirname(browser_code) # determine where to put the app, if the output_dir is not # specified we'll put the app output in build/ and remove # pre-existing output, otherwise we'll write into the location # and hope for the best. if output_dir == None: app_info = chromeless.AppInfo(dir=browser_code_dir) output_dir = os.path.join(self.dirs.build_dir, app_info.name) + ".xul" if os.path.exists(output_dir): if verbose: print "Removing old xul app" shutil.rmtree(output_dir) if not os.path.isdir(output_dir): os.makedirs(output_dir) if verbose: print "Building xulrunner app in >%s< ..." % output_dir # extract information about the application from appinfo.json app_info = chromeless.AppInfo(dir=browser_code_dir) res_dir = os.path.join(os.path.dirname(__file__), "resources") # copy all the template files which require no substitution template_dir = os.path.join(res_dir, "xulrunner.template") if verbose: print " ... copying application template" for f in os.listdir(template_dir): src = os.path.join(template_dir, f) dst = os.path.join(output_dir, f) if (os.path.isdir(src)): shutil.copytree(src, dst) else: shutil.copy(src, dst) # sub in application.ini if verbose: print " ... creating application.ini" app_ini_template = os.path.join(res_dir, "application.ini.template") app_ini_path = os.path.join(output_dir, "application.ini") self._sub_and_copy( app_ini_template, app_ini_path, { "application_name": app_info.name, "application_vendor": app_info.vendor, "short_version": app_info.version, "build_id": app_info.build_id, "developer_email": app_info.developer_email }) # now copy in required packages (and update harness options with new pathing # as we go) if verbose: print " ... copying in CommonJS packages" IGNORED_FILES = [".gitignore", ".hgignore", "install.rdf"] IGNORED_FILE_SUFFIXES = ["~", ".test.js"] IGNORED_DIRS = [".svn", ".hg", "defaults"] def filter_filenames(filenames): for filename in filenames: if filename in IGNORED_FILES: continue if any([ filename.endswith(suffix) for suffix in IGNORED_FILE_SUFFIXES ]): continue yield filename pkg_tgt_dir = os.path.join(output_dir, "packages") new_resources = {} for resource in harness_options['resources']: base_arcpath = os.path.join('packages', resource) new_resources[resource] = ['packages', resource] abs_dirname = harness_options['resources'][resource] # Always create the directory, even if it contains no files, # since the harness will try to access it. res_tgt_dir = os.path.join(pkg_tgt_dir, resource) os.makedirs(res_tgt_dir) # in development mode we'll create symlinks. otherwise we'll # recursively copy over required packages and filter out temp files if dev_mode and platform.system() != 'Windows': for f in os.listdir(abs_dirname): os.symlink(os.path.join(abs_dirname, f), os.path.join(res_tgt_dir, f)) else: for dirpath, dirnames, filenames in os.walk(abs_dirname): goodfiles = list(filter_filenames(filenames)) tgt_dir = res_tgt_dir if dirpath != abs_dirname: tgt_dir = os.path.join(tgt_dir, relpath(dirpath, abs_dirname)) if not os.path.isdir(tgt_dir): os.makedirs(tgt_dir) for filename in goodfiles: shutil.copy(os.path.join(dirpath, filename), os.path.join(tgt_dir, filename)) dirnames[:] = [ dirname for dirname in dirnames if dirname not in IGNORED_DIRS ] harness_options['resources'] = new_resources # and browser code if verbose: print " ... copying in browser code (%s)" % browser_code_dir shutil.copytree(browser_code_dir, os.path.join(output_dir, "browser_code")) # now re-write appinfo if verbose: print " ... writing application info file" with open(os.path.join(output_dir, "browser_code", "appinfo.json"), 'w') as f: f.write(json.dumps(app_info.object, indent=4)) # now munge harness_options a bit to get correct path to browser_code in browser_code_path = "browser_code" if browser_code_main: browser_code_path = os.path.join(browser_code_path, browser_code_main) static_opts = harness_options['staticArgs'] static_opts["browser"] = browser_code_path # and write harness options if verbose: print " ... writing harness options" with open(os.path.join(output_dir, "harness-options.json"), 'w') as f: f.write(json.dumps(harness_options, indent=4)) # XXX: support for extra packages located outside of the packages/ directory! if verbose: print "xul app generated in %s" % relpath( output_dir, self.dirs.cuddlefish_root) return output_dir
def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None, defaults=None, env_root=os.environ.get('CUDDLEFISH_ROOT')): parser_kwargs = dict(arguments=arguments, global_options=global_options, parser_groups=parser_groups, usage=usage, defaults=defaults) (options, args) = parse_args(**parser_kwargs) config_args = get_config_args(options.config, env_root); # reparse configs with arguments from local.json if config_args: parser_kwargs['arguments'] += config_args (options, args) = parse_args(**parser_kwargs) command = args[0] if command == "testpkgs": test_all_packages(env_root, defaults=options.__dict__) return elif command == "testex": test_all_examples(env_root, defaults=options.__dict__) return elif command == "testall": test_all(env_root, defaults=options.__dict__) return elif command == "testcfx": test_cfx(env_root, options.verbose) return elif command == "sdocs": import docgen import chromeless dirname = os.path.join(chromeless.Dirs().build_dir, "docs") docgen.generate_static_docs(env_root, dirname) print "Created docs in %s." % dirname return use_main = False timeout = None inherited_options = ['verbose', 'enable_e10s'] if command in ("run", "package", "appify"): use_main = True elif command == "test": timeout = TEST_RUN_TIMEOUT inherited_options.extend(['iterations', 'filter', 'profileMemory']) else: print >>sys.stderr, "Unknown command: %s" % command print >>sys.stderr, "Try using '--help' for assistance." sys.exit(1) target = "main" # the harness_guid is used for an XPCOM class ID. import uuid harness_guid = str(uuid.uuid4()) targets = [target] if command == "test": targets.append(options.test_runner_pkg) if options.extra_packages: targets.extend(options.extra_packages.split(",")) resources = { } rootPaths = [ ] import chromeless path_to_modules = os.path.join(chromeless.Dirs().cuddlefish_root, "modules") for f in os.listdir(path_to_modules): resourceName = harness_guid + "-" + f resources[resourceName] = os.path.join(path_to_modules, f) rootPaths.append("resource://" + resourceName + "/"); # now add custom modules as specified by the app app_info = chromeless.AppInfo(dir=options.static_args["browser"]) if app_info.module_dirs: ac_path = options.static_args["browser"] if os.path.isfile(ac_path): ac_path = os.path.dirname(ac_path) for d in app_info.module_dirs: resourceName = harness_guid + "-appmodules-" + os.path.basename(d) if not os.path.isabs(d): d = os.path.normpath(os.path.join(ac_path, d)) resources[resourceName] = d rootPaths.append("resource://" + resourceName + "/") harness_contract_id = ('@mozilla.org/harness-service;1?id=%s' % harness_guid) harness_options = { 'bootstrap': { 'contractID': harness_contract_id, 'classID': '{%s}' % harness_guid }, 'jetpackID': harness_guid, 'bundleID': harness_guid, 'staticArgs': options.static_args, 'resources': resources, 'loader': "resource://%s-%s/%s" % (harness_guid, "internal", "cuddlefish.js"), 'rootPaths': rootPaths } if command == "test": harness_options['main'] = 'test_harness/run-tests' # XXX: we should write 'test-app' into a tempdir... harness_options['testDir'] = os.path.join(chromeless.Dirs().cuddlefish_root, "modules", "internal", "test_harness") resourceName = harness_guid + "-app-tests" resources[resourceName] = os.path.join(harness_options['testDir']) rootPaths.append("resource://" + resourceName + "/"); else: harness_options['main'] = 'main' retval = 0 a = appifier.Appifier() if command == 'package': browser_code_path = options.static_args["browser"] a.output_xul_app(browser_code=browser_code_path, harness_options=harness_options, dev_mode=False) elif command == 'appify': browser_code_path = options.static_args["browser"] a.output_application(browser_code=browser_code_path, harness_options=harness_options, dev_mode=False) else: browser_code_path = options.static_args["browser"] if options.profiledir: options.profiledir = os.path.expanduser(options.profiledir) options.profiledir = os.path.abspath(options.profiledir) if options.addons is not None: options.addons = options.addons.split(",") print "app code path: " + browser_code_path if (platform.system() == 'Darwin'): # because of the manner in which we run the application, we must use a # temporary file to enable console output [fd, tmppath] = tempfile.mkstemp() os.close(fd) print "And logging to '%s'" % tmppath harness_options['logFile'] = tmppath standalone_app_dir = a.output_application(browser_code=browser_code_path, harness_options=harness_options, dev_mode=True, verbose=False) print "opening '%s'" % standalone_app_dir tailProcess = None try: import subprocess tailProcess = subprocess.Popen(["tail", "-f", tmppath]) retval = subprocess.call(["open", "-W", standalone_app_dir]) except KeyboardInterrupt: print "got ^C, exiting..." killProcessByName(standalone_app_dir) finally: tailProcess.terminate() os.remove(tmppath) else: xul_app_dir = a.output_xul_app(browser_code=browser_code_path, harness_options=harness_options, dev_mode=True, verbose=False) from cuddlefish.runner import run_app try: retval = run_app(harness_root_dir=xul_app_dir, harness_options=harness_options, app_type=options.app, binary=options.binary, profiledir=options.profiledir, verbose=options.verbose, timeout=timeout, logfile=options.logfile, addons=options.addons) except Exception, e: if str(e).startswith(MOZRUNNER_BIN_NOT_FOUND): print >>sys.stderr, MOZRUNNER_BIN_NOT_FOUND_HELP.strip() retval = -1 else: raise sys.exit(retval)
def output_app_shell(self, browser_code_dir, dev_mode, verbose=True): # first, determine the application name app_info = chromeless.AppInfo(dir=browser_code_dir) output_dir = os.path.join(self.dirs.build_dir, app_info.name) + ".app" if verbose: print "Building application in >%s< ..." % output_dir # obliterate old directory if present if os.path.exists(output_dir): if verbose: print " ... removing previous application" shutil.rmtree(output_dir) # now let's mock up a XUL.framework dir framework_dir = os.path.join(output_dir, "Contents", "Frameworks", "XUL.framework") os.makedirs(framework_dir) # create the current version dir cur_ver_dir = os.path.join(framework_dir, "Versions") os.makedirs(cur_ver_dir) cur_ver_dir = os.path.join(cur_ver_dir, "Current") xul_bin_src = os.path.join(self.dirs.build_dir, "xulrunner-sdk", "bin") # and recursivly copy in the bin/ directory out of the sdk if verbose: print " ... copying in xulrunner binaries" if dev_mode: os.symlink(xul_bin_src, cur_ver_dir) else: shutil.copytree(xul_bin_src, cur_ver_dir) # create links inside framework for f in ("XUL", "xulrunner-bin", "libxpcom.dylib"): tgt = relpath(os.path.join(cur_ver_dir, f), framework_dir) os.symlink(tgt, os.path.join(framework_dir, f)) # now it's time to write a parameterized Info.plist if verbose: print " ... writing Info.plist" info_plist_path = os.path.join(output_dir, "Contents", "Info.plist") template_path = os.path.join(os.path.dirname(__file__), "resources", "Info.plist.template") self._sub_and_copy(template_path, info_plist_path, { "application_name": app_info.name, "short_version": app_info.version, "full_version": (app_info.version + "." + app_info.build_id) }) # we'll create the MacOS (binary) dir and copy over the xulrunner binary if verbose: print " ... placing xulrunner binary" macos_dir = os.path.join(output_dir, "Contents", "MacOS") os.makedirs(macos_dir) xulrunner_stub_path = os.path.join(cur_ver_dir, "xulrunner") shutil.copy(xulrunner_stub_path, macos_dir) # Finally, create the resources dir (where the xulrunner application will live if verbose: print " ... creating resources directory" resources_path = os.path.join(output_dir, "Contents", "Resources") os.makedirs(resources_path) return { "xulrunner_app_dir": resources_path, "output_dir": output_dir }