Merge remote-tracking branch 'carlos/config-parse'
This commit is contained in:
@@ -23,3 +23,10 @@ The Config type
|
|||||||
set multiple times in the configuration files.
|
set multiple times in the configuration files.
|
||||||
|
|
||||||
The :class:`Config` Mapping interface.
|
The :class:`Config` Mapping interface.
|
||||||
|
|
||||||
|
When using the mapping interface, the value is returned as a
|
||||||
|
string. In order to apply the git-config parsing rules, you can use
|
||||||
|
:method:`Config.get_bool` or :method:`Config.get_int`.
|
||||||
|
|
||||||
|
.. automethod:: pygit2.Config.get_bool
|
||||||
|
.. automethod:: pygit2.Config.get_int
|
||||||
|
101
src/config.c
101
src/config.c
@@ -168,43 +168,94 @@ Config_contains(Config *self, PyObject *py_key) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the C string value given a python string as key */
|
||||||
|
static int
|
||||||
|
get_string(const char **key_out, Config *self, PyObject *py_key)
|
||||||
|
{
|
||||||
|
PyObject *tkey;
|
||||||
|
const char *key;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
key = py_str_borrow_c_str(&tkey, py_key, NULL);
|
||||||
|
if (key == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
err = git_config_get_string(key_out, self->config, key);
|
||||||
|
Py_CLEAR(tkey);
|
||||||
|
|
||||||
|
if (err == GIT_ENOTFOUND) {
|
||||||
|
PyErr_SetObject(PyExc_KeyError, py_key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
Error_set(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Config_getitem(Config *self, PyObject *py_key)
|
Config_getitem(Config *self, PyObject *py_key)
|
||||||
{
|
{
|
||||||
int64_t value_int;
|
int err;
|
||||||
int err, value_bool;
|
|
||||||
const char *value_str;
|
const char *value_str;
|
||||||
const char *key;
|
|
||||||
PyObject* py_value, *tmp;
|
|
||||||
|
|
||||||
key = py_str_borrow_c_str(&tmp, py_key, NULL);
|
err = get_string(&value_str, self, py_key);
|
||||||
if (key == NULL)
|
if (err < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_config_get_string(&value_str, self->config, key);
|
return to_unicode(value_str, NULL, NULL);
|
||||||
Py_CLEAR(tmp);
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Config_get_bool__doc__,
|
||||||
|
"get_bool(key) -> Bool\n"
|
||||||
|
"\n"
|
||||||
|
"Look up *key* and parse its value as a boolean as per the git-config rules\n"
|
||||||
|
"\n"
|
||||||
|
"Truthy values are: 'true', 1, 'on' or 'yes'. Falsy values are: 'false',\n"
|
||||||
|
"0, 'off' and 'no'");
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Config_get_bool(Config *self, PyObject *key)
|
||||||
|
{
|
||||||
|
int err, value;
|
||||||
|
const char *value_str;
|
||||||
|
|
||||||
|
err = get_string(&value_str, self, key);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto cleanup;
|
return NULL;
|
||||||
|
|
||||||
if (git_config_parse_int64(&value_int, value_str) == 0)
|
if ((err = git_config_parse_bool(&value, value_str)) < 0)
|
||||||
py_value = PyLong_FromLongLong(value_int);
|
return NULL;
|
||||||
else if(git_config_parse_bool(&value_bool, value_str) == 0)
|
|
||||||
py_value = PyBool_FromLong(value_bool);
|
|
||||||
else
|
|
||||||
py_value = to_unicode(value_str, NULL, NULL);
|
|
||||||
|
|
||||||
cleanup:
|
return PyBool_FromLong(value);
|
||||||
if (err < 0) {
|
}
|
||||||
if (err == GIT_ENOTFOUND) {
|
|
||||||
PyErr_SetObject(PyExc_KeyError, py_key);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Error_set(err);
|
PyDoc_STRVAR(Config_get_int__doc__,
|
||||||
}
|
"get_int(key) -> int\n"
|
||||||
|
"\n"
|
||||||
|
"Look up *key* and parse its value as an integer as per the git-config rules\n"
|
||||||
|
"\n"
|
||||||
|
"A value can have a suffix 'k', 'm' or 'g' which stand for 'kilo', 'mega' and\n"
|
||||||
|
"'giga' respectively");
|
||||||
|
|
||||||
return py_value;
|
PyObject *
|
||||||
|
Config_get_int(Config *self, PyObject *key)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
int64_t value;
|
||||||
|
const char *value_str;
|
||||||
|
|
||||||
|
err = get_string(&value_str, self, key);
|
||||||
|
if (err < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((err = git_config_parse_int64(&value, value_str)) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return PyLong_FromLongLong(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -369,6 +420,8 @@ PyMethodDef Config_methods[] = {
|
|||||||
METHOD(Config, add_file, METH_VARARGS | METH_KEYWORDS),
|
METHOD(Config, add_file, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD(Config, get_multivar, METH_VARARGS),
|
METHOD(Config, get_multivar, METH_VARARGS),
|
||||||
METHOD(Config, set_multivar, METH_VARARGS),
|
METHOD(Config, set_multivar, METH_VARARGS),
|
||||||
|
METHOD(Config, get_bool, METH_O),
|
||||||
|
METHOD(Config, get_int, METH_O),
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#undef PyLong_Check
|
#undef PyLong_Check
|
||||||
#define PyLong_Check PyInt_Check
|
#define PyLong_Check PyInt_Check
|
||||||
#define PyLong_FromLong PyInt_FromLong
|
#define PyLong_FromLong PyInt_FromLong
|
||||||
|
#define PyInteger_Type PyInt_Type
|
||||||
#define PyBytes_AS_STRING PyString_AS_STRING
|
#define PyBytes_AS_STRING PyString_AS_STRING
|
||||||
#define PyBytes_AsString PyString_AsString
|
#define PyBytes_AsString PyString_AsString
|
||||||
#define PyBytes_AsStringAndSize PyString_AsStringAndSize
|
#define PyBytes_AsStringAndSize PyString_AsStringAndSize
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
#define to_path(x) to_bytes(x)
|
#define to_path(x) to_bytes(x)
|
||||||
#define to_encoding(x) to_bytes(x)
|
#define to_encoding(x) to_bytes(x)
|
||||||
#else
|
#else
|
||||||
|
#define PyInteger_Type PyLong_Type
|
||||||
#define to_path(x) to_unicode(x, Py_FileSystemDefaultEncoding, "strict")
|
#define to_path(x) to_unicode(x, Py_FileSystemDefaultEncoding, "strict")
|
||||||
#define to_encoding(x) PyUnicode_DecodeASCII(x, strlen(x), "strict")
|
#define to_encoding(x) PyUnicode_DecodeASCII(x, strlen(x), "strict")
|
||||||
#endif
|
#endif
|
||||||
|
@@ -74,7 +74,7 @@ class ConfigTest(utils.RepoTestCase):
|
|||||||
|
|
||||||
config_read = Config(CONFIG_FILENAME)
|
config_read = Config(CONFIG_FILENAME)
|
||||||
self.assertTrue('core.bare' in config_read)
|
self.assertTrue('core.bare' in config_read)
|
||||||
self.assertFalse(config_read['core.bare'])
|
self.assertFalse(config_read.get_bool('core.bare'))
|
||||||
self.assertTrue('core.editor' in config_read)
|
self.assertTrue('core.editor' in config_read)
|
||||||
self.assertEqual(config_read['core.editor'], 'ed')
|
self.assertEqual(config_read['core.editor'], 'ed')
|
||||||
|
|
||||||
@@ -88,9 +88,9 @@ class ConfigTest(utils.RepoTestCase):
|
|||||||
|
|
||||||
config.add_file(CONFIG_FILENAME, 0)
|
config.add_file(CONFIG_FILENAME, 0)
|
||||||
self.assertTrue('this.that' in config)
|
self.assertTrue('this.that' in config)
|
||||||
self.assertTrue(config['this.that'])
|
self.assertTrue(config.get_bool('this.that'))
|
||||||
self.assertTrue('something.other.here' in config)
|
self.assertTrue('something.other.here' in config)
|
||||||
self.assertFalse(config['something.other.here'])
|
self.assertFalse(config.get_bool('something.other.here'))
|
||||||
|
|
||||||
def test_read(self):
|
def test_read(self):
|
||||||
config = self.repo.config
|
config = self.repo.config
|
||||||
@@ -103,11 +103,11 @@ class ConfigTest(utils.RepoTestCase):
|
|||||||
lambda: config['abc.def'])
|
lambda: config['abc.def'])
|
||||||
|
|
||||||
self.assertTrue('core.bare' in config)
|
self.assertTrue('core.bare' in config)
|
||||||
self.assertFalse(config['core.bare'])
|
self.assertFalse(config.get_bool('core.bare'))
|
||||||
self.assertTrue('core.editor' in config)
|
self.assertTrue('core.editor' in config)
|
||||||
self.assertEqual(config['core.editor'], 'ed')
|
self.assertEqual(config['core.editor'], 'ed')
|
||||||
self.assertTrue('core.repositoryformatversion' in config)
|
self.assertTrue('core.repositoryformatversion' in config)
|
||||||
self.assertEqual(config['core.repositoryformatversion'], 0)
|
self.assertEqual(config.get_int('core.repositoryformatversion'), 0)
|
||||||
|
|
||||||
new_file = open(CONFIG_FILENAME, "w")
|
new_file = open(CONFIG_FILENAME, "w")
|
||||||
new_file.write("[this]\n\tthat = foobar\n\tthat = foobeer\n")
|
new_file.write("[this]\n\tthat = foobar\n\tthat = foobeer\n")
|
||||||
@@ -129,7 +129,7 @@ class ConfigTest(utils.RepoTestCase):
|
|||||||
self.assertFalse('core.dummy1' in config)
|
self.assertFalse('core.dummy1' in config)
|
||||||
config['core.dummy1'] = 42
|
config['core.dummy1'] = 42
|
||||||
self.assertTrue('core.dummy1' in config)
|
self.assertTrue('core.dummy1' in config)
|
||||||
self.assertEqual(config['core.dummy1'], 42)
|
self.assertEqual(config.get_int('core.dummy1'), 42)
|
||||||
|
|
||||||
self.assertFalse('core.dummy2' in config)
|
self.assertFalse('core.dummy2' in config)
|
||||||
config['core.dummy2'] = 'foobar'
|
config['core.dummy2'] = 'foobar'
|
||||||
|
Reference in New Issue
Block a user