diff onsub.py @ 0:e49f3bbfec4d

Initial version.
author Martin Geisler <mg@aragost.com>
date Mon, 06 Sep 2010 12:09:47 +0200
parents
children a2184bbf38e6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/onsub.py	Mon Sep 06 12:09:47 2010 +0200
@@ -0,0 +1,83 @@
+
+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'))
+
+def foreach(ui, repo, cmd, depthfirst, print0):
+    """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)
+
+        relpath = subrepo.relpath(sub)
+        if print0:
+            ui.write(relpath, "\0")
+        else:
+            ui.note(_("executing '%s' in %s\n") % (cmd, relpath))
+        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=util.Abort,
+                    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')),
+          ('0', 'print0', None,
+           _('end subrepository names with NUL, for use with xargs'))],
+         _('[-b] [-0] CMD'))
+}