diff options
author | Richard Maw <richard.maw@codethink.co.uk> | 2012-04-19 17:27:20 +0000 |
---|---|---|
committer | Richard Maw <richard.maw@codethink.co.uk> | 2012-04-19 17:28:57 +0000 |
commit | cc84de3d6ccd63e1d53a2f66815ff1f192a89d36 (patch) | |
tree | 9b93584d2461ce5e423ca70a282569cd45dd7563 | |
parent | 9dcffcaa08dfc40fd49969719fa3b984802fafe5 (diff) | |
download | morph-cc84de3d6ccd63e1d53a2f66815ff1f192a89d36.tar.gz |
add morphology factory
-rw-r--r-- | morphlib/morphologyfactory.py | 63 | ||||
-rw-r--r-- | morphlib/morphologyfactory_tests.py | 90 |
2 files changed, 153 insertions, 0 deletions
diff --git a/morphlib/morphologyfactory.py b/morphlib/morphologyfactory.py new file mode 100644 index 00000000..5e3bf7f2 --- /dev/null +++ b/morphlib/morphologyfactory.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +# +# 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 cliapp + +class MorphologyFactoryError(cliapp.AppException): + pass + +class AutodetectError(MorphologyFactoryError): + def __init__(self, repo_name, ref): + MorphologyFactoryError.__init__(self, + "Failed to determine the build system of repo %s at " + "ref %s" % (repo_name, ref)) + +class MorphologyFactory(object): + '''An way of creating morphologies which will provide a default''' + + def __init__(self, local_repo_cache, remote_repo_cache): + self._lrc = local_repo_cache + self._rrc = remote_repo_cache + + def get_morphology(self, reponame, sha1, filename): + try: + text = self._cat_text(reponame, sha1, filename) + except: + text = self._autodetect_text(reponame, sha1, filename) + return morphlib.morph2.Morphology(text) + + def _cat_text(self, reponame, sha1, filename): + if self._lrc.has_repo(reponame): + repo = self._lrc.get_repo(reponame) + return repo.cat(sha1, filename) + else: + return self._rrc.cat_file(reponame, sha1, filename) + + def _autodetect_text(self, reponame, sha1, filename): + if self._lrc.has_repo(reponame): + repo = self._lrc.get_repo(reponame) + files = repo.list_files(sha1) + else: + files = self._rrc.list_files(reponame, sha1) + bs = morphlib.buildsystem.detect_build_system(lambda x: x in files) + if bs is None: + raise AutodetectError(reponame, sha1) + assert filename.endswith('.morph') + morph_name = filename[:-len('.morph')] + morph_text = bs.get_morphology_text(morph_name) + return morph_text diff --git a/morphlib/morphologyfactory_tests.py b/morphlib/morphologyfactory_tests.py new file mode 100644 index 00000000..2a0709ed --- /dev/null +++ b/morphlib/morphologyfactory_tests.py @@ -0,0 +1,90 @@ +# 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 unittest + +from morphlib.morph2 import Morphology +from morphlib.morphologyfactory import MorphologyFactory, AutodetectError + +class FakeRemoteRepoCache(object): + def cat_file(self, reponame, sha1, filename): + return '''{ + "name": "remote-foo", + "kind": "chunk", + "build-system": "bar" + }''' + def list_files(self, reponame, sha1): + return ['configure', 'Makefile'] + +class FakeLocalRepo(object): + def cat(self, sha1, filename): + return '''{ + "name": "local-foo", + "kind": "chunk", + "build-system": "bar" + }''' + def list_files(self, sha1): + return ['configure', 'Makefile'] + +class FakeLocalRepoCache(object): + def __init__(self, lr): + self.lr = lr + def has_repo(self, reponame): + return True + def get_repo(self, reponame): + return self.lr + +class MorphologyFactoryTests(unittest.TestCase): + def setUp(self): + self.lr = FakeLocalRepo() + self.lrc = FakeLocalRepoCache(self.lr) + self.rrc = FakeRemoteRepoCache() + self.mf = MorphologyFactory(self.lrc, self.rrc) + + def nosuchfile(self): + raise IOError('File not found') + def doesnothaverepo(self, reponame): + return False + + def test_gets_morph_from_local_repo(self): + morph = self.mf.get_morphology('reponame', 'sha1', 'foo.morph') + self.assertEqual('local-foo', morph['name']) + + def test_gets_morph_from_remote_repo(self): + self.lrc.has_repo = self.doesnothaverepo + morph = self.mf.get_morphology('reponame', 'sha1', 'foo.morph') + self.assertEqual('remote-foo', morph['name']) + + def test_autodetects_local_morphology(self): + self.lr.cat = self.nosuchfile + morph = self.mf.get_morphology('reponame', 'sha1', + 'assumed-local.morph') + self.assertEqual('assumed-local', morph['name']) + + def test_autodetects_remote_morphology(self): + self.lrc.has_repo = self.doesnothaverepo + self.rrc.cat_file = self.nosuchfile + morph = self.mf.get_morphology('reponame', 'sha1', + 'assumed-remote.morph') + self.assertEqual('assumed-remote', morph['name']) + + def test_raises_error_when_fails_detect(self): + self.lr.cat = self.nosuchfile + self.rrc.cat_file = self.nosuchfile + self.lr.list_files = lambda x: ['.'] + self.rrc.list_files = lambda x: ['.'] + self.assertRaises(AutodetectError, self.mf.get_morphology, + 'reponame', 'sha1', 'unreached.morph') |