[PATCH 5 of 5 paths v3] ui: move URL and path detection into getpath()

Gregory Szorc gregory.szorc at gmail.com
Sun Mar 8 14:54:18 CDT 2015


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1423427350 28800
#      Sun Feb 08 12:29:10 2015 -0800
# Node ID 6c3e9b2db9bbe61b474bacb80d4c66baec0cf5d4
# Parent  46c14d03f3e05aa9992d074311c5e92924c2dda3
ui: move URL and path detection into getpath()

ui.expandpath() has code for recognizing URLs or local filesystem
paths. Our goal is to use path instances in more locations. Since many
call sites pass in arguments that could be URLs or filesystem paths,
we move this code into paths.getpath() so that more callers can be
switched to using the new API directly instead of ui.expandpath().

The added check for whether ``name`` is defined is added because
future callers may pass in empty values (expandpath doesn't
appear to receive empty values today).

Upcoming patches will perform additional processing on the "local"
argument to path.__init__. For now, we don't distinguish between the
origin and shoehorn everything into "loc."

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -528,11 +528,8 @@ class ui(object):
         return user
 
     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
-
         if loc == 'default-push':
             p = self.paths.getpath(loc, default=True)
         elif loc == 'default':
             p = self.paths.getpath(loc)
@@ -957,15 +954,19 @@ class paths(dict):
 
             self[name] = path(name, rawloc=loc)
 
     def getpath(self, name, default=False):
-        """Return a ``path`` for the specified name, falling back to a default.
+        """Return a ``path`` from a string.
+
+        Arguments can be named paths (from the config) or locations. Locations
+        are URIs or filesystem paths that are directories having ``.hg``
+        directories.
 
         If ``default`` is True, we attempt to resolve the default path.
         If ``default`` is the string ``push``, we attempt to resolve the
         default push path.
 
-        Returns ``None`` if a path could not be found.
+        Returns ``None`` if a path could not be resolved.
         """
         try:
             return self[name]
         except KeyError:
@@ -983,18 +984,39 @@ class paths(dict):
                 return self['default']
             except KeyError:
                 pass
 
+        try:
+            return path(name)
+        except ValueError:
+            pass
+
         return None
 
 class path(object):
     """Represents an individual path and its configuration."""
 
     def __init__(self, name, rawloc=None):
         """Construct a path from its config options.
 
-        ``name`` is the symbolic name of the path.
+        ``name`` is the symbolic name of the path or location.
         ``rawloc`` is the raw location, as defined in the config.
+
+        When ``rawloc`` isn't defined, we assume ``name`` is the location.
+        In this form, we require that the location be a local filesystem
+        path to a known repository or a URL. If not, ``ValueError`` is
+        raised.
         """
+        if name and not rawloc:
+            if util.hasscheme(name):
+                self.name = None
+                self.loc = name
+            elif os.path.isdir(os.path.join(name, '.hg')):
+                self.name = name
+                self.loc = name
+            else:
+                raise ValueError('location is not a URL or path to a local '
+                                 'repo: %s' % name)
+            return
+
         self.name = name
-        # We'll do more intelligent things with rawloc in the future.
         self.loc = rawloc


More information about the Mercurial-devel mailing list