From: Michael Tremer Date: Wed, 30 Jun 2021 14:59:40 +0000 (+0000) Subject: Add command for reverse dependency resolution X-Git-Tag: 0.9.28~1157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8201cef22c79ea875bfa4e94edeb02008320c53d;p=pakfire.git Add command for reverse dependency resolution Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index 40c389870..363aff7f4 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -472,6 +472,20 @@ static PyObject* Pakfire_whatprovides(PakfireObject* self, PyObject* args, PyObj return obj; } +static PyObject* Pakfire_whatrequires(PakfireObject* self, PyObject* args) { + const char* requires = NULL; + + if (!PyArg_ParseTuple(args, "s", &requires)) + return NULL; + + struct pakfire_packagelist* list = pakfire_whatrequires(self->pakfire, requires, 0); + + PyObject* obj = PyList_FromPackageList(list); + pakfire_packagelist_unref(list); + + return obj; +} + static PyObject* Pakfire_search(PakfireObject* self, PyObject* args) { const char* what; @@ -1018,6 +1032,12 @@ static struct PyMethodDef Pakfire_methods[] = { METH_VARARGS|METH_KEYWORDS, NULL }, + { + "whatrequires", + (PyCFunction)Pakfire_whatrequires, + METH_VARARGS, + NULL + }, { NULL }, }; diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 8bff00247..e066e052f 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -63,6 +63,7 @@ struct pakfire_repolist* pakfire_get_repos(Pakfire pakfire); PakfireRepo pakfire_get_repo(Pakfire pakfire, const char* name); struct pakfire_packagelist* pakfire_whatprovides(Pakfire pakfire, const char* provides, int flags); +struct pakfire_packagelist* pakfire_whatrequires(Pakfire pakfire, const char* what, int flags); struct pakfire_packagelist* pakfire_search(Pakfire pakfire, const char* what, int flags); // Logging diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 5ed69f299..4387cb3ba 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -44,6 +44,7 @@ global: pakfire_update; pakfire_version_compare; pakfire_whatprovides; + pakfire_whatrequires; # arch pakfire_arch_native; diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index d89981cb2..ea6c4d9d8 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -1374,6 +1374,42 @@ PAKFIRE_EXPORT struct pakfire_packagelist* pakfire_whatprovides(Pakfire pakfire, } } +PAKFIRE_EXPORT struct pakfire_packagelist* pakfire_whatrequires(Pakfire pakfire, const char* what, int flags) { + // Refresh repositories + int r = pakfire_refresh(pakfire, 0); + if (r) + return NULL; + + // Get the pool ready + pakfire_pool_apply_changes(pakfire); + + // Translate dependency to ID + Id dep = pakfire_parse_dep(pakfire, what); + if (!dep) { + errno = EINVAL; + return NULL; + } + + Queue matches; + queue_init(&matches); + + // Search for anything that matches + pool_whatmatchesdep(pakfire->pool, SOLVABLE_REQUIRES, dep, &matches, 0); + + // Create a packagelist + struct pakfire_packagelist* list = pakfire_packagelist_from_queue(pakfire, &matches); + + // Cleanup + queue_free(&matches); + + // Sort the list + if (list) { + pakfire_packagelist_sort(list); + } + + return list; +} + PAKFIRE_EXPORT struct pakfire_packagelist* pakfire_search(Pakfire pakfire, const char* what, int flags) { // Refresh repositories int r = pakfire_refresh(pakfire, 0); diff --git a/src/pakfire/cli.py b/src/pakfire/cli.py index 8d196bab5..a7ca30452 100644 --- a/src/pakfire/cli.py +++ b/src/pakfire/cli.py @@ -93,6 +93,13 @@ class Cli(object): provides.add_argument("pattern", nargs="+", help=_("File or feature to search for")) provides.set_defaults(func=self.handle_provides) + # requires + requires = subparsers.add_parser("requires", + help=_("Get a list of packages that require this dependency")) + requires.add_argument("pattern", required=True, + help=_("File or feature to search for")) + requires.set_defaults(func=self.handle_requires) + # reinstall reinstall = subparsers.add_parser("reinstall", help=_("Reinstall one or more packages")) @@ -283,6 +290,11 @@ class Cli(object): s = pkg.dump(long=long) print(s) + def handle_requires(self, ns): + for pkg in self.pakfire(ns).whatrequires(ns.pattern): + s = pkg.dump(long=True) + print(s) + def handle_repolist(self, ns): p = self.pakfire(ns) diff --git a/src/scripts/pakfire-builder.in b/src/scripts/pakfire-builder.in index b3a27a871..e2324f5fd 100644 --- a/src/scripts/pakfire-builder.in +++ b/src/scripts/pakfire-builder.in @@ -103,6 +103,13 @@ class Cli(object): help=_("File or feature to search for")) #provides.set_defaults(func=self._provides) + # requires + requires = subparsers.add_parser("requires", + help=_("Get a list of packages that require a given file or feature")) + requires.add_argument("pattern", required=True, + help=_("File or feature to search for")) + requires.set_defaults(func=self._requires) + # repolist repolist = subparsers.add_parser("repolist", help=_("List all currently enabled repositories")) @@ -215,6 +222,11 @@ class Cli(object): s = pkg.dump(long=True, filelist=ns.filelist) print(s) + def _requires(self, ns): + for pkg in self.pakfire(ns).whatrequires(ns.pattern): + s = pkg.dump(long=True) + print(s) + def _repolist(self, ns): """ List all repositories