[PATCH 1 of 2] paths: Command editable remote paths

Victor Suba vosuba at gmail.com
Sun Nov 13 14:31:51 CST 2011


# HG changeset patch
# User Victor Suba <vosuba at gmail.com>
# Date 1321177468 28800
# Node ID 64efea9f1a8cc6caf370b3967d2b22ac36e9e5de
# Parent  1bb0a5b02da9ef3505bfb4ac02b2d51cf220220f
paths: Command editable remote paths.

diff -r 1bb0a5b02da9 -r 64efea9f1a8c mercurial/commands.py
--- a/mercurial/commands.py	Thu Nov 10 17:06:30 2011 -0600
+++ b/mercurial/commands.py	Sun Nov 13 01:44:28 2011 -0800
@@ -9,7 +9,7 @@
 from lock import release
 from i18n import _, gettext
 import os, re, difflib, time, tempfile, errno
-import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
+import hg, scmutil, util, revlog, extensions, copies, error, bookmarks, pathsutil
 import patch, help, url, encoding, templatekw, discovery
 import archival, changegroup, cmdutil, hbisect
 import sshserver, hgweb, hgweb.server, commandserver
@@ -4120,9 +4120,14 @@
             displayer.show(repo[n])
     displayer.close()
 
- at command('paths', [], _('[NAME]'))
-def paths(ui, repo, search=None):
-    """show aliases for remote repositories
+ at command('paths',
+    [('f', 'force', False, _('force')),
+     ('d', 'delete', False, _('delete a given path')),
+     ('r', 'rename', '', _('rename a given path'), _('NAME'))],
+    _('hg paths [-f] [-d] [-m NAME] [NAME] [URL]'))
+def paths(ui, repo, name=None, url=None, force=False, delete=False,
+            rename=None):
+    """show, create or modify aliases for remote repositories
 
     Show definition of symbolic path name NAME. If no name is given,
     show definition of all available names.
@@ -4149,16 +4154,52 @@
 
     Returns 0 on success.
     """
-    if search:
-        for name, path in ui.configitems("paths"):
-            if name == search:
-                ui.status("%s\n" % util.hidepassword(path))
-                return
-        if not ui.quiet:
-            ui.warn(_("not found!\n"))
-        return 1
+    if name:
+        if url or rename or delete:
+            if not name:
+                raise util.Abort(_("path NAME is missing"))
+            
+            if name in [x[0] for x in ui.configitems("paths")]:
+                raise util.Abort(_("path '%s' exists in [paths] and can't be modified") % name)
+            if rename in [x[0] for x in ui.configitems("paths")]:
+                raise util.Abort(_("path '%s' exists in [paths] and can't be modified") % rename)
+            
+            if rename:
+                if rename in ui._paths:
+                    if (name in ui._paths) and not force:
+                        raise util.Abort(_("path '%s' already exists "
+                                            "(use -f to force)") % name)
+                    url = ui._paths[rename]
+                    del ui._paths[rename]
+                    ui._paths[name] = url
+                    ui.writePaths()
+                    return 0
+                else:
+                    raise util.Abort(_("path '%s' is not defined.\n") % rename)
+            elif delete:
+                if name in ui._paths:
+                    del ui._paths[name]
+                    ui.writePaths()
+                    return 0
+                else:
+                    raise util.Abort(_("path '%s' is not defined.\n") % name)
+            elif url:
+                if (name in ui._paths) and not force:
+                    raise util.Abort(_("path '%s' already exists "
+                                        "(use -f to force)") % name)
+                ui._paths[name] = url
+                ui.writePaths()
+                return 0
+        else:
+            for pname, path in ui.allpaths():
+                if pname == name:
+                    ui.status("%s\n" % util.hidepassword(path))
+                    return
+            if not ui.quiet:
+                ui.warn(_("not found!\n"))
+            return 1
     else:
-        for name, path in ui.configitems("paths"):
+        for name, path in ui.allpaths():
             if ui.quiet:
                 ui.write("%s\n" % name)
             else:
diff -r 1bb0a5b02da9 -r 64efea9f1a8c mercurial/pathsutil.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/pathsutil.py	Sun Nov 13 01:44:28 2011 -0800
@@ -0,0 +1,37 @@
+# Managed remote paths implementation
+#
+# Copyright 2011 Victor Suba Miura <vosuba at gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+import os
+import util
+
+def read():
+    paths = {}
+    try:
+        fp = open(".hg/paths")
+    except IOError:
+        return paths
+    
+    for line in fp.readlines():
+        line = line.strip()
+        if not line:
+            continue
+        if ' ' not in line:
+            repo.ui.warn(_('malformed line in .hg/paths: %r\n') % line)
+            continue
+        path, url = line.split(' ', 1)
+        paths[path] = url
+        
+    fp.close()
+    return paths
+        
+def write(paths):
+    fp = open(".hg/paths", "w")
+    for path, url in paths.items():
+        fp.write("%s %s\n" % (path, url))
+    fp.close()
+
+
diff -r 1bb0a5b02da9 -r 64efea9f1a8c mercurial/ui.py
--- a/mercurial/ui.py	Thu Nov 10 17:06:30 2011 -0600
+++ b/mercurial/ui.py	Sun Nov 13 01:44:28 2011 -0800
@@ -6,7 +6,7 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import errno, getpass, os, socket, sys, tempfile, traceback
+import errno, getpass, os, socket, sys, tempfile, traceback, pathsutil
 import config, scmutil, util, error
 
 class ui(object):
@@ -42,7 +42,12 @@
             # we always trust global config files
             for f in scmutil.rcpath():
                 self.readconfig(f, trust=True)
+        
+        self._paths = pathsutil.read()
 
+    def writePaths(self):
+        pathsutil.write(self._paths)
+        
     def copy(self):
         return self.__class__(self)
 
@@ -411,13 +416,26 @@
         if not self.verbose:
             user = util.shortuser(user)
         return user
-
+    
+    def allpaths(self):
+        """Gather paths from hgrc config, and .hg/paths and return sorted list"""
+        paths = {}
+        for alias, url in self.configitems("paths"):
+            paths[alias] = url
+        for alias, url in self._paths.items():
+            if alias not in paths:
+                paths[alias] = url
+                
+        return [(alias, paths[alias]) for alias in sorted(paths.keys())]
+    
     def expandpath(self, loc, default=None):
         """Return repository location relative to cwd or from [paths]"""
         if util.hasscheme(loc) or os.path.isdir(os.path.join(loc, '.hg')):
             return loc
 
         path = self.config('paths', loc)
+        if not path:
+            path = self._paths.get(loc, None)
         if not path and default is not None:
             path = self.config('paths', default)
         return path or loc


More information about the Mercurial-devel mailing list