view onsub.py @ 4:aa0c2e9f5f59

Adapt to Mercurial API change
author Martin Geisler <mg@aragost.com>
date Wed, 24 Nov 2010 14:58:48 +0100
parents a2184bbf38e6
children 11fd0da50daa
line wrap: on
line source


import os
from mercurial.i18n import _
from mercurial import extensions, subrepo, util

"""execute a command in each subrepository"""

def onsub(ui, repo, *args, **opts):
    """execute a command in each subrepository

    The command is executed with the current working directory set to
    the root of each subrepository. By default, execution stops if the
    command returns a non-zero exit code. Use --ignore-errors to
    override this.

    Use --verbose/-v to print the name of each subrepo before the
    command is executed, use --print0/-0 to terminate this line with a
    NUL character instead of a newline. This can for instance be
    useful in combination with :hg:`status --print0`.

    The command has access to the following environment variables:

    ``HG_REPO``:
        Absolute path to the top-level repository in which the onsub
        command was executed.

    ``HG_SUBPATH``:
        Relative path to the current subrepository from the top-level
        repository.

    ``HG_SUBURL``:
        URL for the current subrepository as specified in the
        containing repository's ``.hgsub`` file.

    ``HG_SUBSTATE``:
        State of the current subrepository as specified in the
        containing repository's ``.hgsubstate`` file.
    """
    cmd = ' '.join(args)
    foreach(ui, repo, cmd, not opts.get('breadth_first'), opts.get('print0'),
            opts.get('ignore_errors'))

def foreach(ui, repo, cmd, depthfirst, print0, ignoreerrors):
    """execute cmd in repo.root and in each subrepository"""
    ctx = repo['.']
    work = [ctx.sub(subpath) for subpath in sorted(ctx.substate)]
    if depthfirst:
        work.reverse()

    while work:
        if depthfirst:
            sub = work.pop()
        else:
            sub = work.pop(0)

        # subrepo.relpath was renamed to subrepo.subrelpath in
        # 18b5b6392fcf.
        if hasattr(subrepo, 'relpath'):
            relpath = subrepo.relpath(sub)
        else:
            relpath = subrepo.subrelpath(sub)

        if print0:
            ui.write(relpath, "\0")
        else:
            ui.note(_("executing '%s' in %s\n") % (cmd, relpath))
        if ignoreerrors:
            onerr = None
        else:
            onerr = util.Abort
        util.system(cmd, environ=dict(HG_SUBPATH=relpath,
                                      HG_SUBURL=sub._path,
                                      HG_SUBSTATE=sub._state[1],
                                      HG_REPO=repo.root),
                    cwd=os.path.join(repo.root, relpath),
                    onerr=onerr,
                    errprefix=_('terminated onsub in %s') % relpath)

        if isinstance(sub, subrepo.hgsubrepo):
            rev = sub._state[1]
            ctx = sub._repo[rev]
            w = [ctx.sub(subpath) for subpath in sorted(ctx.substate)]
            if depthfirst:
                w.reverse()
            work.extend(w)

cmdtable = {
    "onsub":
        (onsub,
         [('b', 'breadth-first', None,
           _('use breadth-first traversal')),
          ('', 'ignore-errors', None,
           _('continue execution despite errors')),
          ('0', 'print0', None,
           _('end subrepository names with NUL, for use with xargs'))],
         _('[-b] [-0] [--ignore-errors] CMD'))
}