added note support

* Repository.create_note()
* Repository.lookup_note()
* Repository.notes() - generator
This commit is contained in:
Nico von Geyso
2013-03-10 12:42:22 +01:00
parent 4a82a80982
commit 2328cdef69
5 changed files with 391 additions and 0 deletions

37
include/pygit2/note.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* Copyright 2010-2013 The pygit2 contributors
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file 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; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDE_pygit2_note_h
#define INCLUDE_pygit2_note_h
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <git2.h>
PyObject* wrap_note(Repository* repo, git_oid* annotated_id, const char* ref);
#endif

View File

@@ -67,6 +67,21 @@ typedef struct {
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
Repository *repo;
git_note *note;
char* annotated_id;
} Note;
typedef struct {
PyObject_HEAD
Repository *repo;
git_note_iterator* iter;
char* ref;
} NoteIter;
typedef struct {
PyObject_HEAD
Diff* diff; Diff* diff;
size_t i; size_t i;
size_t n; size_t n;

236
src/note.c Normal file
View File

@@ -0,0 +1,236 @@
/*
* Copyright 2010-2013 The pygit2 contributors
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file 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; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
#include <pygit2/error.h>
#include <pygit2/utils.h>
#include <pygit2/types.h>
#include <pygit2/oid.h>
#include <pygit2/note.h>
extern PyTypeObject SignatureType;
PyDoc_STRVAR(Note_remove__doc__,
"Removes a note for an annotated object");
PyObject*
Note_remove(Note *self, PyObject* args)
{
char *ref = "refs/notes/commits";
int err = GIT_ERROR;
git_oid annotated_id;
Signature *py_author, *py_committer;
if (!PyArg_ParseTuple(args, "O!O!|s",
&SignatureType, &py_author,
&SignatureType, &py_committer,
&ref))
return NULL;
err = git_oid_fromstr(&annotated_id, self->annotated_id);
if (err < 0)
return Error_set(err);
err = git_note_remove(self->repo->repo, ref, py_author->signature,
py_committer->signature, &annotated_id);
if (err < 0)
return Error_set(err);
Py_RETURN_NONE;
}
PyDoc_STRVAR(Note_oid__doc__,
"Gets the id of the blob containing the note message\n");
PyObject *
Note_oid__get__(Note *self)
{
return git_oid_to_py_str(git_note_oid(self->note));
}
PyDoc_STRVAR(Note_message__doc__,
"Gets message of the note\n");
PyObject *
Note_message__get__(Note *self)
{
return PyUnicode_FromString(git_note_message(self->note));
}
static void
Note_dealloc(Note *self)
{
Py_CLEAR(self->repo);
free(self->annotated_id);
git_note_free(self->note);
PyObject_Del(self);
}
PyMethodDef Note_methods[] = {
METHOD(Note, remove, METH_VARARGS),
{NULL}
};
PyMemberDef Note_members[] = {
MEMBER(Note, annotated_id, T_STRING, "id of the annotated object."),
{NULL}
};
PyGetSetDef Note_getseters[] = {
GETTER(Note, message),
GETTER(Note, oid),
{NULL}
};
PyDoc_STRVAR(Note__doc__, "Note object.");
PyTypeObject NoteType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_pygit2.Note", /* tp_name */
sizeof(Note), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Note_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 */
Note__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Note_methods, /* tp_methods */
Note_members, /* tp_members */
Note_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 *
NoteIter_iternext(NoteIter *self)
{
int err;
git_oid note_id, annotated_id;
err = git_note_next(&note_id, &annotated_id, self->iter);
if (err < 0)
return Error_set(err);
return (PyObject*) wrap_note(self->repo, &annotated_id, self->ref);
}
void
NoteIter_dealloc(NoteIter *self)
{
git_note_iterator_free(self->iter);
PyObject_Del(self);
}
PyDoc_STRVAR(NoteIter__doc__, "Note iterator object.");
PyTypeObject NoteIterType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_pygit2.NoteIter", /* tp_name */
sizeof(NoteIter), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)NoteIter_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 */
NoteIter__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc) NoteIter_iternext, /* tp_iternext */
};
PyObject*
wrap_note(Repository* repo, git_oid* annotated_id, const char* ref)
{
Note* py_note = NULL;
int err = GIT_ERROR;
py_note = (Note*) PyType_GenericNew(&NoteType, NULL, NULL);
if (py_note == NULL) {
PyErr_NoMemory();
return NULL;
}
err = git_note_read(&py_note->note, repo->repo, ref, annotated_id);
if (err < 0)
return Error_set(err);
py_note->repo = repo;
Py_INCREF(repo);
py_note->annotated_id = git_oid_allocfmt(annotated_id);
return (PyObject*) py_note;
}

View File

