summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis Pohlmann <jannis.pohlmann@codethink.co.uk>2012-05-04 14:47:59 +0000
committerJannis Pohlmann <jannis.pohlmann@codethink.co.uk>2012-05-04 14:47:59 +0000
commit1bae1c3f268ddc80e5466ff714ae1b5873754c47 (patch)
tree8bc4c7627cb2218db47c01fa84e5d7539b320916
parent3fe9adac5bedbd9b419b9dd1447999be3555baf1 (diff)
downloadmorph-1bae1c3f268ddc80e5466ff714ae1b5873754c47.tar.gz
Add new RepoAliasResolver class to resolve repo names with aliases.
-rw-r--r--morphlib/__init__.py1
-rw-r--r--morphlib/repoaliasresolver.py83
-rw-r--r--morphlib/repoaliasresolver_tests.py79
3 files changed, 163 insertions, 0 deletions
diff --git a/morphlib/__init__.py b/morphlib/__init__.py
index de1b9f85..23d9f8b6 100644
--- a/morphlib/__init__.py
+++ b/morphlib/__init__.py
@@ -46,6 +46,7 @@ import morph2
import morphologyfactory
import remoteartifactcache
import remoterepocache
+import repoaliasresolver
import savefile
import source
import sourcepool
diff --git a/morphlib/repoaliasresolver.py b/morphlib/repoaliasresolver.py
new file mode 100644
index 00000000..3daf34dd
--- /dev/null
+++ b/morphlib/repoaliasresolver.py
@@ -0,0 +1,83 @@
+# Copyright (C) 2012 Codethink Limited
+#
+# 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; version 2 of the License.
+#
+# 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.
+
+
+import logging
+import re
+
+
+class RepoAliasResolver(object):
+
+ def __init__(self, aliases):
+ self.aliases = aliases
+
+ def pull_url(self, reponame):
+ '''Expand a possibly shortened repo name to a pull url.'''
+ return self._expand_reponame(reponame, 'pullpat')
+
+ def push_url(self, reponame):
+ '''Expand a possibly shortened repo name to a push url.'''
+ return self._expand_reponame(reponame, 'pushpat')
+
+ def _expand_reponame(self, reponame, patname):
+ logging.debug('expanding: reponame=%s' % reponame)
+ logging.debug('expanding: patname=%s' % patname)
+
+ prefix, suffix = self._split_reponame(reponame)
+ logging.debug('expanding: prefix=%s' % prefix)
+ logging.debug('expanding: suffix=%s' % suffix)
+
+ # There was no prefix.
+ if prefix is None:
+ logging.debug('expanding: no prefix')
+ return reponame
+
+ pat = r'^(?P<prefix>[a-z0-9]+)=(?P<pullpat>[^#]+)#(?P<pushpat>[^#]+)$'
+ for alias in self.aliases:
+ logging.debug('expanding: alias="%s"' % alias)
+ m = re.match(pat, alias)
+ logging.debug('expanding: m=%s' % repr(m))
+ if m:
+ logging.debug('expanding: prefix group=%s' % m.group('prefix'))
+ if m and m.group('prefix') == prefix:
+ pullpat = m.group(patname)
+ logging.debug('expanding: pullpat=%s' % pullpat)
+ return self._apply_url_pattern(pullpat, suffix)
+
+ # Unknown prefix. Which means it may be a real URL instead.
+ # Let the caller deal with it.
+ logging.debug('expanding: unknown prefix')
+ return reponame
+
+ def _split_reponame(self, reponame):
+ '''Split reponame into prefix and suffix.
+
+ The prefix is returned as None if there was no prefix.
+
+ '''
+
+ pat = r'^(?P<prefix>[a-z0-9]+):(?P<rest>.*)$'
+ m = re.match(pat, reponame)
+ if m:
+ return m.group('prefix'), m.group('rest')
+ else:
+ return None, reponame
+
+ def _apply_url_pattern(self, pattern, shortname):
+ if '%s' in pattern:
+ return shortname.join(pattern.split('%s'))
+ else:
+ return pattern + shortname
+
diff --git a/morphlib/repoaliasresolver_tests.py b/morphlib/repoaliasresolver_tests.py
new file mode 100644
index 00000000..fc6095ca
--- /dev/null
+++ b/morphlib/repoaliasresolver_tests.py
@@ -0,0 +1,79 @@
+# Copyright (C) 2012 Codethink Limited
+#
+# 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; version 2 of the License.
+#
+# 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.
+
+
+import morphlib
+import unittest
+
+
+class RepoAliasResolverTests(unittest.TestCase):
+
+ def setUp(self):
+ self.aliases = [
+ 'upstream='
+ 'git://gitorious.org/baserock-morphs/%s#'
+ 'git@gitorious.org:baserock-morphs/%s.git',
+ 'baserock='
+ 'git://gitorious.org/baserock/%s#'
+ 'git@gitorious.org:baserock/%s.git',
+ 'append='
+ 'git://append/#'
+ 'git@append/',
+ ]
+ self.resolver = morphlib.repoaliasresolver.RepoAliasResolver(
+ self.aliases)
+
+ def test_resolve_urls_without_alias_prefix(self):
+ self.assertEqual(self.resolver.pull_url('bar'), 'bar')
+ self.assertEqual(self.resolver.push_url('bar'), 'bar')
+
+ self.assertEqual(self.resolver.pull_url('foo'), 'foo')
+ self.assertEqual(self.resolver.push_url('foo'), 'foo')
+
+ def test_resolve_urls_for_repos_of_one_alias(self):
+ url = self.resolver.pull_url('upstream:foo')
+ self.assertEqual(url, 'git://gitorious.org/baserock-morphs/foo')
+ url = self.resolver.push_url('upstream:foo')
+ self.assertEqual(url, 'git@gitorious.org:baserock-morphs/foo.git')
+
+ url = self.resolver.pull_url('upstream:bar')
+ self.assertEqual(url, 'git://gitorious.org/baserock-morphs/bar')
+ url = self.resolver.push_url('upstream:bar')
+ self.assertEqual(url, 'git@gitorious.org:baserock-morphs/bar.git')
+
+ def test_resolve_urls_for_repos_of_another_alias(self):
+ url = self.resolver.pull_url('baserock:foo')
+ self.assertEqual(url, 'git://gitorious.org/baserock/foo')
+ url = self.resolver.push_url('baserock:foo')
+ self.assertEqual(url, 'git@gitorious.org:baserock/foo.git')
+
+ url = self.resolver.pull_url('baserock:bar')
+ self.assertEqual(url, 'git://gitorious.org/baserock/bar')
+ url = self.resolver.push_url('baserock:bar')
+ self.assertEqual(url, 'git@gitorious.org:baserock/bar.git')
+
+ def test_resolve_urls_for_unknown_alias(self):
+ self.assertEqual(self.resolver.pull_url('unknown:foo'), 'unknown:foo')
+ self.assertEqual(self.resolver.push_url('unknown:foo'), 'unknown:foo')
+
+ self.assertEqual(self.resolver.pull_url('unknown:bar'), 'unknown:bar')
+ self.assertEqual(self.resolver.push_url('unknown:bar'), 'unknown:bar')
+
+ def test_resolve_urls_for_pattern_without_placeholder(self):
+ self.assertEqual(self.resolver.pull_url('append:foo'), 'git://append/foo')
+ self.assertEqual(self.resolver.push_url('append:foo'), 'git@append/foo')
+
+ self.assertEqual(self.resolver.pull_url('append:bar'), 'git://append/bar')
+ self.assertEqual(self.resolver.push_url('append:bar'), 'git@append/bar')