ui: change default path fallback mechanism (issue4796)
authorGregory Szorc <gregory.szorc@gmail.com>
Sun, 06 Sep 2015 11:28:48 -0700
changeset 26189 663fbc336e22
parent 26188 662ea52d5dca
child 26190 29d29a82263f
ui: change default path fallback mechanism (issue4796) The previous paths API code always fell back to the default path. This was wrong because if a requested path doesn't exist, that should error. Only if no path was requested should we fall back to the default. As part of implementing the test case for issue 4796, it was discovered that the "repository does not exist" error message raised by localrepository.__init__ wasn't being seen because the paths API validates paths before localrepository.__init__ was being called. The exception and error message from localrepository.__init__ has been introduced to getpath(). This necessitated rewriting expandpath() both to catch the exception and to have proper default fallback. This code is more complicated than I'd like. But making all tests pass was a big chore. As more code moves to getpath(), there will likely be opportunities to improve things a bit.
mercurial/ui.py
tests/test-default-push.t
--- a/mercurial/ui.py	Mon Sep 07 21:58:17 2015 +0900
+++ b/mercurial/ui.py	Sun Sep 06 11:28:48 2015 -0700
@@ -550,9 +550,21 @@
 
     def expandpath(self, loc, default=None):
         """Return repository location relative to cwd or from [paths]"""
-        p = self.paths.getpath(loc, default=default)
-        if p:
-            return p.rawloc
+        try:
+            p = self.paths.getpath(loc)
+            if p:
+                return p.rawloc
+        except error.RepoError:
+            pass
+
+        if default:
+            try:
+                p = self.paths.getpath(default)
+                if p:
+                    return p.rawloc
+            except error.RepoError:
+                pass
+
         return loc
 
     @util.propertycache
@@ -1014,9 +1026,24 @@
         ``name`` can be a named path or locations. Locations are filesystem
         paths or URIs.
 
-        Returns the first of ``name`` or ``default`` that is present, or None
-        if neither is present.
+        Returns None if ``name`` is not a registered path, a URI, or a local
+        path to a repo.
         """
+        # Only fall back to default if no path was requested.
+        if name is None:
+            if default:
+                try:
+                    return self[default]
+                except KeyError:
+                    return None
+            else:
+                return None
+
+        # Most likely empty string.
+        # This may need to raise in the future.
+        if not name:
+            return None
+
         try:
             return self[name]
         except KeyError:
@@ -1024,15 +1051,10 @@
             try:
                 return path(None, rawloc=name)
             except ValueError:
-                pass
+                raise error.RepoError(_('repository %s does not exist') %
+                                        name)
 
-            if default is not None:
-                try:
-                    return self[default]
-                except KeyError:
-                    pass
-
-        return None
+        assert False
 
 class path(object):
     """Represents an individual path and its configuration."""
--- a/tests/test-default-push.t	Mon Sep 07 21:58:17 2015 +0900
+++ b/tests/test-default-push.t	Sun Sep 06 11:28:48 2015 -0700
@@ -45,3 +45,9 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
+
+Pushing to a path that isn't defined should not fall back to default
+
+  $ hg --cwd b push doesnotexist
+  abort: repository doesnotexist does not exist!
+  [255]