Commits

davidjade  committed 445306e

reworked to use ACTION parameter for hg commands instead of flags
added -all flag to process current repo as well as all subrepos
removed -noRecurse and added -recurse flag (recurse is no longer the default)
removed automatic recloning of missing subrepos by default (must use -c to reclone missing)
added extension config setting for forcing -all flag for user-defined commands

  • Participants
  • Parent commits 7f02223

Comments (0)

Files changed (1)

 
 from mercurial.i18n import _
 from hgext.fetch import fetch
-from mercurial import hg, util
+from mercurial import hg, util, commands
 import os, string
 
-def subrepo(ui, repo, **opts):
+def subrepo(ui, repo, action=None, **opts):
     '''allows for easy(er) management of mutiple subrepositories at once
 
     This extension provides the ability to batch-process subrepositories
-    with a few defined commands. Each command generally loops through the
+    with hg commands. Each command generally loops through the 
     subrepositories listed in .hgsub, and simply calls an hg action.
 
     Subrepositories can be complicated, and this extension should not be
     used as a bludgeon, but rather a scalpal. It is for the occasions that
     active development of the main repo is dependent on the subrepos having
-    the newest, bleeding edge code. This extension is nothing
-    but a series of for loops!
+    the newest, bleeding edge code. This extension is nothing but a series 
+    of for loops!
 
     Watch the output in case user intervention / remediation is required,
     and always remember that updating subrepos will usually require a commit
 
     optList = opts.get('list', None)
     optReclone = opts.get('reclone', None)
-    optPull = opts.get('pull', None)
-    optUpdate = opts.get('update', None)
-    optIncoming = opts.get('incoming', None)
-    optOutgoing = opts.get('outgoing', None)
-    optFetch = opts.get('fetch', None)
-    optStatus = opts.get('status', None)
-    optNoRecurse = opts.get('norecurse', None)
-    optMap = opts.get('map', None)
+    optRecurse = opts.get('recurse', None)
+    optAll = opts.get('all', None)
 
     if optList:
         ui.status("listing subrepos:\n-------\n")
         func = lambda repoPath, remotePath: ListRepo(ui, repoPath, remotePath)
-        doCommand(ui, repo, func, False, optNoRecurse)
+        doCommand(ui, repo, func, (optRecurse or optAll), False)	# never use doForAll for listing subrepos
         ui.status("-------\n")
+        return
 
     if optReclone:
         ui.status("checking for missing subrepo clones...\n")
-        func = lambda repoPath, remotePath: doReclone(ui, repoPath, remotePath)
-        doCommand(ui, repo, func, True, optNoRecurse)
+        doReclone(ui, repo, (optRecurse or optAll))
         ui.status("finishing recloning\n")
+        if action == None: return
 
-    if optPull:
-        ui.status("pulling all subrepos...\n")
-        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, remotePath, "pull")
-        doCommand(ui, repo, func, True, optNoRecurse)
+    if action == None:
+        ui.status("hg subrepo: missing action\n")
+        commands.help_(ui, "subrepo")
+    else:
+        # force optAll mode for user-defined actions
+        forceAllForCommands = ui.config("subrepo", "forceAllForCommands")
+        if not forceAllForCommands == None:
+            if action in (forceAllForCommands.split(';')): optAll = True
+
+        # do action for all subrepos
+        ui.status("doing '%s' for all subrepos, watch output for necessity of user intervention...\n" % action)
+        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, action)
+        doCommand(ui, repo, func, (optRecurse or optAll), optAll)
         ui.status("---------------------------\n")
 
-    if optUpdate:
-        ui.status("updating all subrepos to tip, watch output for necessity of user intervention...\n")
-        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, remotePath, "update")
-        doCommand(ui, repo, func, True, optNoRecurse)
-        ui.status("---------------------------\n")
-
-    if optIncoming:
-        ui.status("getting incoming changesets for all subrepos\n")
-        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, remotePath, "incoming")
-        doCommand(ui, repo, func, False, optNoRecurse)
-        ui.status("---------------------------\n")
-
-    if optOutgoing:
-        ui.status("getting outgoing changesets for all subrepos\n")
-        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, remotePath, "outgoing")
-        doCommand(ui, repo, func, False, optNoRecurse)
-        ui.status("---------------------------\n")
-
-    if optFetch:
-        ui.status("fetching all subrepos, watch output for necessity of user intervention...\n")
-        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, remotePath, "fetch")
-        doCommand(ui, repo, func, True, optNoRecurse)
-        ui.status("---------------------------\n")
-        ui.status("finished fetching, be sure to commit parent repo to update .hgsubstate\n")
-
-    if optStatus:
-        ui.status("getting status for all subrepos\n")
-        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, remotePath, "status")
-        doCommand(ui, repo, func, False, optNoRecurse)
-        ui.status("---------------------------\n")
-
-    if optMap:
-        ui.status("mapping '%s' for all subrepos\n" % opts['map'])
-        func = lambda repoPath, remotePath: doHgTextCommand(ui, repoPath, remotePath, opts['map'])
-        doCommand(ui, repo, func, True, optNoRecurse)
-        ui.status("---------------------------\n")
+        # special messages for some actions
+        if action == "fetch": ui.status("finished fetching, be sure to commit parent repo to update .hgsubstate\n")
 
 
 # execute a function for each subrepo with optional recloning and optional recursion
 # func is defined as func(localPath, remotePath)
-def doCommand(ui, repo, func, cloneMissing, noRecurse, relativePath=""):
+def doCommand(ui, repo, func, recurse, doForRoot, relativePath=""):
+    if relativePath == "" and doForRoot:
+        func(".", ui.config('paths', 'default'))
     if os.path.exists(os.path.join(repo.root, ".hgsub")):
         for local, remote in getSubreposFromHgsub(repo):
             subrepoPath = os.path.join(relativePath, local)
-            if not os.path.exists(subrepoPath) and cloneMissing:
-                recloneSubrepo(ui, subrepoPath, remote)
             if os.path.exists(subrepoPath):
                 func(subrepoPath, remote)
-                if not noRecurse:
-                    doCommand(ui, hg.repository(ui, subrepoPath, False), func, cloneMissing, noRecurse, subrepoPath)
+                if recurse:
+                    doCommand(ui, hg.repository(ui, subrepoPath, False), func, recurse, doForRoot, subrepoPath)
             else:
                 ui.status("* %s is missing (perhaps you should reclone)\n" % subrepoPath)
 
 
 
-def doHgTextCommand(ui, repoPath, remotePath, commandText):
+def doHgTextCommand(ui, repoPath, commandText):
     ui.status("---------------------------\n")
     ui.status("* %s\n" % repoPath)
     currentwd = os.getcwd()
     ui.status("* %s\t@ %s\n" %(repoPath, remotePath))
 
 
-def doReclone(ui, repoPath, remotePath):
-    return
-
-
 def getSubreposFromHgsub(repo):
     # XXX arguably this could, or should use:
     #  mercurial.subrepo.state(repo['.'])
     return [map(string.strip, line.split('=')) for line in f]
 
 
+# reclone all missing subrepos
+def doReclone(ui, repo, recurse, relativePath=""):
+    if os.path.exists(os.path.join(repo.root, ".hgsub")):
+        for local, remote in getSubreposFromHgsub(repo):
+            subrepoPath = os.path.join(relativePath, local)
+            if os.path.exists(subrepoPath):
+                ui.status("* %s exists \n" % subrepoPath)
+            else:
+                recloneSubrepo(ui, subrepoPath, remote)
+            if recurse:
+                doReclone(ui,  hg.repository(ui, subrepoPath, False), recurse, subrepoPath)
+
+
 def recloneSubrepo(ui, local, remote):
     # todo: clone at the revision specified in .hgsubstate?
     ui.status("* %s is missing, recloning...\n" % local);
 cmdtable = {
     "subrepo":
         (subrepo,
-         [('l', 'list', None, _('list registered subrepositories')),
-          ('c', 'reclone', None, _('reclone all missing but registered subrepositories (as defined in .hgsub), leaving existing ones intact; this does not look at nor modify .hgsubstate!')),
-          ('i', 'incoming', None, _('call hg incoming within each subrepository')),
-          ('o', 'outgoing', None, _('call hg outgoing within each subrepository')),
-          ('p', 'pull', None, _('call hg pull within each subrepository')),
-          ('u', 'update', None, _('call hg update within each subrepository')),
-          ('f', 'fetch', None, _('call hg fetch within each subrepository')),
-          ('s', 'status', None, _('call hg status within each subrepository')),
-          ('m', 'map', "", _('call hg \"CommandArgument\" within each subrepository')),
-          ('', 'norecurse', None, _('do not operate recursively within each subrepository'))
+         [
+          ('l', 'list', None, _('list registered subrepositories then quit')),
+          ('r', 'recurse', None, _('operate recursively within each subrepository')),
+          ('a', 'all', None, _('operate in root repo as well as recursively within each subrepository')),
+          ('c', 'reclone', None, _('reclone all missing but registered subrepositories (as defined in .hgsub), ' +
+		  'leaving existing ones intact; this does not look at nor modify .hgsubstate! ' +
+		  'If an ACTION is specified it will execute after recloning all missing subrepos.')),
          ],
-         _('hg subrepo [ACTION]'))
+         _('hg subrepo [-l] [-r] [-a] [-c] [ACTION] '))
 }