view mozillatry.py @ 7:51d1167cc684

something still wrong here but on the right track, i hope
author Jeff Hammel <jhammel@mozilla.com>
date Tue, 04 Dec 2012 13:22:39 -0800
parents 6f35d0d90c64
children 7423fa8b4343
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):

    usage = '%prog [options] patch <patch2> <...>'
    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 check(self, config):
        """check configuration"""

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


def read_config(filename, options):
    """read .mozutils config file and substitute for options if None"""

    # XXX stub; this should really use
    # e.g. http://k0s.org/mozilla/hg/configuration/
    from ConfigParser import ConfigParser
    parser = ConfigParser()
    if not os.path.exists(filename):
        return parser
    parser.read(filename)
    if options.mozilla_central is None:
        try:
            path = parser.get('hg', 'mozilla-central')
            if path:
                options.mozilla_central = os.path.expanduser(path)
        except Exception: # XXX temporary hack
            pass
    return parser



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()