DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (b6057e17f856)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
#!/usr/bin/env python
# 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/.

import os
import sys

sys.path.insert(1, os.path.dirname(sys.path[0]))

from mozharness.base.script import BaseScript
from mozharness.mozilla.bouncer.submitter import BouncerSubmitterMixin
from mozharness.mozilla.purge import PurgeMixin


class BouncerSubmitter(BaseScript, PurgeMixin, BouncerSubmitterMixin):
    config_options = [
        [["--repo"], {
            "dest": "repo",
            "help": "Specify source repo, e.g. releases/mozilla-beta",
        }],
        [["--revision"], {
            "dest": "revision",
            "help": "Source revision/tag used to fetch shipped-locales",
        }],
        [["--version"], {
            "dest": "version",
            "help": "Current version",
        }],
        [["--previous-version"], {
            "dest": "prev_versions",
            "action": "extend",
            "help": "Previous version(s)",
        }],
        [["--build-number"], {
            "dest": "build_number",
            "help": "Build number of version",
        }],
        [["--bouncer-api-prefix"], {
            "dest": "bouncer-api-prefix",
            "help": "Bouncer admin API URL prefix",
        }],
        [["--credentials-file"], {
            "dest": "credentials_file",
            "help": "File containing Bouncer credentials",
        }],
    ]

    def __init__(self, require_config_file=True):
        BaseScript.__init__(self,
                            config_options=self.config_options,
                            require_config_file=require_config_file,
                            # other stuff
                            all_actions=[
                                'clobber',
                                'download-shipped-locales',
                                'submit',
                            ],
                            default_actions=[
                                'clobber',
                                'download-shipped-locales',
                                'submit',
                            ],
                            )
        self.locales = None
        self.credentials = None

    def _pre_config_lock(self, rw_config):
        super(BouncerSubmitter, self)._pre_config_lock(rw_config)

        for opt in ["version", "credentials_file", "bouncer-api-prefix"]:
            if opt not in self.config:
                self.fatal("%s must be specified" % opt)
        if self.need_shipped_locales():
            for opt in ["shipped-locales-url", "repo", "revision"]:
                if opt not in self.config:
                    self.fatal("%s must be specified" % opt)

    def need_shipped_locales(self):
        return any(e.get("add-locales") for e in
                   self.config["products"].values())

    def query_shipped_locales_path(self):
        dirs = self.query_abs_dirs()
        return os.path.join(dirs["abs_work_dir"], "shipped-locales")

    def download_shipped_locales(self):
        if not self.need_shipped_locales():
            self.info("No need to download shipped-locales")
            return

        replace_dict = {"revision": self.config["revision"],
                        "repo": self.config["repo"]}
        url = self.config["shipped-locales-url"] % replace_dict
        dirs = self.query_abs_dirs()
        self.mkdir_p(dirs["abs_work_dir"])
        if not self.download_file(url=url,
                                  file_name=self.query_shipped_locales_path()):
            self.fatal("Unable to fetch shipped-locales from %s" % url)
        # populate the list
        self.load_shipped_locales()

    def load_shipped_locales(self):
        if self.locales:
            return self.locales
        content = self.read_from_file(self.query_shipped_locales_path())
        locales = []
        for line in content.splitlines():
            locale = line.split()[0]
            if locale:
                locales.append(locale)
        self.locales = locales
        return self.locales

    def submit(self):
        subs = {
            "version": self.config["version"]
        }
        if self.config.get("build_number"):
            subs["build_number"] = self.config["build_number"]

        for product, pr_config in sorted(self.config["products"].items()):
            product_name = pr_config["product-name"] % subs
            if self.product_exists(product_name):
                self.warning("Product %s already exists. Skipping..." %
                             product_name)
                continue
            self.info("Adding %s..." % product)
            self.api_add_product(
                product_name=product_name,
                add_locales=pr_config.get("add-locales"),
                ssl_only=pr_config.get("ssl-only"))
            self.info("Adding paths...")
            for platform, pl_config in sorted(pr_config["paths"].items()):
                bouncer_platform = pl_config["bouncer-platform"]
                path = pl_config["path"] % subs
                self.info("%s (%s): %s" % (platform, bouncer_platform, path))
                self.api_add_location(product_name, bouncer_platform, path)

        # Add partial updates
        if "partials" in self.config and self.config.get("prev_versions"):
            self.submit_partials()

    def submit_partials(self):
        subs = {
            "version": self.config["version"]
        }
        if self.config.get("build_number"):
            subs["build_number"] = self.config["build_number"]
        prev_versions = self.config.get("prev_versions")
        for product, part_config in sorted(self.config["partials"].items()):
            product_name_tmpl = part_config["product-name"]
            for prev_version in prev_versions:
                prev_version, prev_build_number = prev_version.split("build")
                subs["prev_version"] = prev_version
                subs["prev_build_number"] = prev_build_number
                product_name = product_name_tmpl % subs
                if self.product_exists(product_name):
                    self.warning("Product %s already exists. Skipping..." %
                                product_name)
                    continue
                self.info("Adding partial updates for %s" % product_name)
                self.api_add_product(
                    product_name=product_name,
                    add_locales=part_config.get("add-locales"),
                    ssl_only=part_config.get("ssl-only"))
                for platform, pl_config in sorted(part_config["paths"].items()):
                    bouncer_platform = pl_config["bouncer-platform"]
                    path = pl_config["path"] % subs
                    self.info("%s (%s): %s" % (platform, bouncer_platform, path))
                    self.api_add_location(product_name, bouncer_platform, path)


if __name__ == '__main__':
    myScript = BouncerSubmitter()
    myScript.run_and_exit()