summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindings/solv.i6
-rwxr-xr-xexamples/pysolv8
-rw-r--r--src/rules.c35
-rw-r--r--src/solver.c87
-rw-r--r--test/testcases/cleandeps/cleandeps_dup.t33
-rw-r--r--test/testcases/cleandeps/cleandeps_in.t15
-rw-r--r--test/testcases/cleandeps/cleandeps_up.t33
-rw-r--r--test/testcases/cleandeps/mistake-packages.repo3
-rw-r--r--test/testcases/cleandeps/mistake-system.repo3
-rw-r--r--test/testcases/cleandeps/mistake.t11
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