From a5999f6ff7fbadb4f8cc94f5e4283dacbf231a59 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 21 Apr 2013 13:56:21 +0200 Subject: [PATCH] pkgman: Add "update" command --- src/bin/pkgman/Jamfile | 1 + src/bin/pkgman/PackageManager.cpp | 30 +++++++++++ src/bin/pkgman/PackageManager.h | 2 + src/bin/pkgman/command_update.cpp | 90 +++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 src/bin/pkgman/command_update.cpp diff --git a/src/bin/pkgman/Jamfile b/src/bin/pkgman/Jamfile index de3d08c07e..e57ee9a370 100644 --- a/src/bin/pkgman/Jamfile +++ b/src/bin/pkgman/Jamfile @@ -8,6 +8,7 @@ BinCommand pkgman : command_drop_repo.cpp command_install.cpp command_list_repos.cpp + command_update.cpp command_refresh.cpp command_resolve_dependencies.cpp command_search.cpp diff --git a/src/bin/pkgman/PackageManager.cpp b/src/bin/pkgman/PackageManager.cpp index f587451f32..833d6ce56d 100644 --- a/src/bin/pkgman/PackageManager.cpp +++ b/src/bin/pkgman/PackageManager.cpp @@ -223,6 +223,36 @@ PackageManager::Uninstall(const char* const* packages, int packageCount) } +void +PackageManager::Update(const char* const* packages, int packageCount) +{ + // solve + BSolverPackageSpecifierList packagesToUpdate; + for (int i = 0; i < packageCount; i++) { + if (!packagesToUpdate.AppendSpecifier(packages[i])) + DIE(B_NO_MEMORY, "failed to add specified package"); + } + + const BSolverPackageSpecifier* unmatchedSpecifier; + status_t error = fSolver->Update(packagesToUpdate, true, + &unmatchedSpecifier); + if (error != B_OK) { + if (unmatchedSpecifier != NULL) { + DIE(error, "failed to find a match for \"%s\"", + unmatchedSpecifier->SelectString().String()); + } else + DIE(error, "failed to compute packages to update"); + } + + _HandleProblems(); + + // install/uninstall packages + _AnalyzeResult(); + _PrintResult(); + _ApplyPackageChanges(); +} + + void PackageManager::_HandleProblems() { diff --git a/src/bin/pkgman/PackageManager.h b/src/bin/pkgman/PackageManager.h index ca9b3a0c7e..c212fb314b 100644 --- a/src/bin/pkgman/PackageManager.h +++ b/src/bin/pkgman/PackageManager.h @@ -54,6 +54,8 @@ public: int packageCount); void Uninstall(const char* const* packages, int packageCount); + void Update(const char* const* packages, + int packageCount); private: typedef BObjectList PackageList; diff --git a/src/bin/pkgman/command_update.cpp b/src/bin/pkgman/command_update.cpp new file mode 100644 index 0000000000..91d6a5b04a --- /dev/null +++ b/src/bin/pkgman/command_update.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2013, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ingo Weinhold + */ + + +#include +#include +#include + +#include "Command.h" +#include "pkgman.h" +#include "PackageManager.h" + + +// TODO: internationalization! + + +using namespace BPackageKit; +using namespace BPackageKit::BPrivate; + + +static const char* const kShortUsage = + " %command% [ ... ]\n" + " Updates the specified or all packages.\n"; + +static const char* const kLongUsage = + "Usage: %program% %command% [ ... ]\n" + "Updates the specified packages. If no packages are given, all packages\n" + "in the installation location are updated.\n" + "\n" + "Options:\n" + " -H, --home\n" + " Update the packages in the user's home directory. Default is to\n" + " update in the common directory.\n" + "\n"; + + +DEFINE_COMMAND(UpdateCommand, "update", kShortUsage, kLongUsage, + kCommandCategoryPackages) + + +int +UpdateCommand::Execute(int argc, const char* const* argv) +{ + bool installInHome = false; + + while (true) { + static struct option sLongOptions[] = { + { "help", no_argument, 0, 'h' }, + { "home", no_argument, 0, 'H' }, + { 0, 0, 0, 0 } + }; + + opterr = 0; // don't print errors + int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, NULL); + if (c == -1) + break; + + switch (c) { + case 'h': + PrintUsageAndExit(false); + break; + + case 'H': + installInHome = true; + break; + + default: + PrintUsageAndExit(true); + break; + } + } + + // The remaining arguments, if any, are the packages to be installed. + int packageCount = argc - optind; + const char* const* packages = argv + optind; + + // perform the update + BPackageInstallationLocation location = installInHome + ? B_PACKAGE_INSTALLATION_LOCATION_HOME + : B_PACKAGE_INSTALLATION_LOCATION_COMMON; + PackageManager packageManager(location, true, true); + packageManager.Update(packages, packageCount); + + return 0; +}