Introduce libgit2 options
Allow setting and getting the mwindow size and search paths.
This commit is contained in:
185
src/options.c
Normal file
185
src/options.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 "error.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
extern PyObject *GitError;
|
||||
|
||||
static PyObject *
|
||||
get_search_path(long level)
|
||||
{
|
||||
char *buf = NULL;
|
||||
size_t len = 64;
|
||||
PyObject *py_path;
|
||||
int error;
|
||||
|
||||
do {
|
||||
len *= 2;
|
||||
char *tmp = realloc(buf, len);
|
||||
if (!tmp) {
|
||||
free(buf);
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
buf = tmp;
|
||||
|
||||
error = git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, level, buf, len);
|
||||
} while(error == GIT_EBUFS);
|
||||
|
||||
if (error < 0) {
|
||||
free(buf);
|
||||
Error_set(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
py_path = to_unicode(buf, NULL, NULL);
|
||||
free(buf);
|
||||
|
||||
if (!py_path)
|
||||
return NULL;
|
||||
|
||||
return py_path;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
option(PyObject *self, PyObject *args)
|
||||
{
|
||||
long option;
|
||||
int error;
|
||||
PyObject *py_option;
|
||||
|
||||
py_option = PyTuple_GetItem(args, 0);
|
||||
if (!py_option)
|
||||
return NULL;
|
||||
|
||||
if (!PyLong_Check(py_option))
|
||||
goto on_non_integer;
|
||||
|
||||
option = PyLong_AsLong(py_option);
|
||||
|
||||
switch (option) {
|
||||
case GIT_OPT_GET_SEARCH_PATH:
|
||||
{
|
||||
PyObject *py_level;
|
||||
|
||||
py_level = PyTuple_GetItem(args, 1);
|
||||
if (!py_level)
|
||||
return NULL;
|
||||
|
||||
if (!PyLong_Check(py_level))
|
||||
goto on_non_integer;
|
||||
|
||||
return get_search_path(PyLong_AsLong(py_level));
|
||||
break;
|
||||
}
|
||||
|
||||
case GIT_OPT_SET_SEARCH_PATH:
|
||||
{
|
||||
PyObject *py_level, *py_path, *tpath;
|
||||
const char *path;
|
||||
int err;
|
||||
|
||||
py_level = PyTuple_GetItem(args, 1);
|
||||
if (!py_level)
|
||||
return NULL;
|
||||
|
||||
py_path = PyTuple_GetItem(args, 2);
|
||||
if (!py_path)
|
||||
return NULL;
|
||||
|
||||
if (!PyLong_Check(py_level))
|
||||
goto on_non_integer;
|
||||
|
||||
path = py_str_borrow_c_str(&tpath, py_path, NULL);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
err = git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, PyLong_AsLong(py_level), path);
|
||||
Py_DECREF(tpath);
|
||||
|
||||
if (err < 0) {
|
||||
Error_set(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
case GIT_OPT_GET_MWINDOW_SIZE:
|
||||
{
|
||||
size_t size;
|
||||
|
||||
if ((error = git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &size)) < 0) {
|
||||
Error_set(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyLong_FromSize_t(size);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GIT_OPT_SET_MWINDOW_SIZE:
|
||||
{
|
||||
size_t size;
|
||||
PyObject *py_size;
|
||||
|
||||
py_size = PyTuple_GetItem(args, 1);
|
||||
if (!py_size)
|
||||
return NULL;
|
||||
|
||||
if (!PyLong_Check(py_size))
|
||||
goto on_non_integer;
|
||||
|
||||
|
||||
size = PyLong_AsSize_t(py_size);
|
||||
if ((error = git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, size)) < 0) {
|
||||
Error_set(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_ValueError, "unknown/unsupported option value");
|
||||
return NULL;
|
||||
|
||||
on_non_integer:
|
||||
PyErr_SetString(PyExc_TypeError, "option is not an integer");
|
||||
return NULL;
|
||||
}
|
51
src/options.h
Normal file
51
src/options.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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_blame_h
|
||||
#define INCLUDE_pygit2_blame_h
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#include <git2.h>
|
||||
#include "types.h"
|
||||
|
||||
PyDoc_STRVAR(option__doc__,
|
||||
"Get or set a libgit2 option\n"
|
||||
"Arguments:\n"
|
||||
" (GIT_OPT_GET_SEARCH_PATH, level)\n"
|
||||
" Get the config search path for the given level\n"
|
||||
" (GIT_OPT_SET_SEARCH_PATH, level, path)\n"
|
||||
" Set the config search path for the given level\n"
|
||||
" (GIT_OPT_GET_MWINDOW_SIZE)\n"
|
||||
" Get the maximum mmap window size\n"
|
||||
" (GIT_OPT_SET_MWINDOW_SIZE, size)\n"
|
||||
" Set the maximum mmap window size\n");
|
||||
|
||||
|
||||
PyObject *option(PyObject *self, PyObject *args);
|
||||
|
||||
#endif
|
13
src/pygit2.c
13
src/pygit2.c
@@ -39,6 +39,7 @@
|
||||
#include "utils.h"
|
||||
#include "repository.h"
|
||||
#include "oid.h"
|
||||
#include "options.h"
|
||||
|
||||
/* FIXME: This is for pypy */
|
||||
#ifndef MAXPATHLEN
|
||||
@@ -244,6 +245,7 @@ PyMethodDef module_methods[] = {
|
||||
discover_repository__doc__},
|
||||
{"hashfile", hashfile, METH_VARARGS, hashfile__doc__},
|
||||
{"hash", hash, METH_VARARGS, hash__doc__},
|
||||
{"option", option, METH_VARARGS, option__doc__},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -259,6 +261,12 @@ moduleinit(PyObject* m)
|
||||
ADD_CONSTANT_INT(m, LIBGIT2_VER_REVISION)
|
||||
ADD_CONSTANT_STR(m, LIBGIT2_VERSION)
|
||||
|
||||
/* libgit2 options */
|
||||
ADD_CONSTANT_INT(m, GIT_OPT_GET_SEARCH_PATH);
|
||||
ADD_CONSTANT_INT(m, GIT_OPT_SET_SEARCH_PATH);
|
||||
ADD_CONSTANT_INT(m, GIT_OPT_GET_MWINDOW_SIZE);
|
||||
ADD_CONSTANT_INT(m, GIT_OPT_SET_MWINDOW_SIZE);
|
||||
|
||||
/* Errors */
|
||||
GitError = PyErr_NewException("_pygit2.GitError", NULL, NULL);
|
||||
Py_INCREF(GitError);
|
||||
@@ -424,6 +432,11 @@ moduleinit(PyObject* m)
|
||||
ADD_CONSTANT_INT(m, GIT_DIFF_FIND_AND_BREAK_REWRITES)
|
||||
|
||||
/* Config */
|
||||
ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_LOCAL);
|
||||
ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_GLOBAL);
|
||||
ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_XDG);
|
||||
ADD_CONSTANT_INT(m, GIT_CONFIG_LEVEL_SYSTEM);
|
||||
|
||||
INIT_TYPE(ConfigType, NULL, PyType_GenericNew)
|
||||
INIT_TYPE(ConfigIterType, NULL, NULL)
|
||||
ADD_TYPE(m, Config)
|
||||
|
57
test/test_options.py
Normal file
57
test/test_options.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
#
|
||||
# Copyright 2010-2014 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.
|
||||
|
||||
"""Tests for Blame objects."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import pygit2
|
||||
from pygit2 import GIT_OPT_GET_MWINDOW_SIZE, GIT_OPT_SET_MWINDOW_SIZE
|
||||
from pygit2 import GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH
|
||||
from pygit2 import GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_XDG, GIT_CONFIG_LEVEL_GLOBAL
|
||||
from pygit2 import option
|
||||
from . import utils
|
||||
|
||||
class OptionsTest(utils.NoRepoTestCase):
|
||||
|
||||
def test_mwindow_size(self):
|
||||
new_size = 200 * 1024
|
||||
option(GIT_OPT_SET_MWINDOW_SIZE, new_size)
|
||||
self.assertEqual(new_size, option(GIT_OPT_GET_MWINDOW_SIZE))
|
||||
|
||||
def test_search_path(self):
|
||||
paths = [(GIT_CONFIG_LEVEL_GLOBAL, '/tmp/global'),
|
||||
(GIT_CONFIG_LEVEL_XDG, '/tmp/xdg'),
|
||||
(GIT_CONFIG_LEVEL_SYSTEM, '/tmp/etc')]
|
||||
|
||||
for level, path in paths:
|
||||
option(GIT_OPT_SET_SEARCH_PATH, level, path)
|
||||
self.assertEqual(path, option(GIT_OPT_GET_SEARCH_PATH, level))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user