diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2011-05-10 10:21:26 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2011-05-10 10:21:26 +0200 |
commit | cd26aaebbda94dc3740e41bbd3f91ba6b1a25c10 (patch) | |
tree | 7ea33a01a8a33b3cea92e0f6872bb1c7b5279a5e | |
parent | 7ae36c3e019a5cc16924d1b6007774bfb625036f (diff) | |
download | gitpython-cd26aaebbda94dc3740e41bbd3f91ba6b1a25c10.tar.gz |
Made repository paths methods a property to be compatible with the existing repo interface. Added submodule interface ... goal is to provide all of the extra repo functionality in custom interfaces
-rw-r--r-- | git/db/compat.py | 13 | ||||
-rw-r--r-- | git/db/interface.py | 79 | ||||
-rw-r--r-- | git/db/py/base.py | 67 | ||||
-rw-r--r-- | git/db/py/complex.py | 5 | ||||
-rw-r--r-- | git/db/py/submodule.py | 33 | ||||
-rw-r--r-- | git/objects/submodule/__init__.py | 4 | ||||
-rw-r--r-- | git/objects/submodule/base.py | 4 | ||||
-rw-r--r-- | git/objects/submodule/root.py | 5 | ||||
-rw-r--r-- | git/objects/submodule/util.py | 4 | ||||
-rw-r--r-- | git/refs/log.py | 2 | ||||
-rw-r--r-- | git/refs/symbolic.py | 18 | ||||
-rw-r--r-- | git/repo/base.py | 39 | ||||
-rw-r--r-- | git/test/test_base.py | 27 | ||||
-rw-r--r-- | git/test/test_import.py | 14 |
14 files changed, 234 insertions, 80 deletions
diff --git a/git/db/compat.py b/git/db/compat.py new file mode 100644 index 00000000..1c0ba6f5 --- /dev/null +++ b/git/db/compat.py @@ -0,0 +1,13 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php +"""Module providing adaptors to maintain backwards compatability""" + +class RepoCompatInterface(object): + """Interface to install backwards compatability of the new complex repository + types with the previous, all in one, repository.""" + + @property + def bare(self): + return self.is_bare diff --git a/git/db/interface.py b/git/db/interface.py index b7c167c5..bdda70b3 100644 --- a/git/db/interface.py +++ b/git/db/interface.py @@ -6,7 +6,7 @@ __all__ = ( 'ObjectDBR', 'ObjectDBW', 'RootPathDB', 'CompoundDB', 'CachingDB', 'TransportDB', 'ConfigurationMixin', 'RepositoryPathsMixin', - 'RefSpec', 'FetchInfo', 'PushInfo', 'ReferencesMixin') + 'RefSpec', 'FetchInfo', 'PushInfo', 'ReferencesMixin', 'SubmoduleDB') class ObjectDBR(object): @@ -151,7 +151,7 @@ class RootPathDB(object): access.""" super(RootPathDB, self).__init__(root_path) - #{ Interface + #{ Interface def root_path(self): """:return: path at which this db operates""" raise NotImplementedError() @@ -390,33 +390,60 @@ class RepositoryPathsMixin(object): raise NotImplementedError() #} end subclass interface + #{ Object Interface + + def __eq__(self, rhs): + raise NotImplementedError() + + def __ne__(self, rhs): + raise NotImplementedError() + + def __hash__(self): + raise NotImplementedError() + + def __repr__(self): + raise NotImplementedError() + + #} END object interface + #{ Interface + @property def is_bare(self): """:return: True if this is a bare repository :note: this value is cached upon initialization""" raise NotImplementedError() - def git_path(self): + @property + def git_dir(self): """:return: path to directory containing this actual git repository (which in turn provides access to objects and references""" raise NotImplementedError() - def working_tree_path(self): + @property + def working_tree_dir(self): """:return: path to directory containing the working tree checkout of our git repository. :raise AssertionError: If this is a bare repository""" raise NotImplementedError() - def objects_path(self): + @property + def objects_dir(self): """:return: path to the repository's objects directory""" raise NotImplementedError() + @property def working_dir(self): """:return: working directory of the git process or related tools, being - either the working_tree_path if available or the git_path""" + either the working_tree_dir if available or the git_path""" raise NotImplementedError() - + + @property + def description(self): + """:return: description text associated with this repository or set the + description.""" + raise NotImplementedError() + #} END interface @@ -465,5 +492,43 @@ class ConfigurationMixin(object): repository = configuration file for this repostory only""" raise NotImplementedError() + #} END interface + +class SubmoduleDB(object): + """Interface providing access to git repository submodules. + The actual implementation is found in the Submodule object type, which is + currently only available in one implementation.""" + + @property + def submodules(self): + """ + :return: git.IterableList(Submodule, ...) of direct submodules + available from the current head""" + raise NotImplementedError() + + def submodule(self, name): + """ :return: Submodule with the given name + :raise ValueError: If no such submodule exists""" + raise NotImplementedError() + + def create_submodule(self, *args, **kwargs): + """Create a new submodule + + :note: See the documentation of Submodule.add for a description of the + applicable parameters + :return: created submodules""" + raise NotImplementedError() + + def iter_submodules(self, *args, **kwargs): + """An iterator yielding Submodule instances, see Traversable interface + for a description of args and kwargs + :return: Iterator""" + raise NotImplementedError() + + def submodule_update(self, *args, **kwargs): + """Update the submodules, keeping the repository consistent as it will + take the previous state into consideration. For more information, please + see the documentation of RootModule.update""" + raise NotImplementedError() diff --git a/git/db/py/base.py b/git/db/py/base.py index 5c470ba4..f45711d5 100644 --- a/git/db/py/base.py +++ b/git/db/py/base.py @@ -273,34 +273,70 @@ class PureRepositoryPathsMixin(RepositoryPathsMixin): # lets not assume the option exists, although it should pass #END check bare flag + + #} end subclass interface + + #{ Object Interface + + def __eq__(self, rhs): + if hasattr(rhs, 'git_dir'): + return self.git_dir == rhs.git_dir + return False + + def __ne__(self, rhs): + return not self.__eq__(rhs) + + def __hash__(self): + return hash(self.git_dir) + def __repr__(self): + return "%s(%r)" % (type(self).__name__, self.git_dir) - #} end subclass interface + #} END object interface #{ Interface + @property def is_bare(self): return self._bare - def git_path(self): + @property + def git_dir(self): return self._git_path - def working_tree_path(self): - if self.is_bare(): - raise AssertionError("Repository at %s is bare and does not have a working tree directory" % self.git_path()) + @property + def working_tree_dir(self): + if self.is_bare: + raise AssertionError("Repository at %s is bare and does not have a working tree directory" % self.git_dir) #END assertion - return dirname(self.git_path()) - - def objects_path(self): - return join(self.git_path(), self.objs_dir) - + return dirname(self.git_dir) + + @property + def objects_dir(self): + return join(self.git_dir, self.objs_dir) + + @property def working_dir(self): - if self.is_bare(): - return self.git_path() + if self.is_bare: + return self.git_dir else: - return self.working_tree_dir() + return self.working_tree_dir #END handle bare state + def _mk_description(): + def _get_description(self): + filename = join(self.git_dir, 'description') + return file(filename).read().rstrip() + + def _set_description(self, descr): + filename = join(self.git_dir, 'description') + file(filename, 'w').write(descr+'\n') + + return property(_get_description, _set_description, "Descriptive text for the content of the repository") + + description = _mk_description() + del(_mk_description) + #} END interface @@ -313,7 +349,7 @@ class PureConfigurationMixin(ConfigurationMixin): def __init__(self, *args, **kwargs): """Verify prereqs""" - assert hasattr(self, 'git_path') + assert hasattr(self, 'git_dir') def _path_at_level(self, level ): # we do not support an absolute path of the gitconfig on windows , @@ -327,7 +363,7 @@ class PureConfigurationMixin(ConfigurationMixin): elif level == "global": return normpath(expanduser("~/.%s" % self.system_config_file_name)) elif level == "repository": - return join(self.git_path(), self.repo_config_file_name) + return join(self.git_dir, self.repo_config_file_name) #END handle level raise ValueError("Invalid configuration level: %r" % level) @@ -346,5 +382,6 @@ class PureConfigurationMixin(ConfigurationMixin): def config_writer(self, config_level="repository"): return GitConfigParser(self._path_at_level(config_level), read_only=False) + #} END interface diff --git a/git/db/py/complex.py b/git/db/py/complex.py index 1f929e31..de68d4fd 100644 --- a/git/db/py/complex.py +++ b/git/db/py/complex.py @@ -15,6 +15,7 @@ from resolve import PureReferencesMixin from loose import PureLooseObjectODB from pack import PurePackedODB from ref import PureReferenceDB +from submodule import PureSubmoduleDB from git.util import ( LazyMixin, @@ -32,7 +33,7 @@ import os __all__ = ('PureGitODB', 'PureGitDB') -class PureGitODB(PureRootPathDB, PureObjectDBW, PureCompoundDB): +class PureGitODB(PureRootPathDB, PureObjectDBW, PureCompoundDB, PureSubmoduleDB): """A git-style object-only database, which contains all objects in the 'objects' subdirectory. :note: The type needs to be initialized on the ./objects directory to function, @@ -107,7 +108,7 @@ class PureGitDB(PureGitODB, PureRepositoryPathsMixin, PureConfigurationMixin, Pu def __init__(self, root_path): """Initialize ourselves on the .git directory, or the .git/objects directory.""" PureRepositoryPathsMixin._initialize(self, root_path) - super(PureGitDB, self).__init__(self.objects_path()) + super(PureGitDB, self).__init__(self.objects_dir) diff --git a/git/db/py/submodule.py b/git/db/py/submodule.py new file mode 100644 index 00000000..735f90b1 --- /dev/null +++ b/git/db/py/submodule.py @@ -0,0 +1,33 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php +from git.objects.submodule.base import Submodule +from git.objects.submodule.root import RootModule +from git.db.interface import SubmoduleDB + +__all__ = ["PureSubmoduleDB"] + +class PureSubmoduleDB(SubmoduleDB): + """Pure python implementation of submodule functionality""" + + @property + def submodules(self): + return Submodule.list_items(self) + + def submodule(self, name): + try: + return self.submodules[name] + except IndexError: + raise ValueError("Didn't find submodule named %r" % name) + # END exception handling + + def create_submodule(self, *args, **kwargs): + return Submodule.add(self, *args, **kwargs) + + def iter_submodules(self, *args, **kwargs): + return RootModule(self).traverse(*args, **kwargs) + + def submodule_update(self, *args, **kwargs): + return RootModule(self).update(*args, **kwargs) + diff --git a/git/objects/submodule/__init__.py b/git/objects/submodule/__init__.py index 82df59b0..c8bf2d49 100644 --- a/git/objects/submodule/__init__.py +++ b/git/objects/submodule/__init__.py @@ -1,2 +1,6 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php # NOTE: Cannot import anything here as the top-level _init_ has to handle # our dependencies diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 62f4feee..a57111d3 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -1,3 +1,7 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php from git.util import RepoAliasMixin import util from util import ( diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index 132604f6..5e4cad2d 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -1,3 +1,7 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php from base import Submodule, UpdateProgress from util import ( find_first_remote_branch @@ -24,6 +28,7 @@ BRANCHCHANGE = RootUpdateProgress.BRANCHCHANGE URLCHANGE = RootUpdateProgress.URLCHANGE PATHCHANGE = RootUpdateProgress.PATHCHANGE + class RootModule(Submodule): """A (virtual) Root of all submodules in the given repository. It can be used to more easily traverse all submodules of the master repository""" diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py index 9b32807a..2c5f6bc1 100644 --- a/git/objects/submodule/util.py +++ b/git/objects/submodule/util.py @@ -1,3 +1,7 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php import git from git.exc import InvalidGitRepositoryError from git.config import GitConfigParser diff --git a/git/refs/log.py b/git/refs/log.py index 80102e7f..3b9d8514 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -151,7 +151,7 @@ class RefLog(list, Serializable): instance would be found. The path is not guaranteed to point to a valid file though. :param ref: SymbolicReference instance""" - return join(ref.repo.git_path(), "logs", to_native_path(ref.path)) + return join(ref.repo.git_dir, "logs", to_native_path(ref.path)) @classmethod def iter_entries(cls, stream): diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 1a0d3566..d670bd47 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -82,11 +82,11 @@ class SymbolicReference(object): @property def abspath(self): - return join_path_native(self.repo.git_path(), self.path) + return join_path_native(self.repo.git_dir, self.path) @classmethod def _get_packed_refs_path(cls, repo): - return join(repo.git_path(), 'packed-refs') + return join(repo.git_dir, 'packed-refs') @classmethod def _iter_packed_refs(cls, repo): @@ -139,7 +139,7 @@ class SymbolicReference(object): point to, or None""" tokens = None try: - fp = open(join(repo.git_path(), ref_path), 'r') + fp = open(join(repo.git_dir, ref_path), 'r') value = fp.read().rstrip() fp.close() tokens = value.split(" ") @@ -416,7 +416,7 @@ class SymbolicReference(object): or just "myreference", hence 'refs/' is implied. Alternatively the symbolic reference to be deleted""" full_ref_path = cls.to_full_path(path) - abs_path = join(repo.git_path(), full_ref_path) + abs_path = join(repo.git_dir, full_ref_path) if exists(abs_path): os.remove(abs_path) else: @@ -469,7 +469,7 @@ class SymbolicReference(object): corresponding object and a detached symbolic reference will be created instead""" full_ref_path = cls.to_full_path(path) - abs_ref_path = join(repo.git_path(), full_ref_path) + abs_ref_path = join(repo.git_dir, full_ref_path) # figure out target data target = reference @@ -550,8 +550,8 @@ class SymbolicReference(object): if self.path == new_path: return self - new_abs_path = join(self.repo.git_path(), new_path) - cur_abs_path = join(self.repo.git_path(), self.path) + new_abs_path = join(self.repo.git_dir, new_path) + cur_abs_path = join(self.repo.git_dir, self.path) if isfile(new_abs_path): if not force: # if they point to the same file, its not an error @@ -581,7 +581,7 @@ class SymbolicReference(object): # walk loose refs # Currently we do not follow links - for root, dirs, files in os.walk(join_path_native(repo.git_path(), common_path)): + for root, dirs, files in os.walk(join_path_native(repo.git_dir, common_path)): if 'refs/' not in root: # skip non-refs subfolders refs_id = [ i for i,d in enumerate(dirs) if d == 'refs' ] if refs_id: @@ -590,7 +590,7 @@ class SymbolicReference(object): for f in files: abs_path = to_native_path_linux(join_path(root, f)) - rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_path()) + '/', "")) + rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_dir) + '/', "")) # END for each file in root directory # END for each directory to walk diff --git a/git/repo/base.py b/git/repo/base.py index 0b00cb9a..36c19ac8 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -219,45 +219,6 @@ class Repo(object): :raise ValueError: if no remote with such a name exists""" return Remote(self, name) - #{ Submodules - - @property - def submodules(self): - """ - :return: git.IterableList(Submodule, ...) of direct submodules - available from the current head""" - return Submodule.list_items(self) - - def submodule(self, name): - """ :return: Submodule with the given name - :raise ValueError: If no such submodule exists""" - try: - return self.submodules[name] - except IndexError: - raise ValueError("Didn't find submodule named %r" % name) - # END exception handling - - def create_submodule(self, *args, **kwargs): - """Create a new submodule - - :note: See the documentation of Submodule.add for a description of the - applicable parameters - :return: created submodules""" - return Submodule.add(self, *args, **kwargs) - - def iter_submodules(self, *args, **kwargs): - """An iterator yielding Submodule instances, see Traversable interface - for a description of args and kwargs - :return: Iterator""" - return RootModule(self).traverse(*args, **kwargs) - - def submodule_update(self, *args, **kwargs): - """Update the submodules, keeping the repository consistent as it will - take the previous state into consideration. For more information, please - see the documentation of RootModule.update""" - return RootModule(self).update(*args, **kwargs) - - #}END submodules @property def tags(self): diff --git a/git/test/test_base.py b/git/test/test_base.py index ca812ed4..7488ac6b 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -12,10 +12,15 @@ from lib import ( ) import git.objects.base as base +from git.objects import ( + Blob, + Tree, + Commit, + TagObject + ) import git.refs as refs -import os -from git import * + from itertools import chain from git.objects.util import get_object_type_by_name from git.util import hex_to_bin @@ -23,14 +28,22 @@ import tempfile ################## -from git import * from git.util import ( NULL_BIN_SHA ) -from git.typ import ( - str_blob_type - ) +from git.typ import str_blob_type +from git.base import ( + OInfo, + OPackInfo, + ODeltaPackInfo, + OStream, + OPackStream, + ODeltaPackStream, + IStream, + ) + +import os class TestBase(TestBase): @@ -94,7 +107,7 @@ class TestBase(TestBase): assert base.Object in get_object_type_by_name(tname).mro() # END for each known type - assert_raises( ValueError, get_object_type_by_name, "doesntexist" ) + self.failUnlessRaises(ValueError, get_object_type_by_name, "doesntexist") def test_object_resolution(self): # objects must be resolved to shas so they compare equal diff --git a/git/test/test_import.py b/git/test/test_import.py new file mode 100644 index 00000000..d97cee55 --- /dev/null +++ b/git/test/test_import.py @@ -0,0 +1,14 @@ +# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors +# +# This module is part of GitDB and is released under +# the New BSD License: http://www.opensource.org/licenses/bsd-license.php +"""This module's whole purpose is to verify the __all__ descriptions in the respective +module, by importing using from x import *""" + +# perform the actual imports + +from nose import SkipTest + +class TestDummy(object): + def test_base(self): + raise SkipTest("todo") |