diff options
Diffstat (limited to 'git/db/py/base.py')
-rw-r--r-- | git/db/py/base.py | 278 |
1 files changed, 139 insertions, 139 deletions
diff --git a/git/db/py/base.py b/git/db/py/base.py index 6710a0cc..127d828a 100644 --- a/git/db/py/base.py +++ b/git/db/py/base.py @@ -6,29 +6,29 @@ from git.db.interface import * from git.util import ( - pool, - join, - isfile, - normpath, - abspath, - dirname, - LazyMixin, - hex_to_bin, - bin_to_hex, - expandvars, - expanduser, - exists, - is_git_dir, - ) + pool, + join, + isfile, + normpath, + abspath, + dirname, + LazyMixin, + hex_to_bin, + bin_to_hex, + expandvars, + expanduser, + exists, + is_git_dir, +) from git.index import IndexFile from git.config import GitConfigParser -from git.exc import ( - BadObject, - AmbiguousObjectName, - InvalidGitRepositoryError, - NoSuchPathError - ) +from git.exc import ( + BadObject, + AmbiguousObjectName, + InvalidGitRepositoryError, + NoSuchPathError +) from async import ChannelThreadTask @@ -37,28 +37,28 @@ import sys import os -__all__ = ( 'PureObjectDBR', 'PureObjectDBW', 'PureRootPathDB', 'PureCompoundDB', - 'PureConfigurationMixin', 'PureRepositoryPathsMixin', 'PureAlternatesFileMixin', - 'PureIndexDB') - +__all__ = ('PureObjectDBR', 'PureObjectDBW', 'PureRootPathDB', 'PureCompoundDB', + 'PureConfigurationMixin', 'PureRepositoryPathsMixin', 'PureAlternatesFileMixin', + 'PureIndexDB') + class PureObjectDBR(ObjectDBR): - - #{ Query Interface - + + #{ Query Interface + def has_object_async(self, reader): task = ChannelThreadTask(reader, str(self.has_object_async), lambda sha: (sha, self.has_object(sha))) - return pool.add_task(task) - + return pool.add_task(task) + def info_async(self, reader): task = ChannelThreadTask(reader, str(self.info_async), self.info) return pool.add_task(task) - + def stream_async(self, reader): # base implementation just uses the stream method repeatedly task = ChannelThreadTask(reader, str(self.stream_async), self.stream) return pool.add_task(task) - + def partial_to_complete_sha_hex(self, partial_hexsha): len_partial_hexsha = len(partial_hexsha) if len_partial_hexsha % 2 != 0: @@ -67,53 +67,52 @@ class PureObjectDBR(ObjectDBR): partial_binsha = hex_to_bin(partial_hexsha) # END assure successful binary conversion return self.partial_to_complete_sha(partial_binsha, len(partial_hexsha)) - + #} END query interface - - + + class PureObjectDBW(ObjectDBW): - + def __init__(self, *args, **kwargs): try: super(PureObjectDBW, self).__init__(*args, **kwargs) except TypeError: pass - #END handle py 2.6 + # END handle py 2.6 self._ostream = None - + #{ Edit Interface def set_ostream(self, stream): cstream = self._ostream self._ostream = stream return cstream - + def ostream(self): return self._ostream - + def store_async(self, reader): - task = ChannelThreadTask(reader, str(self.store_async), self.store) + task = ChannelThreadTask(reader, str(self.store_async), self.store) return pool.add_task(task) - + #} END edit interface - + class PureRootPathDB(RootPathDB): - + def __init__(self, root_path): self._root_path = root_path super(PureRootPathDB, self).__init__(root_path) - - - #{ Interface + + #{ Interface def root_path(self): return self._root_path - + def db_path(self, rela_path=None): if not rela_path: return self._root_path return join(self._root_path, rela_path) #} END interface - + def _databases_recursive(database, output): """Fill output list with database from db, in order. Deals with Loose, Packed @@ -127,50 +126,51 @@ def _databases_recursive(database, output): else: output.append(database) # END handle database type - + class PureCompoundDB(CompoundDB, PureObjectDBR, LazyMixin, CachingDB): + def _set_cache_(self, attr): if attr == '_dbs': self._dbs = list() else: super(PureCompoundDB, self)._set_cache_(attr) - - #{ PureObjectDBR interface - + + #{ PureObjectDBR interface + def has_object(self, sha): for db in self._dbs: if db.has_object(sha): return True - #END for each db + # END for each db return False - + def info(self, sha): for db in self._dbs: try: return db.info(sha) except BadObject: pass - #END for each db - + # END for each db + def stream(self, sha): for db in self._dbs: try: return db.stream(sha) except BadObject: pass - #END for each db + # END for each db def size(self): - return reduce(lambda x,y: x+y, (db.size() for db in self._dbs), 0) - + return reduce(lambda x, y: x + y, (db.size() for db in self._dbs), 0) + def sha_iter(self): return chain(*(db.sha_iter() for db in self._dbs)) - + #} END object DBR Interface - + #{ Interface - + def databases(self): return tuple(self._dbs) @@ -183,15 +183,15 @@ class PureCompoundDB(CompoundDB, PureObjectDBR, LazyMixin, CachingDB): # END if is caching db # END for each database to update return stat - + def partial_to_complete_sha_hex(self, partial_hexsha): len_partial_hexsha = len(partial_hexsha) if len_partial_hexsha % 2 != 0: partial_binsha = hex_to_bin(partial_hexsha + "0") else: partial_binsha = hex_to_bin(partial_hexsha) - # END assure successful binary conversion - + # END assure successful binary conversion + candidate = None for db in self._dbs: full_bin_sha = None @@ -213,34 +213,34 @@ class PureCompoundDB(CompoundDB, PureObjectDBR, LazyMixin, CachingDB): if not candidate: raise BadObject(partial_binsha) return candidate - + def partial_to_complete_sha(self, partial_binsha, hex_len): """Simple adaptor to feed into our implementation""" return self.partial_to_complete_sha_hex(bin_to_hex(partial_binsha)[:hex_len]) #} END interface - - + + class PureRepositoryPathsMixin(RepositoryPathsMixin): # slots has no effect here, its just to keep track of used attrs - __slots__ = ("_git_path", '_bare', '_working_tree_dir') - - #{ Configuration + __slots__ = ("_git_path", '_bare', '_working_tree_dir') + + #{ Configuration repo_dir = '.git' objs_dir = 'objects' #} END configuration - + #{ Subclass Interface def _initialize(self, path): epath = abspath(expandvars(expanduser(path or os.getcwd()))) if not exists(epath): raise NoSuchPathError(epath) - #END check file + # END check file self._working_tree_dir = None self._git_path = None curpath = epath - + # walk up the path to find the .git dir while curpath: if is_git_dir(curpath): @@ -256,7 +256,7 @@ class PureRepositoryPathsMixin(RepositoryPathsMixin): if not dummy: break # END while curpath - + if self._git_path is None: raise InvalidGitRepositoryError(epath) # END path not found @@ -264,167 +264,167 @@ class PureRepositoryPathsMixin(RepositoryPathsMixin): self._bare = self._working_tree_dir is None if hasattr(self, 'config_reader'): try: - self._bare = self.config_reader("repository").getboolean('core','bare') + self._bare = self.config_reader("repository").getboolean('core', 'bare') except Exception: # lets not assume the option exists, although it should pass - #END handle exception - #END check bare flag + # END handle exception + # END check bare flag self._working_tree_dir = self._bare and None or self._working_tree_dir - + #} 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 object interface - + #{ Interface - + @property def is_bare(self): return self._bare - + @property def git_dir(self): return self._git_path - + @property def working_tree_dir(self): if self._working_tree_dir is None: raise AssertionError("Repository at %s is bare and does not have a working tree directory" % self.git_dir) - #END assertion + # END assertion 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_dir else: return self.working_tree_dir - #END handle bare state - + # 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') - + 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 - - + + class PureConfigurationMixin(ConfigurationMixin): - + #{ Configuration system_config_file_name = "gitconfig" repo_config_file_name = "config" #} END - + def __new__(cls, *args, **kwargs): """This is just a stupid workaround for the evil py2.6 change which makes mixins quite impossible""" return super(PureConfigurationMixin, cls).__new__(cls, *args, **kwargs) - + def __init__(self, *args, **kwargs): """Verify prereqs""" try: super(PureConfigurationMixin, self).__init__(*args, **kwargs) except TypeError: pass - #END handle code-breaking change in python 2.6 + # END handle code-breaking change in python 2.6 assert hasattr(self, 'git_dir') - - def _path_at_level(self, level ): - # we do not support an absolute path of the gitconfig on windows , + + def _path_at_level(self, level): + # we do not support an absolute path of the gitconfig on windows , # use the global config instead if sys.platform == "win32" and level == "system": level = "global" - #END handle windows - + # END handle windows + if level == "system": return "/etc/%s" % self.system_config_file_name elif level == "global": return normpath(expanduser("~/.%s" % self.system_config_file_name)) elif level == "repository": return join(self.git_dir, self.repo_config_file_name) - #END handle level - + # END handle level + raise ValueError("Invalid configuration level: %r" % level) - + #{ Interface - + def config_reader(self, config_level=None): files = None if config_level is None: - files = [ self._path_at_level(f) for f in self.config_level ] + files = [self._path_at_level(f) for f in self.config_level] else: - files = [ self._path_at_level(config_level) ] - #END handle level + files = [self._path_at_level(config_level)] + # END handle level return GitConfigParser(files, read_only=True) - + def config_writer(self, config_level="repository"): return GitConfigParser(self._path_at_level(config_level), read_only=False) - - + #} END interface - - + + class PureIndexDB(IndexDB): #{ Configuration IndexCls = IndexFile #} END configuration - + @property def index(self): return self.IndexCls(self) - - + + class PureAlternatesFileMixin(object): + """Utility able to read and write an alternates file through the alternates property It needs to be part of a type with the git_dir or db_path property. - + The file by default is assumed to be located at the default location as imposed by the standard git repository layout""" - + #{ Configuration alternates_filepath = os.path.join('info', 'alternates') # relative path to alternates file - + #} END configuration - + def __init__(self, *args, **kwargs): try: super(PureAlternatesFileMixin, self).__init__(*args, **kwargs) except TypeError: pass - #END handle py2.6 code breaking changes - self._alternates_path() # throws on incompatible type - - #{ Interface - + # END handle py2.6 code breaking changes + self._alternates_path() # throws on incompatible type + + #{ Interface + def _alternates_path(self): if hasattr(self, 'git_dir'): return join(self.git_dir, 'objects', self.alternates_filepath) @@ -432,8 +432,8 @@ class PureAlternatesFileMixin(object): return self.db_path(self.alternates_filepath) else: raise AssertionError("This mixin requires a parent type with either the git_dir property or db_path method") - #END handle path - + # END handle path + def _get_alternates(self): """The list of alternates for this repo from which objects can be retrieved @@ -462,7 +462,7 @@ class PureAlternatesFileMixin(object): :note: The method does not check for the existance of the paths in alts as the caller is responsible.""" - alternates_path = self._alternates_path() + alternates_path = self._alternates_path() if not alts: if isfile(alternates_path): os.remove(alternates_path) @@ -472,10 +472,10 @@ class PureAlternatesFileMixin(object): f.write("\n".join(alts)) finally: f.close() - # END file handling + # END file handling # END alts handling - alternates = property(_get_alternates, _set_alternates, doc="Retrieve a list of alternates paths or set a list paths to be used as alternates") - + alternates = property(_get_alternates, _set_alternates, + doc="Retrieve a list of alternates paths or set a list paths to be used as alternates") + #} END interface - |