author Chris Manchester <cmanchester@mozilla.com>
Thu, 10 Sep 2015 12:43:41 -0700
changeset 261858 b660da4b26e0c386be0324951f64f812848505af
parent 259878 5f2f45c700d1221ab8b9de896a5f00fb792fe1f7
child 261902 4c42d55c2455b134fbc72ad19a1036804a6f53d0
permissions -rw-r--r--
Bug 1203598 - Mention the required mercurial version when suggesting a user install the "push-to-try" extension. r=armenzg DONTBUILD

# 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 sys
import os
import itertools
import subprocess
import which

from collections import defaultdict

try: -b %s -p %s -u %s -t none %s %s

class AutoTry(object):

    test_flavors = [

    def __init__(self, topsrcdir, resolver, mach_context):
        self.topsrcdir = topsrcdir
        self.resolver = resolver
        self.mach_context = mach_context

        if os.path.exists(os.path.join(self.topsrcdir, '.hg')):
            self._use_git = False
            self._use_git = True

    def resolve_manifests(self, paths=None, tags=None):
        if not (paths or tags):
            return {}

        tests = list(self.resolver.resolve_tests(tags=tags,
        manifests_by_flavor = defaultdict(set)

        for t in tests:
            if t['flavor'] in AutoTry.test_flavors:
                flavor = t['flavor']
                if 'subsuite' in t and t['subsuite'] == 'devtools':
                    flavor = 'devtools-chrome'
                manifest = os.path.relpath(t['manifest'], self.topsrcdir)

        return dict(manifests_by_flavor)

    def calc_try_syntax(self, platforms, flavors, tests, extra_tests, builds,
                        manifests, tags):

        # Maps from flavors to the try syntax snippets implied by that flavor.
        # TODO: put selected tests under their own builder/label to avoid
        # confusion reading results on treeherder.
        flavor_suites = {
            'mochitest': ['mochitest-1', 'mochitest-e10s-1'],
            'xpcshell': ['xpcshell'],
            'chrome': ['mochitest-o'],
            'browser-chrome': ['mochitest-browser-chrome-1',
            'devtools-chrome': ['mochitest-dt',
            'crashtest': ['crashtest', 'crashtest-e10s'],
            'reftest': ['reftest', 'reftest-e10s'],

        if tags:
            tags = ' '.join('--tag %s' % t for t in tags)
            tags = ''

        if not tests:
            tests = ','.join(itertools.chain(*(flavor_suites[f] for f in flavors)))
            if extra_tests:
                tests += ',%s' % (extra_tests)

        manifests = ' '.join(manifests)
        if manifests:
            manifests = '--try-test-paths %s' % manifests
        return TRY_SYNTAX_TMPL % (builds, platforms, tests, manifests, tags)

    def _run_git(self, *args):
        args = ['git'] + list(args)
        ret = subprocess.call(args)
        if ret:
            print('ERROR git command %s returned %s' %
                  (args, ret))

    def _git_push_to_try(self, msg):
        self._run_git('commit', '--allow-empty', '-m', msg)
        self._run_git('push', 'hg::ssh://hg.mozilla.org/try',
        self._run_git('reset', 'HEAD~')

    def push_to_try(self, msg, verbose):
        if not self._use_git:
                hg_args = ['hg', 'push-to-try', '-m', msg]
                subprocess.check_call(hg_args, stderr=subprocess.STDOUT)
            except subprocess.CalledProcessError as e:
                print('ERROR hg command %s returned %s' % (hg_args, e.returncode))
                print('The "push-to-try" hg extension is required to push from '
                      'hg to try with the autotry command.\n\nIt can be installed '
                      'to Mercurial 3.3 or above by running ./mach mercurial-setup')
            except which.WhichError:
                print('ERROR git-cinnabar is required to push from git to try with'
                      'the autotry command.\n\nMore information can by found at '

    def find_uncommited_changes(self):
        if self._use_git:
            stat = subprocess.check_output(['git', 'status', '-z'])
            return any(len(entry.strip()) and entry.strip()[0] in ('A', 'M', 'D')
                       for entry in stat.split('\0'))
            stat = subprocess.check_output(['hg', 'status'])
            return any(len(entry.strip()) and entry.strip()[0] in ('A', 'M', 'R')
                       for entry in stat.splitlines())