Refspec: create the type to wrap refspecs

This commit is contained in:
Carlos Martín Nieto
2014-01-19 23:05:41 +01:00
parent 73518fd804
commit e681a47245
4 changed files with 197 additions and 6 deletions

View File

@@ -63,6 +63,7 @@ extern PyTypeObject RefLogEntryType;
extern PyTypeObject BranchType;
extern PyTypeObject SignatureType;
extern PyTypeObject RemoteType;
extern PyTypeObject RefspecType;
extern PyTypeObject NoteType;
extern PyTypeObject NoteIterType;
extern PyTypeObject BlameType;
@@ -420,6 +421,11 @@ moduleinit(PyObject* m)
/* Remotes */
INIT_TYPE(RemoteType, NULL, NULL)
ADD_TYPE(m, Remote)
INIT_TYPE(RefspecType, NULL, NULL)
ADD_TYPE(m, Refspec)
/* Direction for the refspec */
ADD_CONSTANT_INT(m, GIT_DIRECTION_FETCH)
ADD_CONSTANT_INT(m, GIT_DIRECTION_PUSH)
/* Blame */
INIT_TYPE(BlameType, NULL, NULL)

View File

@@ -36,6 +36,181 @@
extern PyObject *GitError;
extern PyTypeObject RepositoryType;
extern PyTypeObject RefspecType;
Refspec *
wrap_refspec(const Remote *owner, const git_refspec *refspec)
{
Refspec *spec;
spec = PyObject_New(Refspec, &RefspecType);
if (!spec)
return NULL;
Py_INCREF(owner);
spec->owner = owner;
spec->refspec = refspec;
return spec;
}
PyDoc_STRVAR(Refspec_direction__doc__,
"The direction of this refspec (fetch or push)");
PyObject *
Refspec_direction__get__(Refspec *self)
{
return Py_BuildValue("i", git_refspec_direction(self->refspec));
}
PyDoc_STRVAR(Refspec_src__doc__, "Source or lhs of the refspec");
PyObject *
Refspec_src__get__(Refspec *self)
{
return to_unicode(git_refspec_src(self->refspec), NULL, NULL);
}
PyDoc_STRVAR(Refspec_dst__doc__, "Destination or rhs of the refspec");
PyObject *
Refspec_dst__get__(Refspec *self)
{
return to_unicode(git_refspec_dst(self->refspec), NULL, NULL);
}
PyDoc_STRVAR(Refspec_string__doc__, "String used to create this refspec");
PyObject *
Refspec_string__get__(Refspec *self)
{
return to_unicode(git_refspec_string(self->refspec), NULL, NULL);
}
PyDoc_STRVAR(Refspec_force__doc__,
"Whether this refspec allows non-fast-forward updates");
PyObject *
Refspec_force__get__(Refspec *self)
{
if (git_refspec_force(self->refspec))
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
PyDoc_STRVAR(Refspec_src_matches__doc__,
"src_matches(str) -> Bool\n"
"\n"
"Returns whether the string matches the source refspec\n");
PyObject *
Refspec_src_matches(Refspec *self, PyObject *py_str)
{
char *str;
int res;
str = py_str_to_c_str(py_str, NULL);
if (!str)
return NULL;
res = git_refspec_src_matches(self->refspec, str);
free(str);
if (res)
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
PyDoc_STRVAR(Refspec_dst_matches__doc__,
"dst_matches(str) -> Bool\n"
"\n"
"Returns whether the string matches the destination refspec\n");
PyObject *
Refspec_dst_matches(Refspec *self, PyObject *py_str)
{
char *str;
int res;
str = py_str_to_c_str(py_str, NULL);
if (!str)
return NULL;
res = git_refspec_dst_matches(self->refspec, str);
free(str);
if (res)
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
PyMethodDef Refspec_methods[] = {
METHOD(Refspec, src_matches, METH_O),
METHOD(Refspec, dst_matches, METH_O),
{NULL}
};
PyGetSetDef Refspec_getseters[] = {
GETTER(Refspec, direction),
GETTER(Refspec, src),
GETTER(Refspec, dst),
GETTER(Refspec, string),
GETTER(Refspec, force),
{NULL}
};
static void
Refspec_dealloc(Refspec *self)
{
Py_CLEAR(self->owner);
PyObject_Del(self);
}
PyDoc_STRVAR(Refspec__doc__, "Refspec object.");
PyTypeObject RefspecType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_pygit2.Refspec", /* tp_name */
sizeof(Remote), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Refspec_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Refspec__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Refspec_methods, /* tp_methods */
0, /* tp_members */
Refspec_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
PyObject *
Remote_init(Remote *self, PyObject *args, PyObject *kwds)
@@ -306,8 +481,7 @@ Remote_get_refspec(Remote *self, PyObject *value)
return NULL;
}
return Py_BuildValue("(ss)", git_refspec_src(refspec),
git_refspec_dst(refspec));
return (PyObject*) wrap_refspec(self, refspec);
}

View File

@@ -198,6 +198,12 @@ typedef struct {
/* git_remote */
SIMPLE_TYPE(Remote, git_remote, remote)
/* git_refspec */
typedef struct {
PyObject_HEAD
const Remote *owner;
const git_refspec *refspec;
} Refspec;
/* git_blame */
SIMPLE_TYPE(Blame, git_blame, blame)

View File

@@ -39,6 +39,7 @@ REMOTE_FETCHSPEC_DST = 'refs/remotes/origin/*'
REMOTE_REPO_OBJECTS = 30
REMOTE_REPO_BYTES = 2758
ORIGIN_REFSPEC = '+refs/heads/*:refs/remotes/origin/*'
class RepositoryTest(utils.RepoTestCase):
def test_remote_create(self):
@@ -80,13 +81,17 @@ class RepositoryTest(utils.RepoTestCase):
self.assertEqual(remote.refspec_count, 1)
refspec = remote.get_refspec(0)
self.assertEqual(refspec[0], REMOTE_FETCHSPEC_SRC)
self.assertEqual(refspec[1], REMOTE_FETCHSPEC_DST)
self.assertEqual(refspec.src, REMOTE_FETCHSPEC_SRC)
self.assertEqual(refspec.dst, REMOTE_FETCHSPEC_DST)
self.assertEqual(True, refspec.force)
self.assertEqual(ORIGIN_REFSPEC, refspec.string)
self.assertEqual(list, type(remote.get_fetch_refspecs()))
self.assertEqual(1, len(remote.get_fetch_refspecs()))
self.assertEqual('+refs/heads/*:refs/remotes/origin/*',
remote.get_fetch_refspecs()[0])
self.assertEqual(ORIGIN_REFSPEC, remote.get_fetch_refspecs()[0])
self.assertTrue(refspec.src_matches('refs/heads/master'))
self.assertTrue(refspec.dst_matches('refs/remotes/origin/master'))
self.assertEqual(list, type(remote.get_push_refspecs()))
self.assertEqual(0, len(remote.get_push_refspecs()))