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;
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);
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;
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)
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
***
***/
+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)
{
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);
}
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);
}
}
}
Id p, pp, ip, jp;
Id req, *reqp, sup, *supp;
Solvable *s;
- Queue iq;
+ Queue iq, iqcopy;
int i;
map_empty(cleandepsmap);
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)
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;
}
}
}
+ queue_init_clone(&iqcopy, &iq);
if (!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)
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
}
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)
{
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))
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);
}
}
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
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)
{
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))
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)
*/
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;
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:
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;
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!
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
+++ /dev/null
-=Pkg: A 2 1 noarch
-=Req: B = 1
-=Pkg: B 1 1 noarch
+++ /dev/null
-=Pkg: A 1 1 noarch
-=Req: B
-=Pkg: B 2 1 noarch
-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