12 #include "repo_solv.h"
13 #include "repo_susetags.h"
14 #include "repo_updateinfoxml.h"
15 #include "repo_rpmmd.h"
17 #include "solverdebug.h"
20 cookie_gzread(void *cookie, char *buf, size_t nbytes)
22 return gzread((gzFile *)cookie, buf, nbytes);
26 cookie_gzclose(void *cookie)
28 return gzclose((gzFile *)cookie);
32 myfopen(const char *fn)
34 cookie_io_functions_t cio;
40 suf = strrchr(fn, '.');
41 if (!suf || strcmp(suf, ".gz") != 0)
42 return fopen(fn, "r");
43 gzf = gzopen(fn, "r");
46 memset(&cio, 0, sizeof(cio));
47 cio.read = cookie_gzread;
48 cio.close = cookie_gzclose;
49 return fopencookie(gzf, "r", cio);
53 showproblems(Solver *solv, Solvable *s, Queue *cand, Queue *badguys)
55 Pool *pool = solv->pool;
63 printf("can't install %s:\n", solvable2str(pool, s));
64 while ((problem = solver_next_problem(solv, problem)) != 0)
66 solver_findallproblemrules(solv, problem, &rids);
67 for (jj = 0; jj < rids.count; jj++)
69 Id probr = rids.elements[jj];
73 solver_allruleinfos(solv, probr, &rinfo);
74 for (k = 0; k < rinfo.count; k += 4)
76 Id dep, source, target;
77 source = rinfo.elements[k + 1];
78 target = rinfo.elements[k + 2];
79 dep = rinfo.elements[k + 3];
80 switch (rinfo.elements[k])
82 case SOLVER_PROBLEM_DISTUPGRADE_RULE:
84 case SOLVER_PROBLEM_INFARCH_RULE:
85 printf(" %s has inferior architecture\n", solvid2str(pool, source));
87 case SOLVER_PROBLEM_UPDATE_RULE:
88 printf(" update rule for %s\n", solvid2str(pool, source));
90 queue_pushunique(badguys, source);
93 /* only drop update problem packages from cand so that we see all problems of this patch */
94 for (l = 0; l < cand->count; l++)
95 if (cand->elements[l] == source || cand->elements[l] == -source)
101 for (l = 0; l < cand->count; l++)
102 if (cand->elements[l] < 0)
103 cand->elements[l] = -cand->elements[l];
106 for (l = 0; l < cand->count; l++)
107 if (cand->elements[l] == source)
109 cand->elements[l] = -source;
112 case SOLVER_PROBLEM_JOB_RULE:
114 case SOLVER_PROBLEM_RPM_RULE:
115 printf(" some dependency problem\n");
117 case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP:
118 printf(" nothing provides requested %s\n", dep2str(pool, dep));
120 case SOLVER_PROBLEM_NOT_INSTALLABLE:
121 printf(" package %s is not installable\n", solvid2str(pool, source));
123 case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP:
124 printf(" nothing provides %s needed by %s\n", dep2str(pool, dep), solvid2str(pool, source));
127 Reldep *rd = GETRELDEP(pool, dep);
128 if (!ISRELDEP(rd->name))
131 FOR_PROVIDES(rp, rpp, rd->name)
132 printf(" (we have %s)\n", solvid2str(pool, rp));
136 case SOLVER_PROBLEM_SAME_NAME:
137 printf(" cannot install both %s and %s\n", solvid2str(pool, source), solvid2str(pool, target));
139 case SOLVER_PROBLEM_PACKAGE_CONFLICT:
140 printf(" package %s conflicts with %s provided by %s\n", solvid2str(pool, source), dep2str(pool, dep), solvid2str(pool, target));
142 case SOLVER_PROBLEM_PACKAGE_OBSOLETES:
143 printf(" package %s obsoletes %s provided by %s\n", solvid2str(pool, source), dep2str(pool, dep), solvid2str(pool, target));
145 case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE:
146 printf(" package %s requires %s, but none of the providers can be installed\n", solvid2str(pool, source), dep2str(pool, dep));
148 case SOLVER_PROBLEM_SELF_CONFLICT:
149 printf(" package %s conflicts with %s provided by itself\n", solvid2str(pool, source), dep2str(pool, dep));
160 toinst(Solver *solv, Repo *repo, Repo *instrepo)
162 Pool *pool = solv->pool;
166 for (k = 0; k < solv->decisionq.count; k++)
168 p = solv->decisionq.elements[k];
169 if (p < 0 || p == SYSTEMSOLVABLE)
172 pool->solvables[p].repo = instrepo;
177 frominst(Solver *solv, Repo *repo, Repo *instrepo)
179 Pool *pool = solv->pool;
182 for (k = 1; k < pool->nsolvables; k++)
183 if (pool->solvables[k].repo == instrepo)
184 pool->solvables[k].repo = repo;
188 main(int argc, char **argv)
191 char *arch, *mypatch;
202 Repo *repo, *instrepo;
208 pool = pool_create();
209 pool_setarch(pool, arch);
212 repo = repo_create(pool, 0);
213 instrepo = repo_create(pool, 0);
214 for (i = 3; i < argc; i++)
216 if (!strcmp(argv[i], "--updaterepos"))
218 updatestart = pool->nsolvables;
222 if (!strcmp(argv[i], "-"))
224 else if ((fp = myfopen(argv[i])) == 0)
229 if (l >= 8 && !strcmp(argv[i] + l - 8, "packages"))
231 repo_add_susetags(repo, fp, 0, 0, 0);
233 else if (l >= 11 && !strcmp(argv[i] + l - 11, "packages.gz"))
235 repo_add_susetags(repo, fp, 0, 0, 0);
237 else if (l >= 14 && !strcmp(argv[i] + l - 14, "primary.xml.gz"))
239 repo_add_rpmmd(repo, fp, 0, 0);
241 else if (l >= 17 && !strcmp(argv[i] + l - 17, "updateinfo.xml.gz"))
243 repo_add_updateinfoxml(repo, fp, 0);
245 else if (repo_add_solv(repo, fp))
247 fprintf(stderr, "could not add repo %s\n", argv[i]);
254 /* bad hack ahead: clone repo */
255 instrepo->idarraydata = repo->idarraydata;
256 instrepo->start = repo->start;
257 instrepo->end = repo->end;
258 instrepo->nsolvables = repo->nsolvables; /* sic! */
259 pool_set_installed(pool, instrepo);
261 pool_addfileprovides(pool);
262 pool_createwhatprovides(pool);
266 queue_init(&badguys);
269 pool_setdebuglevel(pool, 2);
272 for (pid = 1; pid < pool->nsolvables; pid++)
274 Solvable *s = pool->solvables + pid;
277 if (!pool_installable(pool, s))
279 pname = id2str(pool, s->name);
280 if (strncmp(pname, "patch:", 6) != 0)
284 if (strncmp(mypatch, pname + 6, strlen(pname + 6)) != 0)
286 if (strcmp(mypatch, pname + 6) != 0)
288 l = strlen(pname + 6);
289 if (mypatch[l] != '-')
291 if (strcmp(mypatch + l + 1, id2str(pool, s->evr)) != 0)
297 FOR_PROVIDES(p, pp, s->name)
299 Solvable *s2 = pool->solvables + p;
300 if (evrcmp(pool, s->evr, s2->evr, EVRCMP_COMPARE) < 0)
304 continue; /* found a newer one */
311 printf("testing patch %s-%s\n", pname + 6, id2str(pool, s->evr));
314 /* Test 1: are all old patches included */
315 FOR_PROVIDES(p, pp, s->name)
317 Solvable *s2 = pool->solvables + p;
321 if (evrcmp(pool, s->evr, s2->evr, EVRCMP_COMPARE) <= 0)
325 conp2 = s2->repo->idarraydata + s2->conflicts;
326 while ((con2 = *conp2++) != 0)
331 rd2 = GETRELDEP(pool, con2);
332 conp = s->repo->idarraydata + s->conflicts;
333 while ((con = *conp++) != 0)
338 rd = GETRELDEP(pool, con);
339 if (rd->name == rd2->name)
345 printf("%s:\n", solvable2str(pool, s));
346 printf(" %s contained %s\n", solvable2str(pool, s2), dep2str(pool, rd2->name));
351 /* Test 2: are the packages installable */
352 conp = s->repo->idarraydata + s->conflicts;
353 while ((con = *conp++) != 0)
355 FOR_PROVIDES(p, pp, con)
358 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_WEAK);
361 /* also set up some minimal system */
362 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES|SOLVER_WEAK);
363 queue_push(&job, str2id(pool, "rpm", 1));
364 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES|SOLVER_WEAK);
365 queue_push(&job, str2id(pool, "aaa_base", 1));
367 solv = solver_create(pool);
368 solv->dontinstallrecommended = 1;
369 solv = solver_create(pool);
370 solver_solve(solv, &job);
371 toinst(solv, repo, instrepo);
374 for (i = 1; i < updatestart; i++)
376 if (pool->solvables[i].repo != repo || i == pid)
378 queue_push(&job, SOLVER_ERASE|SOLVER_SOLVABLE);
381 queue_push(&job, SOLVER_INSTALL_SOLVABLE);
382 queue_push(&job, pid);
383 solv = solver_create(pool);
384 solv->dontinstallrecommended = 1;
385 solver_solve(solv, &job);
386 if (solv->problems.count)
389 showproblems(solv, s, 0, 0);
391 frominst(solv, repo, instrepo);
399 /* Test 3: can we upgrade all packages? */
401 queue_empty(&badguys);
402 for (p = 1; p < pool->nsolvables; p++)
404 Solvable *s = pool->solvables + p;
407 if (strchr(id2str(pool, s->name), ':'))
408 continue; /* only packages, please */
409 if (!pool_installable(pool, s))
411 queue_push(&cand, p);
415 solv = solver_create(pool);
416 solv->dontinstallrecommended = 1;
417 solv = solver_create(pool);
419 for (i = 0; i < badguys.count; i++)
421 queue_push(&job, SOLVER_ERASE|SOLVER_SOLVABLE|SOLVER_WEAK);
422 queue_push(&job, badguys.elements[i]);
424 conp = s->repo->idarraydata + s->conflicts;
425 while ((con = *conp++) != 0)
427 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES|SOLVER_WEAK);
428 queue_push(&job, con);
430 for (i = 0; i < cand.count; i++)
432 p = cand.elements[i];
433 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_WEAK);
436 solver_solve(solv, &job);
438 solver_printdecisions(solv);
440 /* put packages into installed repo and prune them from cand */
441 toinst(solv, repo, instrepo);
442 for (i = 0; i < cand.count; i++)
444 p = cand.elements[i];
445 if (p > 0 && solv->decisionmap[p] > 0)
446 cand.elements[i] = -p; /* drop candidate */
450 /* now the interesting part: test patch */
453 for (i = 1; i < updatestart; i++)
455 if (pool->solvables[i].repo != repo || i == pid)
457 queue_push(&job, SOLVER_ERASE|SOLVER_SOLVABLE);
461 queue_push(&job, SOLVER_INSTALL_SOLVABLE);
462 queue_push(&job, pid);
463 solv = solver_create(pool);
464 solv->dontinstallrecommended = 1;
465 solver_solve(solv, &job);
467 if (solv->problems.count)
470 showproblems(solv, s, &cand, &badguys);
472 frominst(solv, repo, instrepo);
474 /* now drop all negative elements from cand */
475 for (i = j = 0; i < cand.count; i++)
477 if (cand.elements[i] < 0)
479 cand.elements[j++] = cand.elements[i];
482 break; /* no progress */