From: Michael Tremer Date: Sun, 28 Jul 2013 11:20:55 +0000 (+0200) Subject: Implement distro-sync. X-Git-Url: http://git.ipfire.org/?p=people%2Fstevee%2Fpakfire.git;a=commitdiff_plain;h=d314d72b8e19dc109043329ffa354d732b95eb5a Implement distro-sync. --- diff --git a/Makeconfig b/Makeconfig index b9f7898d..2d5434cd 100644 --- a/Makeconfig +++ b/Makeconfig @@ -31,7 +31,7 @@ ifeq "$(PYTHON_VERSION)" "" $(error Could not determine the version of the python interpreter.) endif -PYTHON_CC = $(CC) -pthread -fPIC +PYTHON_CC = $(CC) -pthread -fPIC -std=c99 PYTHON_CFLAGS = $(shell python-config --cflags) PYTHON_MODULES = pakfire pakfire/packages pakfire/repository ifeq "$(DEBIAN)" "1" diff --git a/python/pakfire/base.py b/python/pakfire/base.py index 943a999d..6b53a496 100644 --- a/python/pakfire/base.py +++ b/python/pakfire/base.py @@ -344,7 +344,7 @@ class Pakfire(object): t.run(logger=logger) - def update(self, pkgs=None, check=False, excludes=None, interactive=True, logger=None, **kwargs): + def update(self, pkgs=None, check=False, excludes=None, interactive=True, logger=None, sync=False, **kwargs): """ check indicates, if the method should return after calculation of the transaction. @@ -370,6 +370,14 @@ class Pakfire(object): exclude = self.pool.create_relation(exclude) request.lock(exclude) + # Update or downgrade to the latest version of all packages + # in the enabled repositories. + if sync: + kwargs.update({ + "allow_downgrade" : True, + "allow_uninstall" : True, + }) + solver = self.pool.solve(request, logger=logger, **kwargs) if not solver.status: diff --git a/python/pakfire/cli.py b/python/pakfire/cli.py index a80b397e..01e0f024 100644 --- a/python/pakfire/cli.py +++ b/python/pakfire/cli.py @@ -68,6 +68,7 @@ class Cli(object): self.parse_command_info() self.parse_command_search() self.parse_command_check_update() + self.parse_command_distro_sync() self.parse_command_update() self.parse_command_downgrade() self.parse_command_provides() @@ -87,6 +88,7 @@ class Cli(object): "reinstall" : self.handle_reinstall, "remove" : self.handle_remove, "check_update" : self.handle_check_update, + "distro_sync" : self.handle_distro_sync, "update" : self.handle_update, "downgrade" : self.handle_downgrade, "info" : self.handle_info, @@ -186,9 +188,11 @@ class Cli(object): sub_remove.add_argument("action", action="store_const", const="remove") @staticmethod - def _parse_command_update(parser): - parser.add_argument("package", nargs="*", - help=_("Give a name of a package to update or leave emtpy for all.")) + def _parse_command_update(parser, package=True): + if package: + parser.add_argument("package", nargs="*", + help=_("Give a name of a package to update or leave emtpy for all.")) + parser.add_argument("--exclude", "-x", nargs="+", help=_("Exclude package from update.")) parser.add_argument("--allow-vendorchange", action="store_true", @@ -203,6 +207,13 @@ class Cli(object): sub_update.add_argument("action", action="store_const", const="update") self._parse_command_update(sub_update) + def parse_command_distro_sync(self): + # Implement the "distro-sync" command. + sub_distro_sync = self.sub_commands.add_parser("distro-sync", + help=_("Sync all installed with the latest one in the distribution.")) + sub_distro_sync.add_argument("action", action="store_const", const="distro_sync") + self._parse_command_update(sub_distro_sync, package=False) + def parse_command_check_update(self): # Implement the "check-update" command. sub_check_update = self.sub_commands.add_parser("check-update", @@ -328,13 +339,19 @@ class Cli(object): def handle_update(self, **args): p = self.create_pakfire() - p.update( - self.args.package, - excludes=self.args.exclude, - allow_vendorchange=self.args.allow_vendorchange, - allow_archchange=not self.args.disallow_archchange, - **args - ) + + packages = getattr(self.args, "package", []) + + args.update({ + "allow_archchange" : not self.args.disallow_archchange, + "allow_vendorchange" : self.args.allow_vendorchange, + "excludes" : self.args.exclude, + }) + + p.update(packages, **args) + + def handle_distro_sync(self): + self.handle_update(sync=True) def handle_check_update(self): self.handle_update(check=True) diff --git a/python/pakfire/satsolver.py b/python/pakfire/satsolver.py index 29288554..5b692b8f 100644 --- a/python/pakfire/satsolver.py +++ b/python/pakfire/satsolver.py @@ -159,7 +159,7 @@ class Pool(_pakfire.Pool): raise DependencyError, solver.get_problem_string() - def solve(self, request, interactive=False, logger=None, **kwargs): + def solve(self, request, interactive=False, logger=None, force_best=False, **kwargs): # XXX implement interactive if not logger: @@ -173,7 +173,7 @@ class Pool(_pakfire.Pool): solver.set(key, val) # Do the solving. - solver.solve() + solver.solve(force_best=force_best) # Return the solver so one can do stuff with it... return solver @@ -315,12 +315,12 @@ class Solver(object): raise Exception, "Unknown configuration setting: %s" % option return self.solver.get_flag(flag) - def solve(self): + def solve(self, force_best=False): assert self.status is None, "Solver did already solve something." # Actually solve the request. start_time = time.time() - self.status = self.solver.solve(self.request) + self.status = self.solver.solve(self.request, force_best) # Save the amount of time that was needed to solve the request. self.time = time.time() - start_time diff --git a/python/src/solver.c b/python/src/solver.c index 54e12947..87704df7 100644 --- a/python/src/solver.c +++ b/python/src/solver.c @@ -56,6 +56,9 @@ PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { /* enable splitprovides by default */ solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, 1); + /* keep explicit obsoletes */ + solver_set_flag(self->_solver, SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES, 1); + return (PyObject *)self; } @@ -192,15 +195,22 @@ PyObject *Solver_set_do_split_provides(SolverObject *self, PyObject *args) { PyObject *Solver_solve(SolverObject *self, PyObject *args) { RequestObject *request; + int force_best = 0; int res = 0; - if (!PyArg_ParseTuple(args, "O", &request)) { + if (!PyArg_ParseTuple(args, "O|i", &request, &force_best)) { return NULL; } // Make sure, the pool is prepared. _Pool_prepare(self->_solver->pool); + /* Force best solution. */ + if (force_best) { + for (int i = 0; i < request->_queue.count; i += 2) + request->_queue.elements[i] |= SOLVER_FORCEBEST; + } + res = solver_solve(self->_solver, &request->_queue); #ifdef DEBUG