Mercurial > hg-onsub
changeset 16:44feac64ecfe
refactoring: disentangled breadth-first and depth-first search; made functions nested
author | jakob krainz <jakob@hawo-net.de> |
---|---|
date | Tue, 06 Mar 2012 19:59:36 +0100 |
parents | 6ee895918df9 |
children | 5ea3f7533ec5 |
files | onsub.py |
diffstat | 1 files changed, 90 insertions(+), 92 deletions(-) [+] |
line wrap: on
line diff
--- a/onsub.py Tue Mar 06 16:21:28 2012 +0100 +++ b/onsub.py Tue Mar 06 19:59:36 2012 +0100 @@ -49,6 +49,92 @@ State of the current subrepository as specified in the containing repository's ``.hgsubstate`` file. """ + + # function level "constants" - these won't be modified by the nested functions + print0 = opts.get('print0') + if opts.get('ignore_errors'): + onerr = None + else: + onerr = util.Abort + maxdepth = opts.get('max_depth') + precmd = None + postcmd = None + includeroot = opts.get('root_repo') + + def execCmd(sub, cmd): + """if sub == None, cmd is executed inside repo; 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 sub == None: + envargdict = dict(HG_SUBPATH='.', + HG_SUBURL='.', + HG_SUBSTATE=repo['.'].hex(), + HG_REPO=repo.root) + relpath = '.' + cmdwd = repo.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=repo.root) + cmdwd = os.path.join(repo.root, relpath) + if cmd != None: + if print0: + ui.write(relpath, "\0") + 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 bfs(): + """execute precmd in repo.root and in each subrepository, breadth-first""" + if includeroot: + execCmd(None, precmd) + ctx = repo['.'] + work = [(1, ctx.sub(subpath)) for subpath in sorted(ctx.substate)] + while work: + (depth, sub) = work.pop(0) + if depth > maxdepth >= 0: + continue + execCmd(sub, precmd) + 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)] + work.extend(w) + + def dfs(): + """execute pre-/postcmd in repo.root and in each subrepository, depth-first""" + + def dfs_rek(depth, sub): + if depth > maxdepth >= 0: + return + execCmd(sub, precmd) + if isinstance(sub, subrepo.hgsubrepo): + rev = sub._state[1] + ctx = sub._repo[rev] + for subpath in sorted(ctx.substate): + dfs_rek(depth+1, ctx.sub(subpath)) + execCmd(sub, postcmd) + + ctx = repo['.'] + work = [ctx.sub(subpath) for subpath in sorted(ctx.substate)] + if includeroot: + execCmd(None, precmd) + for sub in work: + dfs_rek(1, sub) + if includeroot: + execCmd(None, postcmd) + + ### start of main function part ### if len(args) == 2: precmd = args[0] postcmd = args[1] @@ -73,100 +159,12 @@ 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'), - opts.get('root_repo')) -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 + if opts.get('breadth_first'): + bfs() else: - onerr = util.Abort - if cmd != None: - if print0: - ui.write(relpath, "\0") - 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: - (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) - + dfs() + cmdtable = { "onsub": (onsub,