summaryrefslogtreecommitdiff
path: root/bzrlib/directory_service.py
diff options
context:
space:
mode:
authorLorry <lorry@roadtrain.codethink.co.uk>2012-08-22 15:47:16 +0100
committerLorry <lorry@roadtrain.codethink.co.uk>2012-08-22 15:47:16 +0100
commit25335618bf8755ce6b116ee14f47f5a1f2c821e9 (patch)
treed889d7ab3f9f985d0c54c534cb8052bd2e6d7163 /bzrlib/directory_service.py
downloadbzr-tarball-25335618bf8755ce6b116ee14f47f5a1f2c821e9.tar.gz
Tarball conversion
Diffstat (limited to 'bzrlib/directory_service.py')
-rw-r--r--bzrlib/directory_service.py152
1 files changed, 152 insertions, 0 deletions
diff --git a/bzrlib/directory_service.py b/bzrlib/directory_service.py
new file mode 100644
index 0000000..eac7d8d
--- /dev/null
+++ b/bzrlib/directory_service.py
@@ -0,0 +1,152 @@
+# Copyright (C) 2008, 2009, 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Directory service registration and usage.
+
+Directory services are utilities that provide a mapping from URL-like strings
+to true URLs. Examples include lp:urls and per-user location aliases.
+"""
+
+from __future__ import absolute_import
+
+from bzrlib import (
+ errors,
+ registry,
+ )
+from bzrlib.lazy_import import lazy_import
+lazy_import(globals(), """
+from bzrlib import (
+ branch as _mod_branch,
+ controldir as _mod_controldir,
+ urlutils,
+ )
+""")
+
+
+class DirectoryServiceRegistry(registry.Registry):
+ """This object maintains and uses a list of directory services.
+
+ Directory services may be registered via the standard Registry methods.
+ They will be invoked if their key is a prefix of the supplied URL.
+
+ Each item registered should be a factory of objects that provide a look_up
+ method, as invoked by dereference. Specifically, look_up should accept a
+ name and URL, and return a URL.
+ """
+
+ def dereference(self, url):
+ """Dereference a supplied URL if possible.
+
+ URLs that match a registered directory service prefix are looked up in
+ it. Non-matching urls are returned verbatim.
+
+ This is applied only once; the resulting URL must not be one that
+ requires further dereferencing.
+
+ :param url: The URL to dereference
+ :return: The dereferenced URL if applicable, the input URL otherwise.
+ """
+ match = self.get_prefix(url)
+ if match is None:
+ return url
+ service, name = match
+ return service().look_up(name, url)
+
+directories = DirectoryServiceRegistry()
+
+class AliasDirectory(object):
+ """Directory lookup for locations associated with a branch.
+
+ :parent, :submit, :public, :push, :this, and :bound are currently
+ supported. On error, a subclass of DirectoryLookupFailure will be raised.
+ """
+
+ branch_aliases = registry.Registry()
+ branch_aliases.register('parent', lambda b: b.get_parent(),
+ help="The parent of this branch.")
+ branch_aliases.register('submit', lambda b: b.get_submit_branch(),
+ help="The submit branch for this branch.")
+ branch_aliases.register('public', lambda b: b.get_public_branch(),
+ help="The public location of this branch.")
+ branch_aliases.register('bound', lambda b: b.get_bound_location(),
+ help="The branch this branch is bound to, for bound branches.")
+ branch_aliases.register('push', lambda b: b.get_push_location(),
+ help="The saved location used for `bzr push` with no arguments.")
+ branch_aliases.register('this', lambda b: b.base,
+ help="This branch.")
+
+ def look_up(self, name, url):
+ branch = _mod_branch.Branch.open_containing('.')[0]
+ parts = url.split('/', 1)
+ if len(parts) == 2:
+ name, extra = parts
+ else:
+ (name,) = parts
+ extra = None
+ try:
+ method = self.branch_aliases.get(name[1:])
+ except KeyError:
+ raise errors.InvalidLocationAlias(url)
+ else:
+ result = method(branch)
+ if result is None:
+ raise errors.UnsetLocationAlias(url)
+ if extra is not None:
+ result = urlutils.join(result, extra)
+ return result
+
+ @classmethod
+ def help_text(cls, topic):
+ alias_lines = []
+ for key in cls.branch_aliases.keys():
+ help = cls.branch_aliases.get_help(key)
+ alias_lines.append(" :%-10s%s\n" % (key, help))
+ return """\
+Location aliases
+================
+
+Bazaar defines several aliases for locations associated with a branch. These
+can be used with most commands that expect a location, such as `bzr push`.
+
+The aliases are::
+
+%s
+For example, to push to the parent location::
+
+ bzr push :parent
+""" % "".join(alias_lines)
+
+
+directories.register(':', AliasDirectory,
+ 'Easy access to remembered branch locations')
+
+
+class ColocatedDirectory(object):
+ """Directory lookup for colocated branches.
+
+ co:somename will resolve to the colocated branch with "somename" in
+ the current directory.
+ """
+
+ def look_up(self, name, url):
+ dir = _mod_controldir.ControlDir.open_containing('.')[0]
+ return urlutils.join_segment_parameters(dir.user_url,
+ {"branch": urlutils.escape(name)})
+
+
+directories.register('co:', ColocatedDirectory,
+ 'Easy access to colocated branches')
+