comparison 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
comparison
equal deleted inserted replaced
11:4cb3f28590fd 12:90b54c4fe4fe
40 40
41 ``HG_SUBSTATE``: 41 ``HG_SUBSTATE``:
42 State of the current subrepository as specified in the 42 State of the current subrepository as specified in the
43 containing repository's ``.hgsubstate`` file. 43 containing repository's ``.hgsubstate`` file.
44 """ 44 """
45 cmd = ' '.join(args) 45 if len(args) == 2:
46 foreach(ui, repo, cmd, 46 precmd = args[0]
47 postcmd = args[1]
48 if opts.get('breadth_first') or opts.get('post_order'):
49 raise util.Abort(_("onsub: '-b' and '-p' imply the use of only one command"))
50 elif len(args) == 1:
51 if opts.get('post_order'):
52 precmd = None
53 postcmd = args[0]
54 else:
55 precmd = args[0]
56 postcmd = None
57 elif len(args) == 0:
58 # cmd == '' means only do print0
59 if opts.get('post_order'):
60 precmd = None
61 postcmd = ''
62 else:
63 precmd = ''
64 postcmd = None
65 else:
66 raise util.Abort(_("onsub: at most 2 command arguments required"))
67 if opts.get('post_order') and opts.get('breadth_first'):
68 raise util.Abort(_("onsub: '-b' and '-p' are mutually exclusive"))
69 foreach(ui, repo, precmd, postcmd,
47 not opts.get('breadth_first'), 70 not opts.get('breadth_first'),
48 opts.get('max_depth'), 71 opts.get('max_depth'),
49 opts.get('print0'), 72 opts.get('print0'),
50 opts.get('ignore_errors')) 73 opts.get('ignore_errors'),
74 opts.get('root_repo'))
51 75
52 def foreach(ui, repo, cmd, depthfirst, maxdepth, print0, ignoreerrors): 76 def execCmd(ui, rootrepo, sub, doaction, print0, cmd, inroot, ignoreerrors):
53 """execute cmd in repo.root and in each subrepository""" 77 """ if doaction, execute cmd; else, do nothing. if inroot,
54 ctx = repo['.'] 78 then command is executed inside rootrepo; else, inside sub
55 work = [(1, ctx.sub(subpath)) for subpath in sorted(ctx.substate)] 79
56 if depthfirst: 80 If cmd == None, do nothing. If cmd == '', do only the print0 (if needed).
57 work.reverse() 81 Else, do either print0 or the debugging message, then execute the command.
58 82 """
59 while work: 83 if not doaction:
60 if depthfirst: 84 return
61 (depth, sub) = work.pop() 85 if inroot:
62 else: 86 envargdict = dict(HG_SUBPATH='.',
63 (depth, sub) = work.pop(0) 87 HG_SUBURL='.',
64 if depth > maxdepth >= 0: 88 HG_SUBSTATE=rootrepo['.'].hex(),
65 continue 89 HG_REPO=rootrepo.root)
66 90 relpath = '.'
91 cmdwd = rootrepo.root
92 else:
67 # subrepo.relpath was renamed to subrepo.subrelpath in 93 # subrepo.relpath was renamed to subrepo.subrelpath in
68 # 18b5b6392fcf. 94 # 18b5b6392fcf.
69 if hasattr(subrepo, 'relpath'): 95 if hasattr(subrepo, 'relpath'):
70 relpath = subrepo.relpath(sub) 96 relpath = subrepo.relpath(sub)
71 else: 97 else:
72 relpath = subrepo.subrelpath(sub) 98 relpath = subrepo.subrelpath(sub)
73 99 envargdict = dict(HG_SUBPATH=relpath,
100 HG_SUBURL=sub._path,
101 HG_SUBSTATE=sub._state[1],
102 HG_REPO=rootrepo.root)
103 cmdwd = os.path.join(rootrepo.root, relpath)
104 if ignoreerrors:
105 onerr = None
106 else:
107 onerr = util.Abort
108 if cmd != None:
74 if print0: 109 if print0:
75 ui.write(relpath, "\0") 110 ui.write(relpath, "\0")
111 if cmd != '':
112 if not print0: ui.note(_("executing '%s' in %s\n") % (cmd, relpath))
113 util.system(cmd, environ=envargdict, cwd=cmdwd, onerr=onerr,
114 errprefix=_('terminated onsub in %s') % relpath)
115
116
117
118 def foreach(ui, repo, precmd, postcmd, depthfirst, maxdepth, print0, ignoreerrors, includeroot):
119 """execute (pre/post)cmd in repo.root and in each subrepository"""
120 seen = set()
121 execCmd(ui=ui, rootrepo=repo, sub=None, doaction=includeroot,
122 print0=print0, cmd=precmd, inroot=True, ignoreerrors=ignoreerrors)
123 ctx = repo['.']
124 work = [(1, ctx.sub(subpath)) for subpath in sorted(ctx.substate)]
125 if depthfirst:
126 work.reverse()
127 while work:
128 if depthfirst:
129 (depth, sub) = work[-1]
130 if sub in seen:
131 dopreaction = False
132 dopostaction = True
133 doaddchildren = False
134 work.pop()
135 else:
136 dopreaction = True
137 dopostaction = False
138 doaddchildren = True
139 seen.add(sub)
76 else: 140 else:
77 ui.note(_("executing '%s' in %s\n") % (cmd, relpath)) 141 (depth, sub) = work.pop(0)
78 if ignoreerrors: 142 dopreaction = True
79 onerr = None 143 dopostaction = False
80 else: 144 doaddchildren = True
81 onerr = util.Abort 145 if depth > maxdepth >= 0:
82 util.system(cmd, environ=dict(HG_SUBPATH=relpath, 146 continue
83 HG_SUBURL=sub._path, 147 execCmd(ui=ui, rootrepo=repo, sub=sub, doaction=dopreaction,
84 HG_SUBSTATE=sub._state[1], 148 print0=print0, cmd=precmd, inroot=False, ignoreerrors=ignoreerrors)
85 HG_REPO=repo.root), 149 if doaddchildren:
86 cwd=os.path.join(repo.root, relpath), 150 if isinstance(sub, subrepo.hgsubrepo):
87 onerr=onerr, 151 rev = sub._state[1]
88 errprefix=_('terminated onsub in %s') % relpath) 152 ctx = sub._repo[rev]
89 153 w = [(depth + 1, ctx.sub(subpath))
90 if isinstance(sub, subrepo.hgsubrepo): 154 for subpath in sorted(ctx.substate)]
91 rev = sub._state[1] 155 if depthfirst:
92 ctx = sub._repo[rev] 156 w.reverse()
93 w = [(depth + 1, ctx.sub(subpath)) 157 work.extend(w)
94 for subpath in sorted(ctx.substate)] 158 execCmd(ui=ui, rootrepo=repo, sub=sub, doaction=dopostaction,
95 if depthfirst: 159 print0=print0, cmd=postcmd, inroot=False, ignoreerrors=ignoreerrors)
96 w.reverse() 160 execCmd(ui=ui, rootrepo=repo, sub=None, doaction=includeroot,
97 work.extend(w) 161 print0=print0, cmd=postcmd, inroot=True, ignoreerrors=ignoreerrors)
98 162
99 cmdtable = { 163 cmdtable = {
100 "onsub": 164 "onsub":
101 (onsub, 165 (onsub,
102 [('b', 'breadth-first', None, 166 [('b', 'breadth-first', None,
103 _('use breadth-first traversal')), 167 _('use breadth-first traversal')),
168 ('p', 'post-order', None,
169 _('use post-order depth-first traversal')),
170 ('', 'root-repo', None,
171 _('include root repository in traversal')),
104 ('', 'max-depth', -1, 172 ('', 'max-depth', -1,
105 _('limit recursion to N levels (negative for no limit)'), 'N'), 173 _('limit recursion to N levels (negative for no limit)'), 'N'),
106 ('', 'ignore-errors', None, 174 ('', 'ignore-errors', None,
107 _('continue execution despite errors')), 175 _('continue execution despite errors')),
108 ('0', 'print0', None, 176 ('0', 'print0', None,