Introduce RemoteCollection

This lets us look up remotes by name, which is not possible by just
returning the list of remotes.

Move remote creation to Repostiory.remotes.create() and keep the old
Repository.create_remote() for compatibility, delegating to this new
way.

Existing code should keep working, but this moves us towards what we'd
need for a better interface in 0.22 which makes remote renaming and
deleting work with a name rather than an instance and would make sense
to exist as part of an Remote.remotes object.
This commit is contained in:
Carlos Martín Nieto
2014-11-08 13:13:34 +01:00
parent 21e2102e7c
commit b80103b017
4 changed files with 89 additions and 26 deletions

View File

@@ -2,10 +2,14 @@
Remotes
**********************************************************************
.. autoattribute:: pygit2.Repository.remotes
.. automethod:: pygit2.Repository.create_remote
The remote collection
==========================
.. autoclass:: pygit2.remote.RemoteCollection
:members:
The Remote type
====================

View File

@@ -494,3 +494,66 @@ def get_credentials(fn, url, username, allowed):
check_error(err)
return ccred
class RemoteCollection(object):
"""Collection of configured remotes
You can use this class to look up and manage the remotes configured
in a repository. You can access repositories using index
access. E.g. to look up the "origin" remote, you can use
>>> repo.remotes["origin"]
"""
def __init__(self, repo):
self._repo = repo;
def __len__(self):
names = ffi.new('git_strarray *')
try:
err = C.git_remote_list(names, self._repo._repo)
check_error(err)
return names.count
finally:
C.git_strarray_free(names)
def __iter__(self):
names = ffi.new('git_strarray *')
try:
err = C.git_remote_list(names, self._repo._repo)
check_error(err)
cremote = ffi.new('git_remote **')
for i in range(names.count):
err = C.git_remote_load(cremote, self._repo._repo, names.strings[i])
check_error(err)
yield Remote(self._repo, cremote[0])
finally:
C.git_strarray_free(names)
def __getitem__(self, name):
if isinstance(name, int):
return list(self)[name]
cremote = ffi.new('git_remote **')
err = C.git_remote_load(cremote, self._repo._repo, to_bytes(name))
check_error(err)
return Remote(self._repo, cremote[0])
def create(self, name, url):
"""create(name, url) -> Remote
Create a new remote with the given name and url.
"""
cremote = ffi.new('git_remote **')
err = C.git_remote_create(cremote, self._repo._repo, to_bytes(name), to_bytes(url))
check_error(err)
return Remote(self._repo, cremote[0])

View File

@@ -48,7 +48,7 @@ from .config import Config
from .errors import check_error
from .ffi import ffi, C
from .index import Index
from .remote import Remote
from .remote import Remote, RemoteCollection
from .blame import Blame
from .utils import to_bytes, is_string
@@ -58,6 +58,8 @@ class Repository(_Repository):
def __init__(self, *args, **kwargs):
super(Repository, self).__init__(*args, **kwargs)
self._remotes = RemoteCollection(self)
# Get the pointer as the contents of a buffer and store it for
# later access
repo_cptr = ffi.new('git_repository **')
@@ -90,36 +92,17 @@ class Repository(_Repository):
"""create_remote(name, url) -> Remote
Creates a new remote.
This method is deprecated, please use Remote.remotes.create()
"""
cremote = ffi.new('git_remote **')
err = C.git_remote_create(cremote, self._repo, to_bytes(name),
to_bytes(url))
check_error(err)
return Remote(self, cremote[0])
return self.remotes.create(name, url)
@property
def remotes(self):
"""Returns all configured remotes"""
"""The collection of configured remotes"""
names = ffi.new('git_strarray *')
try:
err = C.git_remote_list(names, self._repo)
check_error(err)
l = [None] * names.count
cremote = ffi.new('git_remote **')
for i in range(names.count):
err = C.git_remote_load(cremote, self._repo, names.strings[i])
check_error(err)
l[i] = Remote(self, cremote[0])
return l
finally:
C.git_strarray_free(names)
return self._remotes
#
# Configuration

View File

@@ -167,6 +167,19 @@ class RepositoryTest(utils.RepoTestCase):
remote = self.repo.create_remote(name, url)
self.assertTrue(remote.name in [x.name for x in self.repo.remotes])
def test_remote_collection(self):
remote = self.repo.remotes['origin']
self.assertEqual(REMOTE_NAME, remote.name)
self.assertEqual(REMOTE_URL, remote.url)
with self.assertRaises(KeyError):
self.repo.remotes['upstream']
name = 'upstream'
url = 'git://github.com/libgit2/pygit2.git'
remote = self.repo.remotes.create(name, url)
self.assertTrue(remote.name in [x.name for x in self.repo.remotes])
def test_remote_save(self):
remote = self.repo.remotes[0]