#include "solver.h"
#include "solverdebug.h"
#include "transaction.h"
+#include "testcase.h"
#ifdef SUSE
#include "repo_autopattern.h"
#endif
#include "fileconflicts.h"
#include "deltarpm.h"
#endif
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
#include "patchjobs.h"
#endif
int
-yesno(const char *str)
+yesno(const char *str, int other)
{
char inbuf[128], *ip;
printf("Abort.\n");
exit(1);
}
- if (*ip == 'y' || *ip == 'n')
- return *ip == 'y' ? 1 : 0;
+ if (*ip == 'y' || *ip == 'n' || *ip == other)
+ return *ip == 'n' ? 0 : *ip;
}
}
#ifdef SUSE
static void
-add_autopackages(Pool *pool)
-{
- int i;
- Repo *repo;
- FOR_REPOS(i, repo)
- repo_add_autopattern(repo, 0);
-}
-#endif
-
-#ifdef SUSE
-static void
showdiskusagechanges(Transaction *trans)
{
DUChanges duc[4];
fprintf(stderr, " search: search name/summary/description\n");
fprintf(stderr, " update: update installed packages\n");
fprintf(stderr, " verify: check dependencies of installed packages\n");
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
fprintf(stderr, " patch: install newest maintenance updates\n");
#endif
fprintf(stderr, "\n");
int forcebest = 0;
char *rootdir = 0;
char *keyname = 0;
+ int keyname_depstr = 0;
int debuglevel = 0;
+ int answer, acnt = 0;
+ char *testcase = 0;
argc--;
argv++;
mainmode = MODE_INSTALL;
mode = SOLVER_INSTALL;
}
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
else if (!strcmp(argv[0], "patch"))
{
mainmode = MODE_PATCH;
argc--;
argv++;
}
- if (argc > 2 && !strcmp(argv[1], "--keyname"))
+ else if (argc > 1 && !strcmp(argv[1], "--depstr"))
+ {
+ keyname_depstr = 1;
+ argc--;
+ argv++;
+ }
+ else if (argc > 2 && !strcmp(argv[1], "--keyname"))
{
keyname = argv[2];
argc -= 2;
argv += 2;
}
+ else if (argc > 2 && !strcmp(argv[1], "--testcase"))
+ {
+ testcase = argv[2];
+ argc -= 2;
+ argv += 2;
+ }
else
break;
}
commandlinepkgs[i] = p;
}
if (commandlinerepo)
- repo_internalize(commandlinerepo);
+ {
+ repo_internalize(commandlinerepo);
+#ifdef SUSE
+ repo_add_autopattern(commandlinerepo, 0);
+#endif
+ }
}
#if defined(ENABLE_RPMDB)
if (pool->disttype == DISTTYPE_RPM)
addfileprovides(pool);
#endif
-#ifdef SUSE
- add_autopackages(pool);
-#endif
pool_createwhatprovides(pool);
if (keyname)
flags |= SELECTION_WITH_SOURCE;
if (argv[i][0] == '/')
flags |= SELECTION_FILELIST | (mode == MODE_ERASE ? SELECTION_INSTALLED_ONLY : 0);
+ if (keyname && keyname_depstr)
+ flags |= SELECTION_MATCH_DEPSTR;
if (!keyname)
rflags = selection_make(pool, &job2, argv[i], flags);
else
exit(0);
}
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
if (mainmode == MODE_PATCH)
add_patchjobs(pool, &job);
#endif
queue_push2(&job, SOLVER_ERASE|SOLVER_CLEANDEPS|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
#endif
-#if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA))
rerunsolver:
-#endif
solv = solver_create(pool);
solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
#endif
if (mainmode == MODE_ERASE)
Id problem, solution;
int pcnt, scnt;
- if (!solver_solve(solv, &job))
+ pcnt = solver_solve(solv, &job);
+ if (testcase)
+ {
+ printf("Writing solver testcase:\n");
+ if (!testcase_write(solv, testcase, TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS, 0, 0))
+ printf("%s\n", pool_errstr(pool));
+ testcase = 0;
+ }
+ if (!pcnt)
break;
pcnt = solver_problem_count(solv);
printf("Found %d problems:\n", pcnt);
printf("install size change: %d K\n", transaction_calc_installsizechange(trans));
printf("\n");
- if (!yesno("OK to continue (y/n)? "))
+ acnt = solver_alternatives_count(solv);
+ if (acnt)
+ {
+ if (acnt == 1)
+ printf("Have one alternative:\n");
+ else
+ printf("Have %d alternatives:\n", acnt);
+ for (i = 1; i <= acnt; i++)
+ {
+ Id id, from;
+ int atype = solver_get_alternative(solv, i, &id, &from, 0, 0, 0);
+ printf(" - %s\n", solver_alternative2str(solv, atype, id, from));
+ }
+ printf("\n");
+ answer = yesno("OK to continue (y/n/a)? ", 'a');
+ }
+ else
+ answer = yesno("OK to continue (y/n)? ", 0);
+ if (answer == 'a')
+ {
+ Queue choicesq;
+ Queue answerq;
+ Id id, from, chosen;
+ int j;
+
+ queue_init(&choicesq);
+ queue_init(&answerq);
+ for (i = 1; i <= acnt; i++)
+ {
+ int atype = solver_get_alternative(solv, i, &id, &from, &chosen, &choicesq, 0);
+ printf("\n%s\n", solver_alternative2str(solv, atype, id, from));
+ for (j = 0; j < choicesq.count; j++)
+ {
+ Id p = choicesq.elements[j];
+ if (p < 0)
+ p = -p;
+ queue_push(&answerq, p);
+ printf("%6d: %s\n", answerq.count, pool_solvid2str(pool, p));
+ }
+ }
+ queue_free(&choicesq);
+ printf("\n");
+ for (;;)
+ {
+ char inbuf[128], *ip;
+ int neg = 0;
+ printf("OK to continue (y/n), or number to change alternative: ");
+ fflush(stdout);
+ *inbuf = 0;
+ if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
+ {
+ printf("Abort.\n");
+ exit(1);
+ }
+ while (*ip == ' ' || *ip == '\t')
+ ip++;
+ if (*ip == '-' && ip[1] >= '0' && ip[1] <= '9')
+ {
+ neg = 1;
+ ip++;
+ }
+ if (*ip >= '0' && *ip <= '9')
+ {
+ int take = atoi(ip);
+ if (take > 0 && take <= answerq.count)
+ {
+ Id p = answerq.elements[take - 1];
+ queue_free(&answerq);
+ queue_push2(&job, (neg ? SOLVER_DISFAVOR : SOLVER_FAVOR) | SOLVER_SOLVABLE_NAME, pool->solvables[p].name);
+ solver_free(solv);
+ solv = 0;
+ goto rerunsolver;
+ break;
+ }
+ }
+ if (*ip == 'n' || *ip == 'y')
+ {
+ answer = *ip == 'n' ? 0 : *ip;
+ break;
+ }
+ }
+ queue_free(&answerq);
+ }
+ if (!answer)
{
printf("Abort.\n");
transaction_free(trans);
queue_init(&conflicts);
if (checkfileconflicts(pool, &checkq, newpkgs, newpkgsfps, &conflicts))
{
- if (yesno("Re-run solver (y/n/q)? "))
+ if (yesno("Re-run solver (y/n/q)? ", 0))
{
for (i = 0; i < newpkgs; i++)
if (newpkgsfps[i])