From a54a50b48e316421f2735e9c46219164e16dd8cd Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 28 Aug 2013 15:27:09 +0200 Subject: [PATCH] pkgman: add support for [un]installing/updating in system --- src/bin/pkgman/PackageManager.cpp | 57 +++++++++++++++------------- src/bin/pkgman/PackageManager.h | 17 ++++++++- src/bin/pkgman/command_install.cpp | 18 ++++++--- src/bin/pkgman/command_uninstall.cpp | 18 ++++++--- src/bin/pkgman/command_update.cpp | 18 ++++++--- 5 files changed, 83 insertions(+), 45 deletions(-) diff --git a/src/bin/pkgman/PackageManager.cpp b/src/bin/pkgman/PackageManager.cpp index 584a7ac8e3..d7b618403f 100644 --- a/src/bin/pkgman/PackageManager.cpp +++ b/src/bin/pkgman/PackageManager.cpp @@ -76,10 +76,14 @@ PackageManager::RemoteRepository::Config() const // #pragma mark - InstalledRepository -PackageManager::InstalledRepository::InstalledRepository() +PackageManager::InstalledRepository::InstalledRepository(const char* name, + BPackageInstallationLocation location, int32 priority) : BSolverRepository(), - fDisabledPackages(10, true) + fDisabledPackages(10, true), + fInitialName(name), + fLocation(location), + fInitialPriority(priority) { } @@ -115,9 +119,12 @@ PackageManager::PackageManager(BPackageInstallationLocation location, : fLocation(location), fSolver(NULL), - fSystemRepository(new (std::nothrow) InstalledRepository), - fCommonRepository(new (std::nothrow) InstalledRepository), - fHomeRepository(new (std::nothrow) InstalledRepository), + fSystemRepository(new (std::nothrow) InstalledRepository("system", + B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, -1)), + fCommonRepository(new (std::nothrow) InstalledRepository("common", + B_PACKAGE_INSTALLATION_LOCATION_COMMON, -2)), + fHomeRepository(new (std::nothrow) InstalledRepository("home", + B_PACKAGE_INSTALLATION_LOCATION_HOME, -3)), fInstalledRepositories(10), fOtherRepositories(10, true), fDecisionProvider(), @@ -145,29 +152,13 @@ PackageManager::PackageManager(BPackageInstallationLocation location, // one. Instead any requirement that is already installed in a more // general installation location will turn up as to be installed as // well. But we can easily filter those out. - RepositoryBuilder(*fSystemRepository, "system") - .AddPackages(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, "system") - .AddToSolver(fSolver, false); - fSystemRepository->SetPriority(-1); + _AddInstalledRepository(fSystemRepository); - bool installInHome = location == B_PACKAGE_INSTALLATION_LOCATION_HOME; - RepositoryBuilder(*fCommonRepository, "common") - .AddPackages(B_PACKAGE_INSTALLATION_LOCATION_COMMON, "common") - .AddToSolver(fSolver, !installInHome); + if (!fSystemRepository->IsInstalled()) { + _AddInstalledRepository(fCommonRepository); - if (!fInstalledRepositories.AddItem(fSystemRepository) - || !fInstalledRepositories.AddItem(fCommonRepository)) { - DIE(B_NO_MEMORY, "failed to add installed repositories to list"); - } - - if (installInHome) { - fCommonRepository->SetPriority(-2); - RepositoryBuilder(*fHomeRepository, "home") - .AddPackages(B_PACKAGE_INSTALLATION_LOCATION_HOME, "home") - .AddToSolver(fSolver, true); - - if (!fInstalledRepositories.AddItem(fHomeRepository)) - DIE(B_NO_MEMORY, "failed to add home repository to list"); + if (!fCommonRepository->IsInstalled()) + _AddInstalledRepository(fHomeRepository); } } @@ -640,3 +631,17 @@ PackageManager::_FindBasePackage(const PackageList& packages, return -1; } + + +void +PackageManager::_AddInstalledRepository(InstalledRepository* repository) +{ + const char* name = repository->InitialName(); + RepositoryBuilder(*repository, name) + .AddPackages(repository->Location(), name) + .AddToSolver(fSolver, repository->Location() == fLocation); + repository->SetPriority(repository->InitialPriority()); + + if (!fInstalledRepositories.AddItem(repository)) + DIE(B_NO_MEMORY, "failed to add %s repository to list", name); +} diff --git a/src/bin/pkgman/PackageManager.h b/src/bin/pkgman/PackageManager.h index 54013fef1f..07883016f9 100644 --- a/src/bin/pkgman/PackageManager.h +++ b/src/bin/pkgman/PackageManager.h @@ -80,6 +80,9 @@ private: int32 _FindBasePackage(const PackageList& packages, const BPackageInfo& info) const; + void _AddInstalledRepository( + InstalledRepository* repository); + private: BPackageInstallationLocation fLocation; BSolver* fSolver; @@ -110,7 +113,16 @@ private: struct PackageManager::InstalledRepository : public BSolverRepository { - InstalledRepository(); + InstalledRepository(const char* name, + BPackageInstallationLocation location, + int32 priority); + + BPackageInstallationLocation Location() const + { return fLocation; } + const char* InitialName() const + { return fInitialName; } + int32 InitialPriority() const + { return fInitialPriority; } void DisablePackage(BSolverPackage* package); @@ -119,6 +131,9 @@ private: private: PackageList fDisabledPackages; + const char* fInitialName; + BPackageInstallationLocation fLocation; + int32 fInitialPriority; }; diff --git a/src/bin/pkgman/command_install.cpp b/src/bin/pkgman/command_install.cpp index 2600b39d05..7fa380296e 100644 --- a/src/bin/pkgman/command_install.cpp +++ b/src/bin/pkgman/command_install.cpp @@ -35,6 +35,9 @@ static const char* const kLongUsage = " -H, --home\n" " Install the packages in the user's home directory. Default is to\n" " install in the common directory.\n" + " -S, --system\n" + " Install the packages in the system directory. Default is to\n" + " install in the common directory.\n" "\n"; @@ -45,17 +48,19 @@ DEFINE_COMMAND(InstallCommand, "install", kShortUsage, kLongUsage, int InstallCommand::Execute(int argc, const char* const* argv) { - bool installInHome = false; + BPackageInstallationLocation location + = B_PACKAGE_INSTALLATION_LOCATION_COMMON; while (true) { static struct option sLongOptions[] = { { "help", no_argument, 0, 'h' }, { "home", no_argument, 0, 'H' }, + { "system", no_argument, 0, 'S' }, { 0, 0, 0, 0 } }; opterr = 0; // don't print errors - int c = getopt_long(argc, (char**)argv, "hH", sLongOptions, NULL); + int c = getopt_long(argc, (char**)argv, "hHS", sLongOptions, NULL); if (c == -1) break; @@ -65,7 +70,11 @@ InstallCommand::Execute(int argc, const char* const* argv) break; case 'H': - installInHome = true; + location = B_PACKAGE_INSTALLATION_LOCATION_HOME; + break; + + case 'S': + location = B_PACKAGE_INSTALLATION_LOCATION_SYSTEM; break; default: @@ -82,9 +91,6 @@ InstallCommand::Execute(int argc, const char* const* argv) const char* const* packages = argv + optind; // perform the installation - BPackageInstallationLocation location = installInHome - ? B_PACKAGE_INSTALLATION_LOCATION_HOME - : B_PACKAGE_INSTALLATION_LOCATION_COMMON; PackageManager packageManager(location, PackageManager::ADD_INSTALLED_REPOSITORIES | PackageManager::ADD_REMOTE_REPOSITORIES diff --git a/src/bin/pkgman/command_uninstall.cpp b/src/bin/pkgman/command_uninstall.cpp index f4a7baf004..8bbf4e4b1d 100644 --- a/src/bin/pkgman/command_uninstall.cpp +++ b/src/bin/pkgman/command_uninstall.cpp @@ -35,6 +35,9 @@ static const char* const kLongUsage = " -H, --home\n" " Uninstall the packages from the user's home directory. Default is to\n" " uninstall from the common directory.\n" + " -S, --system\n" + " Uninstall the packages from the system directory. Default is to\n" + " uninstall from the common directory.\n" "\n"; @@ -45,17 +48,19 @@ DEFINE_COMMAND(UninstallCommand, "uninstall", kShortUsage, kLongUsage, int UninstallCommand::Execute(int argc, const char* const* argv) { - bool uninstallFromHome = false; + BPackageInstallationLocation location + = B_PACKAGE_INSTALLATION_LOCATION_COMMON; while (true) { static struct option sLongOptions[] = { { "help", no_argument, 0, 'h' }, { "home", no_argument, 0, 'H' }, + { "system", no_argument, 0, 'S' }, { 0, 0, 0, 0 } }; opterr = 0; // don't print errors - int c = getopt_long(argc, (char**)argv, "hH", sLongOptions, NULL); + int c = getopt_long(argc, (char**)argv, "hHS", sLongOptions, NULL); if (c == -1) break; @@ -65,7 +70,11 @@ UninstallCommand::Execute(int argc, const char* const* argv) break; case 'H': - uninstallFromHome = true; + location = B_PACKAGE_INSTALLATION_LOCATION_HOME; + break; + + case 'S': + location = B_PACKAGE_INSTALLATION_LOCATION_SYSTEM; break; default: @@ -82,9 +91,6 @@ UninstallCommand::Execute(int argc, const char* const* argv) const char* const* packages = argv + optind; // perform the installation - BPackageInstallationLocation location = uninstallFromHome - ? B_PACKAGE_INSTALLATION_LOCATION_HOME - : B_PACKAGE_INSTALLATION_LOCATION_COMMON; PackageManager packageManager(location, PackageManager::ADD_INSTALLED_REPOSITORIES); packageManager.Uninstall(packages, packageCount); diff --git a/src/bin/pkgman/command_update.cpp b/src/bin/pkgman/command_update.cpp index 8a8fe01c6b..7f0aacae8b 100644 --- a/src/bin/pkgman/command_update.cpp +++ b/src/bin/pkgman/command_update.cpp @@ -36,6 +36,9 @@ static const char* const kLongUsage = " -H, --home\n" " Update the packages in the user's home directory. Default is to\n" " update in the common directory.\n" + " -S, --system\n" + " Update the packages in the system directory. Default is to\n" + " update in the common directory.\n" "\n"; @@ -46,17 +49,19 @@ DEFINE_COMMAND(UpdateCommand, "update", kShortUsage, kLongUsage, int UpdateCommand::Execute(int argc, const char* const* argv) { - bool installInHome = false; + BPackageInstallationLocation location + = B_PACKAGE_INSTALLATION_LOCATION_COMMON; while (true) { static struct option sLongOptions[] = { { "help", no_argument, 0, 'h' }, { "home", no_argument, 0, 'H' }, + { "system", no_argument, 0, 'S' }, { 0, 0, 0, 0 } }; opterr = 0; // don't print errors - int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, NULL); + int c = getopt_long(argc, (char**)argv, "hHS", sLongOptions, NULL); if (c == -1) break; @@ -66,7 +71,11 @@ UpdateCommand::Execute(int argc, const char* const* argv) break; case 'H': - installInHome = true; + location = B_PACKAGE_INSTALLATION_LOCATION_HOME; + break; + + case 'S': + location = B_PACKAGE_INSTALLATION_LOCATION_SYSTEM; break; default: @@ -80,9 +89,6 @@ UpdateCommand::Execute(int argc, const char* const* argv) 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, PackageManager::ADD_INSTALLED_REPOSITORIES | PackageManager::ADD_REMOTE_REPOSITORIES