From e313dac156c064aa1ff7e502fba6d6e6e221d610 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sun, 28 Oct 2012 13:40:22 +0100 Subject: [PATCH] Make "whatprovides" more mighty with globbing. --- python/pakfire/base.py | 7 ++- python/pakfire/cli.py | 2 +- python/pakfire/repository/__init__.py | 6 -- python/pakfire/satsolver.py | 8 +++ python/src/pool.c | 81 ++++++++++++++++++++++----- 5 files changed, 82 insertions(+), 22 deletions(-) diff --git a/python/pakfire/base.py b/python/pakfire/base.py index a9429ca3e..5a9630423 100644 --- a/python/pakfire/base.py +++ b/python/pakfire/base.py @@ -538,13 +538,16 @@ class Pakfire(object): pkgs = [] for pattern in patterns: - for pkg in self.repos.whatprovides(pattern): + for pkg in self.pool.whatprovides(self, pattern): if pkg in pkgs: continue pkgs.append(pkg) - return sorted(pkgs) + # Sort output. + pkgs.sort() + + return pkgs def resolvdep(self, pkg): # Initialize this pakfire instance. diff --git a/python/pakfire/cli.py b/python/pakfire/cli.py index a4a64a3e0..825c127ec 100644 --- a/python/pakfire/cli.py +++ b/python/pakfire/cli.py @@ -591,7 +591,7 @@ class CliBuilder(Cli): p.dist(pkg, resultdir=resultdir) def handle_provides(self): - Cli.handle_provides(long=True) + Cli.handle_provides(self, long=True) class CliServer(Cli): diff --git a/python/pakfire/repository/__init__.py b/python/pakfire/repository/__init__.py index 660497540..c4d94bd82 100644 --- a/python/pakfire/repository/__init__.py +++ b/python/pakfire/repository/__init__.py @@ -194,12 +194,6 @@ class Repositories(object): if repo.name == name or name == "*": repo.enabled = False - def whatprovides(self, what): - what = self.pakfire.pool.create_relation(what) - - for solv in self.pool.providers(what): - yield packages.SolvPackage(self.pakfire, solv) - def clean(self): log.info("Cleaning up all repository caches...") diff --git a/python/pakfire/satsolver.py b/python/pakfire/satsolver.py index 1aaee7462..0b726f214 100644 --- a/python/pakfire/satsolver.py +++ b/python/pakfire/satsolver.py @@ -178,6 +178,14 @@ class Pool(_pakfire.Pool): # Return the solver so one can do stuff with it... return solver + def whatprovides(self, pakfire, what): + pkgs = [] + for solv in self.providers(what): + pkg = packages.SolvPackage(pakfire, solv) + pkgs.append(pkg) + + return pkgs + class Request(_pakfire.Request): def install(self, what): diff --git a/python/src/pool.c b/python/src/pool.c index 3c418a247..04607396a 100644 --- a/python/src/pool.c +++ b/python/src/pool.c @@ -19,7 +19,9 @@ #############################################################################*/ #include +#include #include +#include #include "config.h" #include "pool.h" @@ -160,28 +162,81 @@ PyObject *Pool_set_installed(PoolObject *self, PyObject *args) { } PyObject *Pool_providers(PoolObject *self, PyObject *args) { - RelationObject *relation; + char *name = NULL; + Queue job; + Solvable *solvable; + Pool *pool = self->_pool; + Id p, pp; + int i; - if (!PyArg_ParseTuple(args, "O", &relation)) { - /* XXX raise exception */ + if (!PyArg_ParseTuple(args, "s", &name)) { return NULL; } - Id id = relation->_id; - - Pool *pool = self->_pool; _Pool_prepare(pool); + queue_init(&job); + + Id id = pool_str2id(pool, name, 0); + + if (id) { + FOR_PROVIDES(p, pp, id) { + solvable = pool->solvables + p; + + if (solvable->name == id) + queue_push2(&job, SOLVER_SOLVABLE, p); + } + } + + for (p = 1; p < pool->nsolvables; p++) { + solvable = pool->solvables + p; + if (!solvable->repo || !pool_installable(pool, solvable)) + continue; + + 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 (i == job.count) + queue_push2(&job, SOLVER_SOLVABLE, p); + } + } + + for (id = 1; id < pool->ss.nstrings; id++) { + if (!pool->whatprovides[id]) + continue; + + if (fnmatch(name, pool_id2str(pool, id), 0) == 0) { + Id *provides = pool->whatprovidesdata + pool->whatprovides[id]; + + while (*provides) { + for (i = 0; i < job.count; i += 2) { + if (job.elements[i] == SOLVER_SOLVABLE && job.elements[i + 1] == *provides) + break; + } + + if (i == job.count) + queue_push2(&job, SOLVER_SOLVABLE, *provides); + + *provides++; + } + } + } + SolvableObject *s; PyObject *list = PyList_New(0); - Id p, pp; - SolvableObject *solvable; - FOR_PROVIDES(p, pp, id) { - solvable = PyObject_New(SolvableObject, &SolvableType); - solvable->_pool = self->_pool; - solvable->_id = p; + 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]; - PyList_Append(list, (PyObject *)solvable); + PyList_Append(list, (PyObject *)s); + } } return list; -- 2.39.5