pkgman install: Add problem solution selection support

This commit is contained in:
Ingo Weinhold
2013-04-21 02:48:52 +02:00
parent 8e6c3631a3
commit 2f028e9a2d
+68 -14
View File
@@ -233,24 +233,60 @@ InstallCommand::Execute(int argc, const char* const* argv)
int32 problemCount = solver->CountProblems();
for (int32 i = 0; i < problemCount; i++) {
// print problem and possible solutions
BSolverProblem* problem = solver->ProblemAt(i);
printf(" %" B_PRId32 ": %s\n", i + 1,
printf("problem %" B_PRId32 ": %s\n", i + 1,
problem->ToString().String());
int32 solutionCount = problem->CountSolutions();
for (int32 k = 0; k < solutionCount; k++) {
const BSolverProblemSolution* solution = problem->SolutionAt(k);
printf(" solution %" B_PRId32 ":\n", k + 1);
printf(" solution %" B_PRId32 ":\n", k + 1);
int32 elementCount = solution->CountElements();
for (int32 l = 0; l < elementCount; l++) {
const BSolverProblemSolutionElement* element
= solution->ElementAt(l);
printf(" - %s\n", element->ToString().String());
printf(" - %s\n", element->ToString().String());
}
}
// let the user choose a solution
printf("Please select a solution, skip the problem for now or "
"quit.\n");
for (;;) {
if (solutionCount > 1)
printf("select [1...%" B_PRId32 "/s/q]: ", solutionCount);
else
printf("select [1/s/q]: ");
char buffer[32];
if (fgets(buffer, sizeof(buffer), stdin) == NULL
|| strcmp(buffer, "q\n") == 0) {
exit(1);
}
if (strcmp(buffer, "s\n") == 0)
break;
char* end;
long selected = strtol(buffer, &end, 0);
if (end == buffer || *end != '\n' || selected < 1
|| selected > solutionCount) {
printf("*** invalid input\n");
continue;
}
error = solver->SelectProblemSolution(problem,
problem->SolutionAt(selected - 1));
if (error != B_OK)
DIE(error, "failed to set solution");
break;
}
}
// TODO: Allow the user to select solutions!
exit(1);
error = solver->SolveAgain();
if (error != B_OK)
DIE(error, "failed to compute packages to install");
}
// print result
@@ -259,27 +295,45 @@ exit(1);
if (error != B_OK)
DIE(error, "failed to compute packages to install");
printf("The following changes will be made:\n");
BObjectList<BSolverPackage> packagesToActivate;
BObjectList<BSolverPackage> packagesToDeactivate;
for (int32 i = 0; const BSolverResultElement* element = result.ElementAt(i);
i++) {
BSolverPackage* package = element->Package();
switch (element->Type()) {
case BSolverResultElement::B_TYPE_INSTALL:
if (installedRepositories.HasItem(package->Repository()))
continue;
printf(" install package %s from repository %s\n",
package->Info().CanonicalFileName().String(),
package->Repository()->Name().String());
if (!installedRepositories.HasItem(package->Repository())) {
if (!packagesToActivate.AddItem(package))
DIE(B_NO_MEMORY, "failed to add package to activate");
}
break;
case BSolverResultElement::B_TYPE_UNINSTALL:
printf(" uninstall package %s\n",
package->VersionedName().String());
if (!packagesToDeactivate.AddItem(package))
DIE(B_NO_MEMORY, "failed to add package to deactivate");
break;
}
}
if (packagesToActivate.IsEmpty() && packagesToDeactivate.IsEmpty()) {
printf("Nothing to do.\n");
exit(0);
}
printf("The following changes will be made:\n");
for (int32 i = 0; BSolverPackage* package = packagesToActivate.ItemAt(i);
i++) {
printf(" install package %s from repository %s\n",
package->Info().CanonicalFileName().String(),
package->Repository()->Name().String());
}
for (int32 i = 0; BSolverPackage* package = packagesToDeactivate.ItemAt(i);
i++) {
printf(" uninstall package %s\n", package->VersionedName().String());
}
// TODO: Print file/download sizes. Unfortunately our package infos don't
// contain the file size. Which is probably correct. The file size (and possibly
// other information) should, however, be provided by the repository cache in