michael@0: # This Source Code Form is subject to the terms of the Mozilla Public michael@0: # License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: # file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: # Generate xpi for the simulator addon by: michael@0: # - building a special gaia profile for it, as we need: michael@0: # * more languages, and, michael@0: # * less apps michael@0: # than b2g desktop's one michael@0: # - retrieve usefull app version metadata from the build system michael@0: # - finally, use addon sdk's cfx tool to build the addon xpi michael@0: # that ships: michael@0: # * a small firefox addon registering to the app manager michael@0: # * b2g desktop runtime michael@0: # * gaia profile michael@0: michael@0: import sys, os, re, subprocess michael@0: from mozbuild.preprocessor import Preprocessor michael@0: from mozbuild.base import MozbuildObject michael@0: from mozbuild.util import ensureParentDir michael@0: from zipfile import ZipFile michael@0: from distutils.version import LooseVersion michael@0: michael@0: ftp_root_path = "/pub/mozilla.org/labs/fxos-simulator" michael@0: UPDATE_LINK = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/%(xpi_name)s" michael@0: UPDATE_URL = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/update.rdf" michael@0: XPI_NAME = "fxos-simulator-%(version)s-%(platform)s.xpi" michael@0: michael@0: class GaiaBuilder(object): michael@0: def __init__(self, build, gaia_path): michael@0: self.build = build michael@0: self.gaia_path = gaia_path michael@0: michael@0: def clean(self): michael@0: self.build._run_make(target="clean", directory=self.gaia_path) michael@0: michael@0: def profile(self, env): michael@0: self.build._run_make(target="profile", directory=self.gaia_path, num_jobs=1, silent=False, append_env=env) michael@0: michael@0: def override_prefs(self, srcfile): michael@0: # Note that each time we call `make profile` in gaia, a fresh new pref file is created michael@0: # cat srcfile >> profile/user.js michael@0: with open(os.path.join(self.gaia_path, "profile", "user.js"), "a") as userJs: michael@0: userJs.write(open(srcfile).read()) michael@0: michael@0: def process_package_overload(src, dst, version, app_buildid): michael@0: ensureParentDir(dst) michael@0: # First replace numeric version like '1.3' michael@0: # Then replace with 'slashed' version like '1_4' michael@0: # Finally set the full length addon version like 1.3.20131230 michael@0: # (reduce the app build id to only the build date michael@0: # as addon manager doesn't handle big ints in addon versions) michael@0: defines = { michael@0: "NUM_VERSION": version, michael@0: "SLASH_VERSION": version.replace(".", "_"), michael@0: "FULL_VERSION": ("%s.%s" % (version, app_buildid[:8])) michael@0: } michael@0: pp = Preprocessor(defines=defines) michael@0: pp.do_filter("substitution") michael@0: with open(dst, "w") as output: michael@0: with open(src, "r") as input: michael@0: pp.processFile(input=input, output=output) michael@0: michael@0: def add_dir_to_zip(zip, top, pathInZip, blacklist=()): michael@0: zf = ZipFile(zip, "a") michael@0: for dirpath, subdirs, files in os.walk(top): michael@0: dir_relpath = os.path.relpath(dirpath, top) michael@0: if dir_relpath.startswith(blacklist): michael@0: continue michael@0: zf.write(dirpath, os.path.join(pathInZip, dir_relpath)) michael@0: for filename in files: michael@0: relpath = os.path.join(dir_relpath, filename) michael@0: if relpath in blacklist: michael@0: continue michael@0: zf.write(os.path.join(dirpath, filename), michael@0: os.path.join(pathInZip, relpath)) michael@0: zf.close() michael@0: michael@0: def main(platform): michael@0: build = MozbuildObject.from_environment() michael@0: topsrcdir = build.topsrcdir michael@0: distdir = build.distdir michael@0: michael@0: srcdir = os.path.join(topsrcdir, "b2g", "simulator") michael@0: michael@0: app_buildid = open(os.path.join(build.topobjdir, "config", "buildid")).read().strip() michael@0: michael@0: # The simulator uses a shorter version string, michael@0: # it only keeps the major version digits A.B michael@0: # whereas MOZ_B2G_VERSION is A.B.C.D michael@0: b2g_version = build.config_environment.defines["MOZ_B2G_VERSION"].replace('"', '') michael@0: version = ".".join(str(n) for n in LooseVersion(b2g_version).version[0:2]) michael@0: michael@0: # Build a gaia profile specific to the simulator in order to: michael@0: # - disable the FTU michael@0: # - set custom prefs to enable devtools debugger server michael@0: # - set custom settings to disable lockscreen and screen timeout michael@0: # - only ship production apps michael@0: gaia_path = build.config_environment.substs["GAIADIR"] michael@0: builder = GaiaBuilder(build, gaia_path) michael@0: builder.clean() michael@0: env = { michael@0: "NOFTU": "1", michael@0: "GAIA_APP_TARGET": "production", michael@0: "SETTINGS_PATH": os.path.join(srcdir, "custom-settings.json") michael@0: } michael@0: builder.profile(env) michael@0: builder.override_prefs(os.path.join(srcdir, "custom-prefs.js")) michael@0: michael@0: # Substitute version strings in the package manifest overload file michael@0: manifest_overload = os.path.join(build.topobjdir, "b2g", "simulator", "package-overload.json") michael@0: process_package_overload(os.path.join(srcdir, "package-overload.json.in"), michael@0: manifest_overload, michael@0: version, michael@0: app_buildid) michael@0: michael@0: # Build the simulator addon xpi michael@0: xpi_name = XPI_NAME % {"version": version, "platform": platform} michael@0: xpi_path = os.path.join(distdir, xpi_name) michael@0: michael@0: update_path = "%s/%s" % (version, platform) michael@0: update_link = UPDATE_LINK % {"update_path": update_path, "xpi_name": xpi_name} michael@0: update_url = UPDATE_URL % {"update_path": update_path} michael@0: subprocess.check_call([ michael@0: build.virtualenv_manager.python_path, os.path.join(topsrcdir, "addon-sdk", "source", "bin", "cfx"), "xpi", \ michael@0: "--pkgdir", srcdir, \ michael@0: "--manifest-overload", manifest_overload, \ michael@0: "--strip-sdk", \ michael@0: "--update-link", update_link, \ michael@0: "--update-url", update_url, \ michael@0: "--static-args", "{\"label\": \"Firefox OS %s\"}" % version, \ michael@0: "--output-file", xpi_path \ michael@0: ]) michael@0: michael@0: # Ship b2g-desktop, but prevent its gaia profile to be shipped in the xpi michael@0: add_dir_to_zip(xpi_path, os.path.join(distdir, "b2g"), "b2g", ("gaia", "B2G.app/Contents/MacOS/gaia")) michael@0: # Then ship our own gaia profile michael@0: add_dir_to_zip(xpi_path, os.path.join(gaia_path, "profile"), "profile") michael@0: michael@0: if __name__ == '__main__': michael@0: if 2 != len(sys.argv): michael@0: print("""Usage: michael@0: python {0} MOZ_PKG_PLATFORM michael@0: """.format(sys.argv[0])) michael@0: sys.exit(1) michael@0: main(*sys.argv[1:]) michael@0: