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