@@ -60,6 +60,8 @@ extern PyTypeObject RefLogIterType;
extern PyTypeObject RefLogEntryType; extern PyTypeObject RefLogEntryType;
extern PyTypeObject SignatureType; extern PyTypeObject SignatureType;
extern PyTypeObject RemoteType; extern PyTypeObject RemoteType;
extern PyTypeObject NoteType;
extern PyTypeObject NoteIterType;
@@ -236,6 +238,11 @@ moduleinit(PyObject* m)
if (PyType_Ready(&RemoteType) < 0) if (PyType_Ready(&RemoteType) < 0)
return NULL; return NULL;
if (PyType_Ready(&NoteType) < 0)
return NULL;
if (PyType_Ready(&NoteIterType) < 0)
return NULL;
Py_INCREF(GitError); Py_INCREF(GitError);
PyModule_AddObject(m, "GitError", GitError); PyModule_AddObject(m, "GitError", GitError);
@@ -281,6 +288,9 @@ moduleinit(PyObject* m)
Py_INCREF(&RemoteType); Py_INCREF(&RemoteType);
PyModule_AddObject(m, "Remote", (PyObject *)&RemoteType); PyModule_AddObject(m, "Remote", (PyObject *)&RemoteType);
Py_INCREF(&NoteType);
PyModule_AddObject(m, "Note", (PyObject *)&NoteType);
PyModule_AddIntConstant(m, "GIT_OBJ_ANY", GIT_OBJ_ANY); PyModule_AddIntConstant(m, "GIT_OBJ_ANY", GIT_OBJ_ANY);
PyModule_AddIntConstant(m, "GIT_OBJ_COMMIT", GIT_OBJ_COMMIT); PyModule_AddIntConstant(m, "GIT_OBJ_COMMIT", GIT_OBJ_COMMIT);
PyModule_AddIntConstant(m, "GIT_OBJ_TREE", GIT_OBJ_TREE); PyModule_AddIntConstant(m, "GIT_OBJ_TREE", GIT_OBJ_TREE);

View File

@@ -33,6 +33,7 @@
#include <pygit2/utils.h> #include <pygit2/utils.h>
#include <pygit2/object.h> #include <pygit2/object.h>
#include <pygit2/oid.h> #include <pygit2/oid.h>
#include <pygit2/note.h>
#include <pygit2/repository.h> #include <pygit2/repository.h>
#include <pygit2/remote.h> #include <pygit2/remote.h>
@@ -47,6 +48,8 @@ extern PyTypeObject ConfigType;
extern PyTypeObject DiffType; extern PyTypeObject DiffType;
extern PyTypeObject RemoteType; extern PyTypeObject RemoteType;
extern PyTypeObject ReferenceType; extern PyTypeObject ReferenceType;
extern PyTypeObject NoteType;
extern PyTypeObject NoteIterType;
git_otype git_otype
int_to_loose_object_type(int type_id) int_to_loose_object_type(int type_id)
@@ -1132,6 +1135,93 @@ Repository_checkout(Repository *self, PyObject *args, PyObject *kw)
} }
PyDoc_STRVAR(Repository_notes__doc__, "");
PyObject *
Repository_notes(Repository *self, PyObject* args)
{
NoteIter *iter = NULL;
char *ref = "refs/notes/commits";
int err = GIT_ERROR;
if (!PyArg_ParseTuple(args, "|s", &ref))
return NULL;
iter = PyObject_New(NoteIter, &NoteIterType);
if (iter != NULL) {
iter->repo = self;
iter->ref = ref;
err = git_note_iterator_new(&iter->iter, self->repo, iter->ref);
if (err == GIT_OK) {
Py_INCREF(self);
return (PyObject*)iter;
}
}
return Error_set(err);
}
PyDoc_STRVAR(Repository_create_note__doc__,
"create_note(message, author, committer, annotated_id [,ref, force]) -> ID\n"
"\n"
"Create a new note for an object, return its SHA-ID."
"If no ref is given 'refs/notes/commits' will be used.");
PyObject *
Repository_create_note(Repository *self, PyObject* args)
{
git_oid note_id, annotated_id;
char *annotated = NULL, *message = NULL, *ref = "refs/notes/commits";
int err = GIT_ERROR;
unsigned int force = 0;
Signature *py_author, *py_committer;
if (!PyArg_ParseTuple(args, "sO!O!s|si",
&message,
&SignatureType, &py_author,
&SignatureType, &py_committer,
&annotated, &ref, &force))
return NULL;
err = git_oid_fromstr(&annotated_id, annotated);
if (err < 0)
return Error_set(err);
err = git_note_create(&note_id, self->repo, py_author->signature,
py_committer->signature, ref,
&annotated_id, message, force);
if (err < 0)
return Error_set(err);
return git_oid_to_python(note_id.id);
}
PyDoc_STRVAR(Repository_lookup_note__doc__,
"lookup_note(annotated_id [, ref]) -> Note\n"
"\n"
"Lookup a note for an annotated object in a repository.");
PyObject *
Repository_lookup_note(Repository *self, PyObject* args)
{
git_oid annotated_id;
char* annotated = NULL, *ref = "refs/notes/commits";
int err;
if (!PyArg_ParseTuple(args, "s|s", &annotated, &ref))
return NULL;
err = git_oid_fromstr(&annotated_id, annotated);
if (err < 0)
return Error_set(err);
return (PyObject*) wrap_note(self, &annotated_id, ref);
}
PyMethodDef Repository_methods[] = { PyMethodDef Repository_methods[] = {
METHOD(Repository, create_blob, METH_VARARGS), METHOD(Repository, create_blob, METH_VARARGS),
METHOD(Repository, create_blob_fromfile, METH_VARARGS), METHOD(Repository, create_blob_fromfile, METH_VARARGS),
@@ -1150,6 +1240,9 @@ PyMethodDef Repository_methods[] = {
METHOD(Repository, status_file, METH_O), METHOD(Repository, status_file, METH_O),
METHOD(Repository, create_remote, METH_VARARGS), METHOD(Repository, create_remote, METH_VARARGS),
METHOD(Repository, checkout, METH_VARARGS|METH_KEYWORDS), METHOD(Repository, checkout, METH_VARARGS|METH_KEYWORDS),
METHOD(Repository, notes, METH_VARARGS),
METHOD(Repository, create_note, METH_VARARGS),
METHOD(Repository, lookup_note, METH_VARARGS),
{NULL} {NULL}
}; };