diff options
author | Guido Günther <agx@sigxcpu.org> | 2013-04-08 10:20:23 +0200 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2013-04-13 14:26:24 +0200 |
commit | 8fd5ec31272984a7fcff628c50b4c22d7e4107ec (patch) | |
tree | 412e290a6fcd4000a3671b8e22e3014d67aaa22d | |
parent | 6eb2ddcdd4909621e89d5b0c1360eb68bc73f901 (diff) | |
download | git-buildpackage-8fd5ec31272984a7fcff628c50b4c22d7e4107ec.tar.gz git-buildpackage-8fd5ec31272984a7fcff628c50b4c22d7e4107ec.tar.bz2 git-buildpackage-8fd5ec31272984a7fcff628c50b4c22d7e4107ec.zip |
Add minimal vfs interface
so we can access blobs in git as file like objects
-rw-r--r-- | gbp/git/vfs.py | 65 | ||||
-rw-r--r-- | tests/test_GitVfs.py | 55 |
2 files changed, 120 insertions, 0 deletions
diff --git a/gbp/git/vfs.py b/gbp/git/vfs.py new file mode 100644 index 00000000..81649eb9 --- /dev/null +++ b/gbp/git/vfs.py @@ -0,0 +1,65 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2013 Guido Günther <agx@sigxcpu.org> +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +"""Make blobs in a git repository accessible as file like objects""" + +import StringIO +from gbp.git.repository import GitRepositoryError + +class GitVfs(object): + + class _File(object): + """ + A file like object representing a file in git + + @todo: We don't support any byte ranges yet. + """ + def __init__(self, content): + self._iter = iter + self._data = StringIO.StringIO(content) + + def readline(self): + return self._data.readline() + + def readlines(self): + return self._data.readlines() + + def read(self, size=None): + return self._data.read(size) + + def close(self): + return self.close() + + def __init__(self, repo, committish=None): + """ + Access files in a unpaced Debian source package. + + @param repo: the git repository to act on + @param committish: the committish to act on + """ + self._repo = repo + self._committish = committish or 'HEAD' + + def open(self, path, flags=None): + flags = flags or 'r' + + if flags != 'r': + raise NotImplementedError("Only reading supported so far") + try: + return GitVfs._File(self._repo.show( + "%s:%s" % (self._committish, path))) + except GitRepositoryError as e: + raise IOError(e) diff --git a/tests/test_GitVfs.py b/tests/test_GitVfs.py new file mode 100644 index 00000000..c4e26940 --- /dev/null +++ b/tests/test_GitVfs.py @@ -0,0 +1,55 @@ +# vim: set fileencoding=utf-8 : + +""" +Test L{gbp.git.GitVfs} +""" + +import os +import gbp.log + +from . import context + +gbp.log.setup(color=False, verbose=True) + +def test_read(): + repo_dir = context.new_tmpdir(__name__) + """ + Create a repository + + Methods tested: + - L{gbp.git.GitVfs.open} + - L{gbp.git._File.readline} + - L{gbp.git._File.readlines} + - L{gbp.git._File.read} + - L{gbp.git._File.close} + + >>> import os, gbp.git.vfs + >>> repo = gbp.git.GitRepository.create(str(repo_dir)) + >>> f = file(os.path.join(repo.path, 'foo.txt'), 'w') + >>> content = 'al pha\\na\\nb\\nc' + >>> f.write('al pha\\na\\nb\\nc') + >>> f.close() + >>> repo.add_files(repo.path, force=True) + >>> repo.commit_all(msg="foo") + >>> vfs = gbp.git.vfs.GitVfs(repo, 'HEAD') + >>> gf = vfs.open('foo.txt') + >>> gf.readline() + 'al pha\\n' + >>> gf.readline() + 'a\\n' + >>> gf.readlines() + ['b\\n', 'c'] + >>> gf.readlines() + [] + >>> gf.readline() + '' + >>> gf.readline() + '' + >>> gbp.git.vfs.GitVfs(repo, 'HEAD').open('foo.txt').read() == content + True + >>> gf = vfs.open('doesnotexist') + Traceback (most recent call last): + ... + IOError: can't get HEAD:doesnotexist: fatal: Path 'doesnotexist' does not exist in 'HEAD' + >>> context.teardown() + """ |