diff options
-rw-r--r-- | bindings/solv.i | 6 | ||||
-rwxr-xr-x | examples/pysolv | 8 | ||||
-rw-r--r-- | src/rules.c | 35 | ||||
-rw-r--r-- | src/solver.c | 87 | ||||
-rw-r--r-- | test/testcases/cleandeps/cleandeps_dup.t | 33 | ||||
-rw-r--r-- | test/testcases/cleandeps/cleandeps_in.t | 15 | ||||
-rw-r--r-- | test/testcases/cleandeps/cleandeps_up.t | 33 | ||||
-rw-r--r-- | test/testcases/cleandeps/mistake-packages.repo | 3 | ||||
-rw-r--r-- | test/testcases/cleandeps/mistake-system.repo | 3 | ||||
-rw-r--r-- | test/testcases/cleandeps/mistake.t | 11 |
10 files changed, 176 insertions, 58 deletions
diff --git a/bindings/solv.i b/bindings/solv.i index 8bd8ee4..d83df92 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -777,11 +777,14 @@ typedef struct { static const Id SOLVER_WEAK = SOLVER_WEAK; static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL; static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS; + static const Id SOLVER_FORCEBEST = SOLVER_FORCEBEST; + static const Id SOLVER_TARGETED = SOLVER_TARGETED; static const Id SOLVER_SETEV = SOLVER_SETEV; static const Id SOLVER_SETEVR = SOLVER_SETEVR; static const Id SOLVER_SETARCH = SOLVER_SETARCH; static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR; static const Id SOLVER_SETREPO = SOLVER_SETREPO; + static const Id SOLVER_SETNAME = SOLVER_SETNAME; static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET; static const Id SOLVER_SETMASK = SOLVER_SETMASK; @@ -2372,7 +2375,7 @@ typedef struct { Id extraflags = solver_solutionelement_extrajobflags($self->solv, $self->problemid, $self->solutionid); if ($self->type == SOLVER_SOLUTION_JOB) return new_Job($self->solv->pool, SOLVER_NOOP, 0); - if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE) + if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE || $self->type == SOLVER_SOLUTION_BEST) return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->p); if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE) return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->rp); @@ -2406,6 +2409,7 @@ typedef struct { static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB; static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH; static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE; + static const int SOLVER_SOLUTION_BEST = SOLVER_SOLUTION_BEST; static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE; static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE; static const int SOLVER_SOLUTION_REPLACE_DOWNGRADE = SOLVER_SOLUTION_REPLACE_DOWNGRADE; diff --git a/examples/pysolv b/examples/pysolv index 23cdd98..7e2eda5 100755 --- a/examples/pysolv +++ b/examples/pysolv @@ -568,7 +568,9 @@ def load_stub(repodata): parser = OptionParser(usage="usage: solv.py [options] COMMAND") -parser.add_option('-r', '--repo', action="append", type="string", dest="repos") +parser.add_option('-r', '--repo', action="append", type="string", dest="repos", help="limit to specified repositories") +parser.add_option('--best', action="store_true", dest="best", help="force installation/update to best packages") +parser.add_option('--clean', action="store_true", dest="clean", help="delete no longer needed packages") (options, args) = parser.parse_args() if not args: parser.print_help(sys.stderr) @@ -744,6 +746,10 @@ if cmd == 'list' or cmd == 'info': for job in jobs: if cmd == 'up' and job.isemptyupdate(): job.how ^= Job.SOLVER_UPDATE ^ Job.SOLVER_INSTALL + if options.best: + job.how |= Job.SOLVER_FORCEBEST + if options.clean: + job.how |= Job.SOLVER_CLEANDEPS #pool.set_debuglevel(2) solver = None diff --git a/src/rules.c b/src/rules.c index 5f8cfbc..4a9459d 100644 --- a/src/rules.c +++ b/src/rules.c @@ -1181,6 +1181,17 @@ reenableinfarchrule(Solver *solv, Id name) *** ***/ +static inline void +add_cleandeps_package(Solver *solv, Id p) +{ + if (!solv->cleandeps_updatepkgs) + { + solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue)); + queue_init(solv->cleandeps_updatepkgs); + } + queue_pushunique(solv->cleandeps_updatepkgs, p); +} + static inline void solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted) { @@ -1211,6 +1222,8 @@ solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted) map_grow(&solv->bestupdatemap, installed->end - installed->start); MAPSET(&solv->bestupdatemap, pi - installed->start); } + if (ps->repo == installed && (how & SOLVER_CLEANDEPS) != 0) + add_cleandeps_package(solv, pi); if (!targeted && ps->repo != installed) MAPSET(&solv->dupmap, pi); } @@ -1254,6 +1267,8 @@ solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted) map_grow(&solv->bestupdatemap, installed->end - installed->start); MAPSET(&solv->bestupdatemap, pi - installed->start); } + if (ps->repo == installed && (how & SOLVER_CLEANDEPS) != 0) + add_cleandeps_package(solv, pi); } } } @@ -2692,7 +2707,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded) Id p, pp, ip, jp; Id req, *reqp, sup, *supp; Solvable *s; - Queue iq; + Queue iq, iqcopy; int i; map_empty(cleandepsmap); @@ -2787,9 +2802,9 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded) for (rid = solv->jobrules; rid < solv->jobrules_end; rid++) { r = solv->rules + rid; - if (r->d < 0) + if (r->d < 0) /* disabled? */ continue; - if (r->d == 0 && r->p < 0 && r->w2 == 0) + if (r->d == 0 && r->p < 0 && r->w2 == 0) /* negative assertion (erase job)? */ { p = -r->p; if (pool->solvables[p].repo != installed) @@ -2802,7 +2817,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded) if ((how & (SOLVER_JOBMASK|SOLVER_CLEANDEPS)) == (SOLVER_ERASE|SOLVER_CLEANDEPS)) queue_push(&iq, p); } - else if (r->p > 0) + else if (r->p > 0) /* install job */ { if (unneeded) continue; @@ -2859,6 +2874,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded) } } } + queue_init_clone(&iqcopy, &iq); if (!unneeded) { @@ -3134,12 +3150,17 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded) } queue_free(&iq); + /* make sure the updatepkgs and mistakes are not in the cleandeps map */ if (solv->cleandeps_updatepkgs) for (i = 0; i < solv->cleandeps_updatepkgs->count; i++) MAPSET(&im, solv->cleandeps_updatepkgs->elements[i]); if (solv->cleandeps_mistakes) for (i = 0; i < solv->cleandeps_mistakes->count; i++) MAPSET(&im, solv->cleandeps_mistakes->elements[i]); + /* also remove original iq packages */ + for (i = 0; i < iqcopy.count; i++) + MAPSET(&im, iqcopy.elements[i]); + queue_free(&iqcopy); for (p = installed->start; p < installed->end; p++) { if (pool->solvables[p].repo != installed) @@ -3150,6 +3171,12 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded) map_free(&im); map_free(&installedm); map_free(&userinstalled); +#ifdef CLEANDEPSDEBUG + printf("=== final cleandeps map:\n"); + for (p = installed->start; p < installed->end; p++) + if (MAPTST(cleandepsmap, p - installed->start)) + printf(" - %s\n", pool_solvid2str(pool, p)); +#endif } diff --git a/src/solver.c b/src/solver.c index 36af038..8b6140c 100644 --- a/src/solver.c +++ b/src/solver.c @@ -2639,6 +2639,17 @@ solver_addjobrule(Solver *solv, Id p, Id d, Id job, int weak) queue_push(&solv->weakruleq, solv->nrules - 1); } +static inline void +add_cleandeps_package(Solver *solv, Id p) +{ + if (!solv->cleandeps_updatepkgs) + { + solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue)); + queue_init(solv->cleandeps_updatepkgs); + } + queue_pushunique(solv->cleandeps_updatepkgs, p); +} + static void add_update_target(Solver *solv, Id p, Id how) { @@ -2667,6 +2678,8 @@ add_update_target(Solver *solv, Id p, Id how) map_grow(&solv->bestupdatemap, installed->end - installed->start); MAPSET(&solv->bestupdatemap, pi - installed->start); } + if (how & SOLVER_CLEANDEPS) + add_cleandeps_package(solv, pi); queue_push2(solv->update_targets, pi, p); /* check if it's ok to keep the installed package */ if (s->evr == si->evr && solvable_identical(s, si)) @@ -2694,6 +2707,8 @@ add_update_target(Solver *solv, Id p, Id how) map_grow(&solv->bestupdatemap, installed->end - installed->start); MAPSET(&solv->bestupdatemap, pi - installed->start); } + if (how & SOLVER_CLEANDEPS) + add_cleandeps_package(solv, pi); queue_push2(solv->update_targets, pi, p); } } @@ -2795,11 +2810,18 @@ solver_solve(Solver *solv, Queue *job) queue_free(&solv->job); queue_init_clone(&solv->job, job); + /* free old stuff */ if (solv->update_targets) { queue_free(solv->update_targets); solv->update_targets = solv_free(solv->update_targets); } + if (solv->cleandeps_updatepkgs) + { + queue_free(solv->cleandeps_updatepkgs); + solv->cleandeps_updatepkgs = solv_free(solv->cleandeps_updatepkgs); + } + /* * create basic rule set of all involved packages * use addedmap bitmap to make sure we don't create rules twice @@ -2849,6 +2871,11 @@ solver_solve(Solver *solv, Queue *job) solv->updatemap_all = 1; if (how & SOLVER_FORCEBEST) solv->bestupdatemap_all = 1; + if (how & SOLVER_CLEANDEPS) + { + FOR_REPO_SOLVABLES(installed, p, s) + add_cleandeps_package(solv, p); + } } else if (select == SOLVER_SOLVABLE_REPO) { @@ -2860,6 +2887,11 @@ solver_solve(Solver *solv, Queue *job) solv->updatemap_all = 1; if (how & SOLVER_FORCEBEST) solv->bestupdatemap_all = 1; + if (how & SOLVER_CLEANDEPS) + { + FOR_REPO_SOLVABLES(installed, p, s) + add_cleandeps_package(solv, p); + } break; } if (solv->noautotarget && !(how & SOLVER_TARGETED)) @@ -2887,6 +2919,8 @@ solver_solve(Solver *solv, Queue *job) map_grow(&solv->bestupdatemap, installed->end - installed->start); MAPSET(&solv->bestupdatemap, p - installed->start); } + if (how & SOLVER_CLEANDEPS) + add_cleandeps_package(solv, p); targeted = 0; } if (!targeted || solv->noautotarget) @@ -3074,11 +3108,6 @@ solver_solve(Solver *solv, Queue *job) */ solv->jobrules = solv->nrules; - if (solv->cleandeps_updatepkgs) - { - queue_free(solv->cleandeps_updatepkgs); - solv->cleandeps_updatepkgs = solv_free(solv->cleandeps_updatepkgs); - } for (i = 0; i < job->count; i += 2) { oldnrules = solv->nrules; @@ -3172,37 +3201,6 @@ solver_solve(Solver *solv, Queue *job) break; case SOLVER_UPDATE: - if ((how & SOLVER_CLEANDEPS) != 0 && installed) - { - if (how == SOLVER_SOLVABLE_ALL || (how == SOLVER_SOLVABLE_REPO && what == installed->repoid)) - { - FOR_REPO_SOLVABLES(installed, p, s) - { - if (!solv->cleandeps_updatepkgs) - { - solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue)); - queue_init(solv->cleandeps_updatepkgs); - } - queue_pushunique(solv->cleandeps_updatepkgs, p); - if (!solv->cleandepsmap.size) - map_grow(&solv->cleandepsmap, installed->end - installed->start); - } - } - FOR_JOB_SELECT(p, pp, select, what) - { - s = pool->solvables + p; - if (s->repo != installed) - continue; - if (!solv->cleandeps_updatepkgs) - { - solv->cleandeps_updatepkgs = solv_calloc(1, sizeof(Queue)); - queue_init(solv->cleandeps_updatepkgs); - } - queue_pushunique(solv->cleandeps_updatepkgs, p); - if (!solv->cleandepsmap.size) - map_grow(&solv->cleandepsmap, installed->end - installed->start); - } - } POOL_DEBUG(SOLV_DEBUG_JOB, "job: %supdate %s\n", weak ? "weak " : "", solver_select2str(pool, select, what)); break; case SOLVER_VERIFY: @@ -3338,6 +3336,16 @@ solver_solve(Solver *solv, Queue *job) MAPSET(&solv->weakrulemap, p); } + /* enable cleandepsmap creation if we have updatepkgs */ + if (solv->cleandeps_updatepkgs && !solv->cleandepsmap.size) + map_grow(&solv->cleandepsmap, installed->end - installed->start); + /* no mistakes */ + if (solv->cleandeps_mistakes) + { + queue_free(solv->cleandeps_mistakes); + solv->cleandeps_mistakes = solv_free(solv->cleandeps_mistakes); + } + /* all new rules are learnt after this point */ solv->learntrules = solv->nrules; @@ -3357,13 +3365,6 @@ solver_solve(Solver *solv, Queue *job) makeruledecisions(solv); POOL_DEBUG(SOLV_DEBUG_SOLVER, "problems so far: %d\n", solv->problems.count); - /* no mistakes */ - if (solv->cleandeps_mistakes) - { - queue_free(solv->cleandeps_mistakes); - solv->cleandeps_mistakes = solv_free(solv->cleandeps_mistakes); - } - /* * ******************************************** * solve! diff --git a/test/testcases/cleandeps/cleandeps_dup.t b/test/testcases/cleandeps/cleandeps_dup.t new file mode 100644 index 0000000..7002434 --- /dev/null +++ b/test/testcases/cleandeps/cleandeps_dup.t @@ -0,0 +1,33 @@ +repo system 0 testtags <inline> +#>=Pkg: A 1 1 noarch +#>=Req: B1 +#>=Pkg: B1 1 1 noarch +repo test 0 testtags <inline> +#>=Pkg: A 1 2 noarch +#>=Req: B1 +#>=Pkg: A 2 1 noarch +#>=Req: B2 = 1 +#>=Pkg: B1 1 1 noarch +#>=Pkg: B2 1 1 noarch +system i686 rpm system + +# check untargeted +job distupgrade name A [cleandeps] +result transaction,problems <inline> +#>erase B1-1-1.noarch@system +#>install B2-1-1.noarch@test +#>upgrade A-1-1.noarch@system A-2-1.noarch@test + +# check targeted +nextjob +job distupgrade name A = 2 [cleandeps] +result transaction,problems <inline> +#>erase B1-1-1.noarch@system +#>install B2-1-1.noarch@test +#>upgrade A-1-1.noarch@system A-2-1.noarch@test + +# check targeted to 1-2 +nextjob +job distupgrade name A = 1-2 [cleandeps] +result transaction,problems <inline> +#>upgrade A-1-1.noarch@system A-1-2.noarch@test diff --git a/test/testcases/cleandeps/cleandeps_in.t b/test/testcases/cleandeps/cleandeps_in.t new file mode 100644 index 0000000..3edacb5 --- /dev/null +++ b/test/testcases/cleandeps/cleandeps_in.t @@ -0,0 +1,15 @@ +repo system 0 testtags <inline> +#>=Pkg: A 1 1 noarch +#>=Req: B1 +#>=Pkg: B1 1 1 noarch +repo test 0 testtags <inline> +#>=Pkg: A 2 1 noarch +#>=Req: B2 = 1 +#>=Pkg: B1 1 1 noarch +#>=Pkg: B2 1 1 noarch +system i686 rpm system +job install name A = 2 [cleandeps] +result transaction,problems <inline> +#>erase B1-1-1.noarch@system +#>install B2-1-1.noarch@test +#>upgrade A-1-1.noarch@system A-2-1.noarch@test diff --git a/test/testcases/cleandeps/cleandeps_up.t b/test/testcases/cleandeps/cleandeps_up.t new file mode 100644 index 0000000..9bb26d2 --- /dev/null +++ b/test/testcases/cleandeps/cleandeps_up.t @@ -0,0 +1,33 @@ +repo system 0 testtags <inline> +#>=Pkg: A 1 1 noarch +#>=Req: B1 +#>=Pkg: B1 1 1 noarch +repo test 0 testtags <inline> +#>=Pkg: A 1 2 noarch +#>=Req: B1 +#>=Pkg: A 2 1 noarch +#>=Req: B2 = 1 +#>=Pkg: B1 1 1 noarch +#>=Pkg: B2 1 1 noarch +system i686 rpm system + +# check untargeted +job update name A [cleandeps] +result transaction,problems <inline> +#>erase B1-1-1.noarch@system +#>install B2-1-1.noarch@test +#>upgrade A-1-1.noarch@system A-2-1.noarch@test + +# check targeted +nextjob +job update name A = 2 [cleandeps] +result transaction,problems <inline> +#>erase B1-1-1.noarch@system +#>install B2-1-1.noarch@test +#>upgrade A-1-1.noarch@system A-2-1.noarch@test + +# check targeted to 1-2 +nextjob +job update name A = 1-2 [cleandeps] +result transaction,problems <inline> +#>upgrade A-1-1.noarch@system A-1-2.noarch@test diff --git a/test/testcases/cleandeps/mistake-packages.repo b/test/testcases/cleandeps/mistake-packages.repo deleted file mode 100644 index 7dcc351..0000000 --- a/test/testcases/cleandeps/mistake-packages.repo +++ /dev/null @@ -1,3 +0,0 @@ -=Pkg: A 2 1 noarch -=Req: B = 1 -=Pkg: B 1 1 noarch diff --git a/test/testcases/cleandeps/mistake-system.repo b/test/testcases/cleandeps/mistake-system.repo deleted file mode 100644 index 4c2d012..0000000 --- a/test/testcases/cleandeps/mistake-system.repo +++ /dev/null @@ -1,3 +0,0 @@ -=Pkg: A 1 1 noarch -=Req: B -=Pkg: B 2 1 noarch diff --git a/test/testcases/cleandeps/mistake.t b/test/testcases/cleandeps/mistake.t index 44a29f0..b51ff69 100644 --- a/test/testcases/cleandeps/mistake.t +++ b/test/testcases/cleandeps/mistake.t @@ -1,9 +1,14 @@ -repo system 0 testtags mistake-system.repo -repo test 0 testtags mistake-packages.repo +repo system 0 testtags <inline> +#>=Pkg: A 1 1 noarch +#>=Req: B +#>=Pkg: B 2 1 noarch +repo test 0 testtags <inline> +#>=Pkg: A 2 1 noarch +#>=Req: B = 1 +#>=Pkg: B 1 1 noarch system i686 rpm system job install name A = 2 [cleandeps] result transaction,problems <inline> -#>erase A-1-1.noarch@system #>problem b5abcb9c info package A-2-1.noarch requires B = 1, but none of the providers can be installed #>problem b5abcb9c solution 37b448af deljob install name A = 2 [cleandeps] #>problem b5abcb9c solution 3c170283 replace B-2-1.noarch@system B-1-1.noarch@test |