annotate onsub.py @ 8:ecc4fd16555d

Add --max-depth option to limit depth of recursion.
author Greg Ward <greg@gerg.ca>
date Sun, 24 Apr 2011 11:09:36 -0400
parents a2ad7553ba79
children 90b54c4fe4fe
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6
11fd0da50daa Copyright and license header
Martin Geisler <mg@aragost.com>
parents: 4
diff changeset
1 # onsub.py - execute commands recursively on subrepositories
11fd0da50daa Copyright and license header
Martin Geisler <mg@aragost.com>
parents: 4
diff changeset
2 #
11fd0da50daa Copyright and license header
Martin Geisler <mg@aragost.com>
parents: 4
diff changeset
3 # Copyright 2010, 2011 aragost Trifork
11fd0da50daa Copyright and license header
Martin Geisler <mg@aragost.com>
parents: 4
diff changeset
4 #
11fd0da50daa Copyright and license header
Martin Geisler <mg@aragost.com>
parents: 4
diff changeset
5 # This software may be used and distributed according to the terms of
11fd0da50daa Copyright and license header
Martin Geisler <mg@aragost.com>
parents: 4
diff changeset
6 # the GNU General Public License version 2 or any later version.
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
7
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
8 import os
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
9 from mercurial.i18n import _
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
10 from mercurial import extensions, subrepo, util
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
11
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
12 """execute a command in each subrepository"""
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
13
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
14 def onsub(ui, repo, *args, **opts):
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
15 """execute a command in each subrepository
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
16
7
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
17 Executes CMD with the current working directory set to the root of
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
18 each subrepository. By default, execution stops if CMD returns a
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
19 non-zero exit code. Use --ignore-errors to override this.
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
20
7
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
21 Use --verbose/-v to print the command being run and the subrepo
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
22 name for each run of CMD in a subrepo. Alternately, use
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
23 --print0/-0 to print just the subrepo name followed by a NUL
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
24 character instead of a newline. This can be useful in combination
a2ad7553ba79 Improve help text (in particular, clarify meaning of --print0).
Greg Ward <greg@gerg.ca>
parents: 6
diff changeset
25 with :hg:`status --print0`.
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
26
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
27 The command has access to the following environment variables:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
28
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
29 ``HG_REPO``:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
30 Absolute path to the top-level repository in which the onsub
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
31 command was executed.
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
32
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
33 ``HG_SUBPATH``:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
34 Relative path to the current subrepository from the top-level
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
35 repository.
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
36
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
37 ``HG_SUBURL``:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
38 URL for the current subrepository as specified in the
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
39 containing repository's ``.hgsub`` file.
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
40
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
41 ``HG_SUBSTATE``:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
42 State of the current subrepository as specified in the
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
43 containing repository's ``.hgsubstate`` file.
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
44 """
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
45 cmd = ' '.join(args)
8
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
46 foreach(ui, repo, cmd,
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
47 not opts.get('breadth_first'),
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
48 opts.get('max_depth'),
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
49 opts.get('print0'),
3
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
50 opts.get('ignore_errors'))
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
51
8
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
52 def foreach(ui, repo, cmd, depthfirst, maxdepth, print0, ignoreerrors):
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
53 """execute cmd in repo.root and in each subrepository"""
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
54 ctx = repo['.']
8
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
55 work = [(1, ctx.sub(subpath)) for subpath in sorted(ctx.substate)]
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
56 if depthfirst:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
57 work.reverse()
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
58
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
59 while work:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
60 if depthfirst:
8
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
61 (depth, sub) = work.pop()
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
62 else:
8
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
63 (depth, sub) = work.pop(0)
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
64 if depth > maxdepth >= 0:
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
65 continue
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
66
4
aa0c2e9f5f59 Adapt to Mercurial API change
Martin Geisler <mg@aragost.com>
parents: 3
diff changeset
67 # subrepo.relpath was renamed to subrepo.subrelpath in
aa0c2e9f5f59 Adapt to Mercurial API change
Martin Geisler <mg@aragost.com>
parents: 3
diff changeset
68 # 18b5b6392fcf.
aa0c2e9f5f59 Adapt to Mercurial API change
Martin Geisler <mg@aragost.com>
parents: 3
diff changeset
69 if hasattr(subrepo, 'relpath'):
aa0c2e9f5f59 Adapt to Mercurial API change
Martin Geisler <mg@aragost.com>
parents: 3
diff changeset
70 relpath = subrepo.relpath(sub)
aa0c2e9f5f59 Adapt to Mercurial API change
Martin Geisler <mg@aragost.com>
parents: 3
diff changeset
71 else:
aa0c2e9f5f59 Adapt to Mercurial API change
Martin Geisler <mg@aragost.com>
parents: 3
diff changeset
72 relpath = subrepo.subrelpath(sub)
aa0c2e9f5f59 Adapt to Mercurial API change
Martin Geisler <mg@aragost.com>
parents: 3
diff changeset
73
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
74 if print0:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
75 ui.write(relpath, "\0")
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
76 else:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
77 ui.note(_("executing '%s' in %s\n") % (cmd, relpath))
3
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
78 if ignoreerrors:
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
79 onerr = None
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
80 else:
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
81 onerr = util.Abort
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
82 util.system(cmd, environ=dict(HG_SUBPATH=relpath,
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
83 HG_SUBURL=sub._path,
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
84 HG_SUBSTATE=sub._state[1],
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
85 HG_REPO=repo.root),
3
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
86 cwd=os.path.join(repo.root, relpath),
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
87 onerr=onerr,
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
88 errprefix=_('terminated onsub in %s') % relpath)
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
89
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
90 if isinstance(sub, subrepo.hgsubrepo):
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
91 rev = sub._state[1]
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
92 ctx = sub._repo[rev]
8
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
93 w = [(depth + 1, ctx.sub(subpath))
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
94 for subpath in sorted(ctx.substate)]
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
95 if depthfirst:
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
96 w.reverse()
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
97 work.extend(w)
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
98
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
99 cmdtable = {
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
100 "onsub":
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
101 (onsub,
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
102 [('b', 'breadth-first', None,
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
103 _('use breadth-first traversal')),
8
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
104 ('', 'max-depth', -1,
ecc4fd16555d Add --max-depth option to limit depth of recursion.
Greg Ward <greg@gerg.ca>
parents: 7
diff changeset
105 _('limit recursion to N levels (negative for no limit)'), 'N'),
3
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
106 ('', 'ignore-errors', None,
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
107 _('continue execution despite errors')),
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
108 ('0', 'print0', None,
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
109 _('end subrepository names with NUL, for use with xargs'))],
3
a2184bbf38e6 Implement --ignore-errors.
Martin Geisler <mg@lazybytes.net>
parents: 0
diff changeset
110 _('[-b] [-0] [--ignore-errors] CMD'))
0
e49f3bbfec4d Initial version.
Martin Geisler <mg@aragost.com>
parents:
diff changeset
111 }