view mozillatry.py @ 11:9b90cf893943

default configuration file
author Jeff Hammel <jhammel@mozilla.com>
date Tue, 04 Dec 2012 15:35:54 -0800
parents f0bca08e296a
children c0e50e040275
line wrap: on
line source

#!/usr/bin/env python

"""
push patches to try
"""

import configuration
import optparse
import os
import sys

from subprocess import check_call as call

def reset(directory):
    """reset an hg directory to a good state"""
    assert os.path.exists(directory) and os.path.isdir(directory)
    hg_dir = os.path.join(directory, '.hg')
    assert os.path.exists(hg_dir) and os.path.isdir(hg_dir)
    call(['hg', 'revert', '--no-backup', '--all'], cwd=directory)
    call(['hg', 'qpop', '--all'], cwd=directory)
    try:
        shutil.rmtree(os.path.join(hg_dir, 'patches')) # remove patches
    except:
        pass

def update(directory):
    """update a mozilla-central checkout"""
    assert os.path.exists(directory) and os.path.isdir(directory)
    reset(directory)
    call(['hg', 'pull'], cwd=directory)
    call(['hg', 'update'], cwd=directory)
    call(['hg', 'qinit'], cwd=directory)

def push_to_try(patches, repo, commit, _try='ssh://hg.mozilla.org/try/'):
    """push a series of patches to try repository"""

    # ensure the repo is in a good state
    update(repo)

    try:
        # apply patches
        for patch in patches:
            call(['hg', 'qimport', patch], cwd=repo)
            call(['hg', 'qpush', '--all'], cwd=repo)
            call(['hg', 'qseries', '-v'], cwd=repo)

        # push to try
        call(['hg', 'qref', '--message', commit], cwd=repo)
        call(['hg', 'push', '-f', _try], cwd=repo)
    finally:
        reset(repo)

def try_syntax(opt=True, debug=True, unittests=('all'), talos=('all'), bug=None):
    """
    return try syntax; see also:
    - https://github.com/pbiggar/trychooser
    - http://trychooser.pub.build.mozilla.org/
    """

    assert opt or debug
    message = ['try:']
    message += ['-b', '%s%s' % (('d' if debug else ''), ('o' if opt else ''))]
    message += ['-u', (','.join(unittests) if unittests else 'none')]
    message += ['-t', (','.join(talos) if talos else 'none')]
    if bug:
        message += ['--post-to-bugzilla', 'Bug', str(bug)]
    return ' '.join(message)

### configuration parsing

class ConfigurationError(Exception):
    """error when checking configuration"""

class MozillaTryConfiguration(configuration.Configuration):

    default_config_file = os.path.join('~', '.mozutils.yaml')
    usage = '%prog [options] patch <patch2> <...>'
    load_help = 'load from config file'
    if os.path.exists(os.path.expanduser(default_config_file)):
        load_help += ' [DEFAULT: %s]' % default_config_file
    options = {'opt': {'default': True,
                       'help': "whether to try on opt builds"},
               'debug': {'default': True,
                         'help': "whether to try on debug builds"},
               'unittests': {'default': [],
                             'help': "unit tests to run",
                             'flags': ['-u', '--unittests']},
               'talostests': {'default': [],
                              'help': "talos tests to run",
                              'flags': ['-t', '--talostests']},
               'mozilla_central': {'help': "path to mozilla-central clone",
                                   'required': True,
                                   'flags': ["--m-c", "--mozilla-central"]}
               }

    def __init__(self):
        configuration.Configuration.__init__(self, usage=self.usage, load='--config')

    def validate(self):
        """check configuration"""

        configuration.Configuration.validate(self)

        if (not self.config.get('opt')) and (not self.config.get('debug')):
            raise ConfigurationError("Must have opt or debug builds")

    def configuration_files(self, options, args):
        configuration_files = configuration.Configuration(self, options, args)
        if not configuration_files:
            default_config = os.path.expanduser(default_config_file)
            if os.path.exists(default_config):
                configuration_files = [default_config]
        return configuration_files

def main(args=sys.argv[1:]):

    # parse command line arguments
    parser = MozillaTryConfiguration()
    options, args = parser.parse_args()
    if not args:
        parser.print_usage()
        parser.exit()

    # get mozilla-central repository directory
    try_directory = options.mozilla_central
    if (try_directory is None) or (not os.path.exists(try_directory)):
        parser.error("mozilla-central directory does not exist: %s" % try_directory)

    # build try syntax
    commit = try_syntax(opt=options.opt,
                        debug=options.debug,
                        unittests=options.unittests,
                        talos=options.talostests
                        )
    print commit

    # push to try
    push_to_try(patches=args, repo=try_directory, commit=commit)

if __name__ == '__main__':
    main()