From: Michael Tremer Date: Thu, 15 Dec 2016 22:00:50 +0000 (+0100) Subject: Rewrite _pakfire.Pool based on libpakfire X-Git-Tag: 0.9.28~1285^2~1365 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b8a51cb638b2f91bf686b0a4e043142a3572e0b9;p=pakfire.git Rewrite _pakfire.Pool based on libpakfire Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 1e3467f12..7e492a2af 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,9 @@ AM_CPPFLAGS = \ AM_CFLAGS = $(OUR_CFLAGS) AM_LDFLAGS = $(OUR_LDFLAGS) +PAKFIRE_CFLAGS = -I$(top_srcdir)/src/libpakfire/include +PAKFIRE_LIBS = libpakfire.la + lib_LTLIBRARIES = libexec_PROGRAMS = pkgpyexec_LTLIBRARIES = @@ -179,6 +182,8 @@ _pakfire_la_SOURCES = \ src/_pakfire/capabilities.c \ src/_pakfire/capabilities.h \ src/_pakfire/constants.h \ + src/_pakfire/package.c \ + src/_pakfire/package.h \ src/_pakfire/pool.c \ src/_pakfire/pool.h \ src/_pakfire/problem.c \ @@ -205,6 +210,7 @@ _pakfire_la_SOURCES = \ _pakfire_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON_DEVEL_CFLAGS) \ + $(PAKFIRE_CFLAGS) \ $(CAP_CFLAGS) \ $(SOLV_CFLAGS) @@ -216,6 +222,7 @@ _pakfire_la_LDFLAGS = \ _pakfire_la_LIBADD = \ $(PYTHON_DEVEL_LIBS) \ + $(PAKFIRE_LIBS) \ $(CAP_LIBS) \ $(SOLV_LIBS) diff --git a/src/_pakfire/_pakfiremodule.c b/src/_pakfire/_pakfiremodule.c index 84702e5ba..086da7a60 100644 --- a/src/_pakfire/_pakfiremodule.c +++ b/src/_pakfire/_pakfiremodule.c @@ -50,15 +50,6 @@ static PyMethodDef pakfireModuleMethods[] = { { NULL, NULL, 0, NULL } }; -static PyMethodDef Pool_methods[] = { - {"prepare", (PyCFunction)Pool_prepare, METH_NOARGS, NULL}, - {"size", (PyCFunction)Pool_size, METH_NOARGS, NULL}, - {"set_installed", (PyCFunction)Pool_set_installed, METH_VARARGS, NULL}, - {"providers", (PyCFunction)Pool_providers, METH_VARARGS, NULL}, - {"search", (PyCFunction)Pool_search, METH_VARARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - static PyMethodDef Problem_methods[] = { {"get_rule", (PyCFunction)Problem_get_rule, METH_NOARGS, NULL}, {"get_source", (PyCFunction)Problem_get_source, METH_NOARGS, NULL}, @@ -210,7 +201,6 @@ PyMODINIT_FUNC PyInit__pakfire(void) { return NULL; // Pool - PoolType.tp_methods = Pool_methods; if (PyType_Ready(&PoolType) < 0) return NULL; Py_INCREF(&PoolType); diff --git a/src/_pakfire/package.c b/src/_pakfire/package.c new file mode 100644 index 000000000..22976de55 --- /dev/null +++ b/src/_pakfire/package.c @@ -0,0 +1,28 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2016 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program 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. If not, see . # +# # +#############################################################################*/ + +#include + +#include "package.h" +#include "pool.h" + +PyObject* new_package(PoolObject* pool, Id id) { + return NULL; // XXX STUB +} diff --git a/src/_pakfire/package.h b/src/_pakfire/package.h new file mode 100644 index 000000000..47bf215f4 --- /dev/null +++ b/src/_pakfire/package.h @@ -0,0 +1,30 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2016 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program 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. If not, see . # +# # +#############################################################################*/ + +#ifndef PYTHON_PAKFIRE_PACKAGE_H +#define PYTHON_PAKFIRE_PACKAGE_H + +#include + +#include "pool.h" + +PyObject* new_package(PoolObject* pool, Id id); + +#endif /* PYTHON_PAKFIRE_PACKAGE_H */ diff --git a/src/_pakfire/pool.c b/src/_pakfire/pool.c index ed69a2cb7..3c0fc8206 100644 --- a/src/_pakfire/pool.c +++ b/src/_pakfire/pool.c @@ -23,222 +23,246 @@ #include #include +#include +#include +#include + #include "constants.h" #include "pool.h" #include "relation.h" #include "repo.h" #include "solvable.h" +#include "util.h" -PyTypeObject PoolType = { - PyVarObject_HEAD_INIT(NULL, 0) - tp_name: "_pakfire.Pool", - tp_basicsize: sizeof(PoolObject), - tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - tp_new : Pool_new, - tp_dealloc: (destructor) Pool_dealloc, - tp_doc: "Sat Pool objects", -}; - -// Pool -PyObject* Pool_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PoolObject *self; - const char *arch; - - if (!PyArg_ParseTuple(args, "s", &arch)) { - /* XXX raise exception */ - return NULL; - } - - self = (PoolObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->_pool = pool_create(); - -#ifdef DEBUG - // Enable debug messages when DEBUG is defined. - pool_setdebuglevel(self->_pool, 1); -#endif - - pool_setdisttype(self->_pool, DISTTYPE_RPM); - pool_setarch(self->_pool, arch); - if (self->_pool == NULL) { - Py_DECREF(self); - return NULL; - } +static PyObject* Pool_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { + PoolObject* self = (PoolObject *)type->tp_alloc(type, 0); + if (self) { + self->pool = NULL; } return (PyObject *)self; } -PyObject *Pool_dealloc(PoolObject *self) { - pool_free(self->_pool); - Py_TYPE(self)->tp_free((PyObject *)self); +static void Pool_dealloc(PoolObject* self) { + if (self->pool) + pakfire_pool_free(self->pool); - Py_RETURN_NONE; + Py_TYPE(self)->tp_free((PyObject *)self); } -PyObject *Pool_add_repo(PoolObject *self, PyObject *args) { - const char *name; - if (!PyArg_ParseTuple(args, "s", &name)) { - /* XXX raise exception */ +static int Pool_init(PoolObject* self, PyObject* args, PyObject* kwds) { + const char* arch; + + if (!PyArg_ParseTuple(args, "s", &arch)) + return -1; + + self->pool = pakfire_pool_create(arch); + if (self->pool == NULL) { + switch(pakfire_get_errno()) { + default: + assert(0); + } + return -1; } - RepoObject *repo; + return 0; +} + +static PyObject* Pool_version_compare(PoolObject* self, PyObject* args) { + const char* evr1 = NULL; + const char* evr2 = NULL; - repo = PyObject_New(RepoObject, &RepoType); - if (repo == NULL) + if (!PyArg_ParseTuple(args, "ss", &evr1, &evr2)) return NULL; - return (PyObject *)repo; + int cmp = pakfire_pool_version_compare(self->pool, evr1, evr2); + return PyLong_FromLong(cmp); +} + +static Py_ssize_t Pool_len(PoolObject* self) { + return pakfire_pool_count(self->pool); } -PyObject *Pool_prepare(PoolObject *self) { - _Pool_prepare(self->_pool); +static PyObject* Pool_get_installed_repo(PoolObject* self) { + PakfireRepo repo = pakfire_pool_get_installed_repo(self->pool); + if (!repo) + Py_RETURN_NONE; + + PyObject* obj = new_repo(self, pakfire_repo_get_name(repo)); + Py_XINCREF(obj); - Py_RETURN_NONE; + return obj; } -void _Pool_prepare(Pool *pool) { - pool_addfileprovides(pool); - pool_createwhatprovides(pool); +static int Pool_set_installed_repo(PoolObject* self, PyObject* value) { +#if 0 + if (PyObject_Not(value)) { + pakfire_pool_set_installed_repo(self->pool, NULL); + return 0; + } +#endif - Repo *r; - int idx; - FOR_REPOS(idx, r) { - repo_internalize(r); + if (!PyObject_TypeCheck(value, &RepoType)) { + PyErr_SetString(PyExc_ValueError, "Argument must be a _pakfire.Repo object"); + return -1; } -} -PyObject *Pool_size(PoolObject *self) { - Pool *pool = self->_pool; + RepoObject* repo = (RepoObject *)value; + pakfire_pool_set_installed_repo(self->pool, repo->repo); - return Py_BuildValue("i", pool->nsolvables); + return 0; } -PyObject *_Pool_search(Pool *pool, Repo *repo, const char *match, int option, const char *keyname) { - // Prepare the pool, so we can search in it. - _Pool_prepare(pool); - - Dataiterator d; - dataiterator_init(&d, pool, repo, 0, - keyname && pool ? pool_str2id(pool, keyname, 0) : 0, match, option); +static PyObject* Pool_get_installonly(PoolObject* self) { + const char** installonly = pakfire_pool_get_installonly(self->pool); - PyObject *list = PyList_New(0); + PyObject* list = PyList_New(0); + const char* name; - SolvableObject *solvable; - while (dataiterator_step(&d)) { - solvable = PyObject_New(SolvableObject, &SolvableType); - solvable->_pool = pool; - solvable->_id = d.solvid; + while ((name = *installonly++) != NULL) { + PyObject* item = PyUnicode_FromString(name); + PyList_Append(list, item); - PyList_Append(list, (PyObject *)solvable); + Py_DECREF(item); } - dataiterator_free(&d); + Py_INCREF(list); return list; } -PyObject *Pool_search(PoolObject *self, PyObject *args) { - const char *match = NULL; - int option = SEARCH_SUBSTRING; - const char *keyname = NULL; - - if (!PyArg_ParseTuple(args, "s|is", &match, &option, &keyname)) { - /* XXX raise exception */ - return NULL; +static int Pool_set_installonly(PoolObject* self, PyObject* value) { + if (!PySequence_Check(value)) { + PyErr_SetString(PyExc_AttributeError, "Expected a sequence."); + return -1; } - return _Pool_search(self->_pool, NULL, match, option, keyname); -} + const int length = PySequence_Length(value); + const char* installonly[length + 1]; -PyObject *Pool_set_installed(PoolObject *self, PyObject *args) { - RepoObject *repo; + for (int i = 0; i < length; i++) { + PyObject* item = PySequence_GetItem(value, i); - if (!PyArg_ParseTuple(args, "O", &repo)) { - /* XXX raise exception */ + installonly[i] = PyUnicode_AsUTF8(item); + Py_DECREF(item); } + installonly[length] = NULL; - pool_set_installed(self->_pool, repo->_repo); + pakfire_pool_set_installonly(self->pool, installonly); - Py_RETURN_NONE; + return 0; } -PyObject *Pool_providers(PoolObject *self, PyObject *args) { - char *name = NULL; - Queue job; - Solvable *solvable; - Pool *pool = self->_pool; - Id p, pp; - int i; +static PyObject* Pool_get_cache_path(PoolObject* self) { + const char* path = pakfire_pool_get_cache_path(self->pool); + if (!path) + Py_RETURN_NONE; - if (!PyArg_ParseTuple(args, "s", &name)) { - return NULL; - } - - _Pool_prepare(pool); - queue_init(&job); + return PyUnicode_FromString(path); +} - Id id = pool_str2id(pool, name, 0); +static int Pool_set_cache_path(PoolObject* self, PyObject* value) { + const char* path = PyUnicode_AsUTF8(value); + assert(path); - if (id) { - FOR_PROVIDES(p, pp, id) { - solvable = pool->solvables + p; + pakfire_pool_set_cache_path(self->pool, path); + return 0; +} - if (solvable->name == id) - queue_push2(&job, SOLVER_SOLVABLE, p); - } - } +static PyObject* Pool_whatprovides(PoolObject* self, PyObject* args, PyObject* kwds) { + char* kwlist[] = {"provides", "glob", "icase", "name_only", NULL}; - for (p = 1; p < pool->nsolvables; p++) { - solvable = pool->solvables + p; - if (!solvable->repo || !pool_installable(pool, solvable)) - continue; + const char* provides; + int glob = 0; + int icase = 0; + int name_only = 0; - id = solvable->name; - if (fnmatch(name, pool_id2str(pool, id), 0) == 0) { - for (i = 0; i < job.count; i += 2) { - if (job.elements[i] == SOLVER_SOLVABLE && job.elements[i + 1] == id) - break; - } + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|iii", kwlist, &provides, &glob, &icase, &name_only)) + return NULL; - if (i == job.count) - queue_push2(&job, SOLVER_SOLVABLE, p); - } - } + int flags = 0; + if (glob) + flags |= PAKFIRE_GLOB; + if (icase) + flags |= PAKFIRE_ICASE; + if (name_only) + flags |= PAKFIRE_NAME_ONLY; - for (id = 1; id < pool->ss.nstrings; id++) { - if (!pool->whatprovides[id]) - continue; + PakfirePackageList list = pakfire_pool_whatprovides(self->pool, provides, flags); - if (fnmatch(name, pool_id2str(pool, id), 0) == 0) { - Id *provides = pool->whatprovidesdata + pool->whatprovides[id]; + return PyList_FromPackageList(self, list); +} - while (*provides) { - for (i = 0; i < job.count; i += 2) { - if (job.elements[i] == SOLVER_SOLVABLE && job.elements[i + 1] == *provides) - break; - } +static PyObject* Pool_search(PoolObject* self, PyObject* args) { + const char* what; - if (i == job.count) - queue_push2(&job, SOLVER_SOLVABLE, *provides); + if (!PyArg_ParseTuple(args, "s", &what)) + return NULL; - provides++; - } - } - } + PakfirePackageList list = pakfire_pool_search(self->pool, what, 0); + return PyList_FromPackageList(self, list); +} - SolvableObject *s; - PyObject *list = PyList_New(0); +static struct PyMethodDef Pool_methods[] = { + { + "search", + (PyCFunction)Pool_search, + METH_VARARGS, + NULL + }, + { + "version_compare", + (PyCFunction)Pool_version_compare, + METH_VARARGS, + NULL + }, + { + "whatprovides", + (PyCFunction)Pool_whatprovides, + METH_VARARGS|METH_KEYWORDS, + NULL + }, + { NULL } +}; - for (i = 0; i < job.count; i += 2) { - switch (job.elements[i]) { - case SOLVER_SOLVABLE: - s = PyObject_New(SolvableObject, &SolvableType); - s->_pool = pool; - s->_id = job.elements[i + 1]; +static struct PyGetSetDef Pool_getsetters[] = { + { + "cache_path", + (getter)Pool_get_cache_path, + (setter)Pool_set_cache_path, + NULL, + NULL + }, + { + "installed_repo", + (getter)Pool_get_installed_repo, + (setter)Pool_set_installed_repo, + NULL, + NULL + }, + { + "installonly", + (getter)Pool_get_installonly, + (setter)Pool_set_installonly, + NULL, + NULL + }, + { NULL } +}; - PyList_Append(list, (PyObject *)s); - } - } +static PySequenceMethods Pool_sequence = { + sq_length: (lenfunc)Pool_len, +}; - return list; -} +PyTypeObject PoolType = { + PyVarObject_HEAD_INIT(NULL, 0) + tp_name: "_pakfire.Pool", + tp_basicsize: sizeof(PoolObject), + tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + tp_new: Pool_new, + tp_dealloc: (destructor)Pool_dealloc, + tp_init: (initproc)Pool_init, + tp_doc: "Pool object", + tp_methods: Pool_methods, + tp_getset: Pool_getsetters, + tp_as_sequence: &Pool_sequence, +}; diff --git a/src/_pakfire/pool.h b/src/_pakfire/pool.h index d535a2fda..a4a135212 100644 --- a/src/_pakfire/pool.h +++ b/src/_pakfire/pool.h @@ -18,29 +18,21 @@ # # #############################################################################*/ -#ifndef PAKFIRE_POOL_H -#define PAKFIRE_POOL_H +#ifndef PYTHON_PAKFIRE_POOL_H +#define PYTHON_PAKFIRE_POOL_H #include -#include +#include -// Sat Pool object typedef struct { - PyObject_HEAD - Pool *_pool; -} PoolObject; + PyObject_HEAD + PakfirePool pool; -extern PyObject* Pool_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -extern PyObject *Pool_dealloc(PoolObject *self); -extern PyObject *Pool_add_repo(PoolObject *self, PyObject *args); -extern PyObject *Pool_prepare(PoolObject *self); -extern void _Pool_prepare(Pool *pool); -extern PyObject *Pool_search(PoolObject *self, PyObject *args); -extern PyObject *Pool_set_installed(PoolObject *self, PyObject *args); -extern PyObject *Pool_providers(PoolObject *self, PyObject *args); -extern PyObject *Pool_size(PoolObject *self); + // XXX COMPAT + Pool* _pool; +} PoolObject; extern PyTypeObject PoolType; -#endif +#endif /* PYTHON_PAKFIRE_POOL_H */ diff --git a/src/_pakfire/repo.c b/src/_pakfire/repo.c index ac317195e..c5810f1ed 100644 --- a/src/_pakfire/repo.c +++ b/src/_pakfire/repo.c @@ -40,6 +40,15 @@ PyTypeObject RepoType = { tp_doc: "Sat Repo objects", }; +PyObject* new_repo(PoolObject* pool, const char* name) { + PyObject* args = Py_BuildValue("Os", (PyObject *)pool, name); + PyObject* repo = PyObject_CallObject((PyObject *)&RepoType, args); + + Py_DECREF(args); + + return repo; +} + PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { RepoObject *self; diff --git a/src/_pakfire/repo.h b/src/_pakfire/repo.h index 9de636f57..02675f8a0 100644 --- a/src/_pakfire/repo.h +++ b/src/_pakfire/repo.h @@ -18,19 +18,25 @@ # # #############################################################################*/ -#ifndef PAKFIRE_REPO_H -#define PAKFIRE_REPO_H +#ifndef PYTHON_PAKFIRE_REPO_H +#define PYTHON_PAKFIRE_REPO_H #include +#include #include +#include "pool.h" + // Sat Repo object typedef struct { - PyObject_HEAD - Repo *_repo; + PyObject_HEAD + PakfireRepo repo; + Repo *_repo; } RepoObject; +PyObject* new_repo(PoolObject* pool, const char* name); + extern PyObject *Repo_dealloc(RepoObject *self); extern PyObject* Repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds); extern PyObject *Repo_name(RepoObject *self); @@ -47,4 +53,4 @@ extern PyObject *Repo_get_all(RepoObject *self); extern PyTypeObject RepoType; -#endif +#endif /* PYTHON_PAKFIRE_REPO_H */ diff --git a/src/_pakfire/solver.c b/src/_pakfire/solver.c index aaca762b8..cf7761d5d 100644 --- a/src/_pakfire/solver.c +++ b/src/_pakfire/solver.c @@ -202,8 +202,10 @@ PyObject *Solver_solve(SolverObject *self, PyObject *args) { return NULL; } +#if 0 // Make sure, the pool is prepared. _Pool_prepare(self->_solver->pool); +#endif /* Force best solution. */ if (force_best) { diff --git a/src/_pakfire/util.c b/src/_pakfire/util.c index aaf50b34d..c62c070ed 100644 --- a/src/_pakfire/util.c +++ b/src/_pakfire/util.c @@ -26,7 +26,12 @@ #include #include +#include +#include +#include + #include "constants.h" +#include "package.h" #include "util.h" PyObject *_personality(PyObject *self, PyObject *args) { @@ -136,3 +141,18 @@ PyObject* performance_index(PyObject* self, PyObject* args) { return PyLong_FromUnsignedLong(iterations); } + +PyObject* PyList_FromPackageList(PoolObject* pool, PakfirePackageList packagelist) { + PyObject* list = PyList_New(0); + + int count = pakfire_packagelist_count(packagelist); + for (int i = 0; i < count; i++) { + PakfirePackage package = pakfire_packagelist_get(packagelist, i); + + PyObject* item = new_package(pool, pakfire_package_id(package)); + PyList_Append(list, item); + Py_DECREF(item); + } + + return list; +} diff --git a/src/_pakfire/util.h b/src/_pakfire/util.h index 97d5bb3a4..f7f43f342 100644 --- a/src/_pakfire/util.h +++ b/src/_pakfire/util.h @@ -18,17 +18,22 @@ # # #############################################################################*/ -#ifndef PAKFIRE_UTIL_H -#define PAKFIRE_UTIL_H +#ifndef PYTHON_PAKFIRE_UTIL_H +#define PYTHON_PAKFIRE_UTIL_H #include +#include #include +#include "pool.h" + extern PyObject *_personality(PyObject *self, PyObject *args); extern PyObject *_sync(PyObject *self, PyObject *args); extern PyObject *_unshare(PyObject *self, PyObject *args); extern PyObject *version_compare(PyObject *self, PyObject *args); extern PyObject* performance_index(PyObject* self, PyObject* args); -#endif +PyObject* PyList_FromPackageList(PoolObject* pool, PakfirePackageList packagelist); + +#endif /* PYTHON_PAKFIRE_UTIL_H */