Mercurial > hg-onsub
diff onsub.py @ 12:90b54c4fe4fe
onsub extension: pre and post order
author | jakob krainz <jakob@hawo-net.de> |
---|---|
date | Tue, 06 Mar 2012 12:55:40 +0100 |
parents | ecc4fd16555d |
children | 34aa014b5989 |
line wrap: on
line diff
--- a/onsub.py Tue Mar 06 12:22:06 2012 +0100 +++ b/onsub.py Tue Mar 06 12:55:40 2012 +0100 @@ -42,65 +42,133 @@ State of the current subrepository as specified in the containing repository's ``.hgsubstate`` file. """ - cmd = ' '.join(args) - foreach(ui, repo, cmd, + if len(args) == 2: + precmd = args[0] + postcmd = args[1] + if opts.get('breadth_first') or opts.get('post_order'): + raise util.Abort(_("onsub: '-b' and '-p' imply the use of only one command")) + elif len(args) == 1: + if opts.get('post_order'): + precmd = None + postcmd = args[0] + else: + precmd = args[0] + postcmd = None + elif len(args) == 0: + # cmd == '' means only do print0 + if opts.get('post_order'): + precmd = None + postcmd = '' + else: + precmd = '' + postcmd = None + else: + raise util.Abort(_("onsub: at most 2 command arguments required")) + if opts.get('post_order') and opts.get('breadth_first'): + raise util.Abort(_("onsub: '-b' and '-p' are mutually exclusive")) + foreach(ui, repo, precmd, postcmd, not opts.get('breadth_first'), opts.get('max_depth'), opts.get('print0'), - opts.get('ignore_errors')) - -def foreach(ui, repo, cmd, depthfirst, maxdepth, print0, ignoreerrors): - """execute cmd in repo.root and in each subrepository""" - ctx = repo['.'] - work = [(1, ctx.sub(subpath)) for subpath in sorted(ctx.substate)] - if depthfirst: - work.reverse() + opts.get('ignore_errors'), + opts.get('root_repo')) - while work: - if depthfirst: - (depth, sub) = work.pop() - else: - (depth, sub) = work.pop(0) - if depth > maxdepth >= 0: - continue - +def execCmd(ui, rootrepo, sub, doaction, print0, cmd, inroot, ignoreerrors): + """ if doaction, execute cmd; else, do nothing. if inroot, + then command is executed inside rootrepo; else, inside sub + + If cmd == None, do nothing. If cmd == '', do only the print0 (if needed). + Else, do either print0 or the debugging message, then execute the command. + """ + if not doaction: + return + if inroot: + envargdict = dict(HG_SUBPATH='.', + HG_SUBURL='.', + HG_SUBSTATE=rootrepo['.'].hex(), + HG_REPO=rootrepo.root) + relpath = '.' + cmdwd = rootrepo.root + else: # subrepo.relpath was renamed to subrepo.subrelpath in # 18b5b6392fcf. if hasattr(subrepo, 'relpath'): relpath = subrepo.relpath(sub) else: relpath = subrepo.subrelpath(sub) - + envargdict = dict(HG_SUBPATH=relpath, + HG_SUBURL=sub._path, + HG_SUBSTATE=sub._state[1], + HG_REPO=rootrepo.root) + cmdwd = os.path.join(rootrepo.root, relpath) + if ignoreerrors: + onerr = None + else: + onerr = util.Abort + if cmd != None: if print0: ui.write(relpath, "\0") - else: - ui.note(_("executing '%s' in %s\n") % (cmd, relpath)) - if ignoreerrors: - onerr = None + if cmd != '': + if not print0: ui.note(_("executing '%s' in %s\n") % (cmd, relpath)) + util.system(cmd, environ=envargdict, cwd=cmdwd, onerr=onerr, + errprefix=_('terminated onsub in %s') % relpath) + + + +def foreach(ui, repo, precmd, postcmd, depthfirst, maxdepth, print0, ignoreerrors, includeroot): + """execute (pre/post)cmd in repo.root and in each subrepository""" + seen = set() + execCmd(ui=ui, rootrepo=repo, sub=None, doaction=includeroot, + print0=print0, cmd=precmd, inroot=True, ignoreerrors=ignoreerrors) + ctx = repo['.'] + work = [(1, ctx.sub(subpath)) for subpath in sorted(ctx.substate)] + if depthfirst: + work.reverse() + while work: + if depthfirst: + (depth, sub) = work[-1] + if sub in seen: + dopreaction = False + dopostaction = True + doaddchildren = False + work.pop() + else: + dopreaction = True + dopostaction = False + doaddchildren = True + seen.add(sub) 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 = [(depth + 1, ctx.sub(subpath)) - for subpath in sorted(ctx.substate)] - if depthfirst: - w.reverse() - work.extend(w) - + (depth, sub) = work.pop(0) + dopreaction = True + dopostaction = False + doaddchildren = True + if depth > maxdepth >= 0: + continue + execCmd(ui=ui, rootrepo=repo, sub=sub, doaction=dopreaction, + print0=print0, cmd=precmd, inroot=False, ignoreerrors=ignoreerrors) + if doaddchildren: + if isinstance(sub, subrepo.hgsubrepo): + rev = sub._state[1] + ctx = sub._repo[rev] + w = [(depth + 1, ctx.sub(subpath)) + for subpath in sorted(ctx.substate)] + if depthfirst: + w.reverse() + work.extend(w) + execCmd(ui=ui, rootrepo=repo, sub=sub, doaction=dopostaction, + print0=print0, cmd=postcmd, inroot=False, ignoreerrors=ignoreerrors) + execCmd(ui=ui, rootrepo=repo, sub=None, doaction=includeroot, + print0=print0, cmd=postcmd, inroot=True, ignoreerrors=ignoreerrors) + cmdtable = { "onsub": (onsub, [('b', 'breadth-first', None, _('use breadth-first traversal')), + ('p', 'post-order', None, + _('use post-order depth-first traversal')), + ('', 'root-repo', None, + _('include root repository in traversal')), ('', 'max-depth', -1, _('limit recursion to N levels (negative for no limit)'), 'N'), ('', 'ignore-errors', None,