b2g/simulator/build_xpi.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/b2g/simulator/build_xpi.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,147 @@
     1.4 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 +
     1.8 +# Generate xpi for the simulator addon by:
     1.9 +# - building a special gaia profile for it, as we need:
    1.10 +#     * more languages, and,
    1.11 +#     * less apps
    1.12 +#   than b2g desktop's one
    1.13 +# - retrieve usefull app version metadata from the build system
    1.14 +# - finally, use addon sdk's cfx tool to build the addon xpi
    1.15 +#   that ships:
    1.16 +#     * a small firefox addon registering to the app manager
    1.17 +#     * b2g desktop runtime
    1.18 +#     * gaia profile
    1.19 +
    1.20 +import sys, os, re, subprocess
    1.21 +from mozbuild.preprocessor import Preprocessor
    1.22 +from mozbuild.base import MozbuildObject
    1.23 +from mozbuild.util import ensureParentDir
    1.24 +from zipfile import ZipFile
    1.25 +from distutils.version import LooseVersion
    1.26 +
    1.27 +ftp_root_path = "/pub/mozilla.org/labs/fxos-simulator"
    1.28 +UPDATE_LINK = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/%(xpi_name)s"
    1.29 +UPDATE_URL = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/update.rdf"
    1.30 +XPI_NAME = "fxos-simulator-%(version)s-%(platform)s.xpi"
    1.31 +
    1.32 +class GaiaBuilder(object):
    1.33 +    def __init__(self, build, gaia_path):
    1.34 +        self.build = build
    1.35 +        self.gaia_path = gaia_path
    1.36 +
    1.37 +    def clean(self):
    1.38 +        self.build._run_make(target="clean", directory=self.gaia_path)
    1.39 +
    1.40 +    def profile(self, env):
    1.41 +        self.build._run_make(target="profile", directory=self.gaia_path, num_jobs=1, silent=False, append_env=env)
    1.42 +
    1.43 +    def override_prefs(self, srcfile):
    1.44 +        # Note that each time we call `make profile` in gaia, a fresh new pref file is created
    1.45 +        # cat srcfile >> profile/user.js
    1.46 +        with open(os.path.join(self.gaia_path, "profile", "user.js"), "a") as userJs:
    1.47 +            userJs.write(open(srcfile).read())
    1.48 +
    1.49 +def process_package_overload(src, dst, version, app_buildid):
    1.50 +    ensureParentDir(dst)
    1.51 +    # First replace numeric version like '1.3'
    1.52 +    # Then replace with 'slashed' version like '1_4'
    1.53 +    # Finally set the full length addon version like 1.3.20131230
    1.54 +    # (reduce the app build id to only the build date
    1.55 +    # as addon manager doesn't handle big ints in addon versions)
    1.56 +    defines = {
    1.57 +        "NUM_VERSION": version,
    1.58 +        "SLASH_VERSION": version.replace(".", "_"),
    1.59 +        "FULL_VERSION": ("%s.%s" % (version, app_buildid[:8]))
    1.60 +    }
    1.61 +    pp = Preprocessor(defines=defines)
    1.62 +    pp.do_filter("substitution")
    1.63 +    with open(dst, "w") as output:
    1.64 +        with open(src, "r") as input:
    1.65 +            pp.processFile(input=input, output=output)
    1.66 +
    1.67 +def add_dir_to_zip(zip, top, pathInZip, blacklist=()):
    1.68 +    zf = ZipFile(zip, "a")
    1.69 +    for dirpath, subdirs, files in os.walk(top):
    1.70 +        dir_relpath = os.path.relpath(dirpath, top)
    1.71 +        if dir_relpath.startswith(blacklist):
    1.72 +            continue
    1.73 +        zf.write(dirpath, os.path.join(pathInZip, dir_relpath))
    1.74 +        for filename in files:
    1.75 +            relpath = os.path.join(dir_relpath, filename)
    1.76 +            if relpath in blacklist:
    1.77 +                continue
    1.78 +            zf.write(os.path.join(dirpath, filename),
    1.79 +                     os.path.join(pathInZip, relpath))
    1.80 +    zf.close()
    1.81 +
    1.82 +def main(platform):
    1.83 +    build = MozbuildObject.from_environment()
    1.84 +    topsrcdir = build.topsrcdir
    1.85 +    distdir = build.distdir
    1.86 +
    1.87 +    srcdir = os.path.join(topsrcdir, "b2g", "simulator")
    1.88 +
    1.89 +    app_buildid = open(os.path.join(build.topobjdir, "config", "buildid")).read().strip()
    1.90 +
    1.91 +    # The simulator uses a shorter version string,
    1.92 +    # it only keeps the major version digits A.B
    1.93 +    # whereas MOZ_B2G_VERSION is A.B.C.D
    1.94 +    b2g_version = build.config_environment.defines["MOZ_B2G_VERSION"].replace('"', '')
    1.95 +    version = ".".join(str(n) for n in LooseVersion(b2g_version).version[0:2])
    1.96 +
    1.97 +    # Build a gaia profile specific to the simulator in order to:
    1.98 +    # - disable the FTU
    1.99 +    # - set custom prefs to enable devtools debugger server
   1.100 +    # - set custom settings to disable lockscreen and screen timeout
   1.101 +    # - only ship production apps
   1.102 +    gaia_path = build.config_environment.substs["GAIADIR"]
   1.103 +    builder = GaiaBuilder(build, gaia_path)
   1.104 +    builder.clean()
   1.105 +    env = {
   1.106 +      "NOFTU": "1",
   1.107 +      "GAIA_APP_TARGET": "production",
   1.108 +      "SETTINGS_PATH": os.path.join(srcdir, "custom-settings.json")
   1.109 +    }
   1.110 +    builder.profile(env)
   1.111 +    builder.override_prefs(os.path.join(srcdir, "custom-prefs.js"))
   1.112 +
   1.113 +    # Substitute version strings in the package manifest overload file
   1.114 +    manifest_overload = os.path.join(build.topobjdir, "b2g", "simulator", "package-overload.json")
   1.115 +    process_package_overload(os.path.join(srcdir, "package-overload.json.in"),
   1.116 +                             manifest_overload,
   1.117 +                             version,
   1.118 +                             app_buildid)
   1.119 +
   1.120 +    # Build the simulator addon xpi
   1.121 +    xpi_name = XPI_NAME % {"version": version, "platform": platform}
   1.122 +    xpi_path = os.path.join(distdir, xpi_name)
   1.123 +
   1.124 +    update_path = "%s/%s" % (version, platform)
   1.125 +    update_link = UPDATE_LINK % {"update_path": update_path, "xpi_name": xpi_name}
   1.126 +    update_url = UPDATE_URL % {"update_path": update_path}
   1.127 +    subprocess.check_call([
   1.128 +      build.virtualenv_manager.python_path, os.path.join(topsrcdir, "addon-sdk", "source", "bin", "cfx"), "xpi", \
   1.129 +      "--pkgdir", srcdir, \
   1.130 +      "--manifest-overload", manifest_overload, \
   1.131 +      "--strip-sdk", \
   1.132 +      "--update-link", update_link, \
   1.133 +      "--update-url", update_url, \
   1.134 +      "--static-args", "{\"label\": \"Firefox OS %s\"}" % version, \
   1.135 +      "--output-file", xpi_path \
   1.136 +    ])
   1.137 +
   1.138 +    # Ship b2g-desktop, but prevent its gaia profile to be shipped in the xpi
   1.139 +    add_dir_to_zip(xpi_path, os.path.join(distdir, "b2g"), "b2g", ("gaia", "B2G.app/Contents/MacOS/gaia"))
   1.140 +    # Then ship our own gaia profile
   1.141 +    add_dir_to_zip(xpi_path, os.path.join(gaia_path, "profile"), "profile")
   1.142 +
   1.143 +if __name__ == '__main__':
   1.144 +    if 2 != len(sys.argv):
   1.145 +        print("""Usage:
   1.146 +  python {0} MOZ_PKG_PLATFORM
   1.147 +""".format(sys.argv[0]))
   1.148 +        sys.exit(1)
   1.149 +    main(*sys.argv[1:])
   1.150 +

mercurial