HaikuDepot: Clean up some aspects of package handling.

- A package can potentially be installed in more than one location. As
  such, track all of them on PackageInfo (not yet exposed/used).

- Rather than attempting to use location, check the package's flags to
  see if it's a system package. If so, disallow deinstallation. Not quite
  complete yet though, as we still needs to also resolve the deps of any
  system package, and likewise disallow removal of those.
This commit is contained in:
Rene Gollent 2013-10-06 18:11:39 -04:00
parent 09729f54ff
commit fe18453425
4 changed files with 72 additions and 52 deletions

View File

@ -55,7 +55,6 @@ using BManager::BPrivate::BFatalErrorException;
typedef std::map<BString, PackageInfoRef> PackageInfoMap; typedef std::map<BString, PackageInfoRef> PackageInfoMap;
typedef std::map<BString, BObjectList<PackageInfo> > PackageLocationMap;
typedef std::map<BString, DepotInfo> DepotInfoMap; typedef std::map<BString, DepotInfo> DepotInfoMap;
@ -414,7 +413,6 @@ MainWindow::_RefreshPackageList()
if (packages.IsEmpty()) if (packages.IsEmpty())
return; return;
PackageLocationMap packageLocations;
PackageInfoMap foundPackages; PackageInfoMap foundPackages;
// if a given package is installed locally, we will potentially // if a given package is installed locally, we will potentially
// get back multiple entries, one for each local installation // get back multiple entries, one for each local installation
@ -422,8 +420,16 @@ MainWindow::_RefreshPackageList()
// is available in. The above map is used to ensure that in such // is available in. The above map is used to ensure that in such
// cases we consolidate the information, rather than displaying // cases we consolidate the information, rather than displaying
// duplicates // duplicates
PackageInfoMap remotePackages; PackageInfoMap remotePackages;
// any package that we find in a remote repository goes in this map.
// this is later used to discern which packages came from a local
// installation only, as those must be handled a bit differently
// upon uninstallation, since we'd no longer be able to pull them
// down remotely.
PackageInfoMap systemPackages;
// any packages flagged as a system package are added to this map.
// such packages cannot be uninstalled, nor can any of their deps.
for (int32 i = 0; i < packages.CountItems(); i++) { for (int32 i = 0; i < packages.CountItems(); i++) {
BSolverPackage* package = packages.ItemAt(i); BSolverPackage* package = packages.ItemAt(i);
const BPackageInfo& repoPackageInfo = package->Info(); const BPackageInfo& repoPackageInfo = package->Info();
@ -445,7 +451,8 @@ MainWindow::_RefreshPackageList()
repoPackageInfo.Version().ToString(), repoPackageInfo.Version().ToString(),
PublisherInfo(BitmapRef(), publisherName, PublisherInfo(BitmapRef(), publisherName,
"", publisherURL), repoPackageInfo.Summary(), "", publisherURL), repoPackageInfo.Summary(),
repoPackageInfo.Description(), ""), repoPackageInfo.Description(), "",
repoPackageInfo.Flags()),
true); true);
if (modelInfo.Get() == NULL) if (modelInfo.Get() == NULL)
@ -462,20 +469,19 @@ MainWindow::_RefreshPackageList()
depots[repository->Name()].AddPackage(modelInfo); depots[repository->Name()].AddPackage(modelInfo);
remotePackages[modelInfo->Title()] = modelInfo; remotePackages[modelInfo->Title()] = modelInfo;
} else { } else {
const char* installationLocation = NULL;
if (repository == static_cast<const BSolverRepository*>( if (repository == static_cast<const BSolverRepository*>(
manager.SystemRepository())) { manager.SystemRepository())) {
installationLocation = "system"; modelInfo->AddInstallationLocation(
B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
} else if (repository == static_cast<const BSolverRepository*>( } else if (repository == static_cast<const BSolverRepository*>(
manager.HomeRepository())) { manager.HomeRepository())) {
installationLocation = "home"; modelInfo->AddInstallationLocation(
} B_PACKAGE_INSTALLATION_LOCATION_HOME);
if (installationLocation != NULL) {
packageLocations[installationLocation].AddItem(
modelInfo.Get());
} }
} }
if (modelInfo->IsSystemPackage())
systemPackages[modelInfo->Title()] = modelInfo;
} }
BAutolock lock(fModel.Lock()); BAutolock lock(fModel.Lock());
@ -505,14 +511,11 @@ MainWindow::_RefreshPackageList()
fModel.AddDepot(it->second); fModel.AddDepot(it->second);
} }
for (PackageLocationMap::iterator it = packageLocations.begin(); for (PackageInfoMap::iterator it = systemPackages.begin();
it != packageLocations.end(); ++it) { it != systemPackages.end(); ++it) {
for (int32 i = 0; i < it->second.CountItems(); i++) { // TODO: need to resolve deps on all of these and correspondingly
fModel.SetPackageState(it->second.ItemAt(i), ACTIVATED); // mark all of those as system packages as well, so we know
// TODO: indicate the specific installation location // not to show uninstallation as an option.
// and verify that the package is in fact activated
// by querying the package roster
}
} }
} }

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2013, Stephan Aßmus <superstippi@gmx.de>. * Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2013, Rene Gollent <rene@gollent.com>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
@ -12,6 +13,7 @@
#include <DataIO.h> #include <DataIO.h>
#include <IconUtils.h> #include <IconUtils.h>
#include <MimeType.h> #include <MimeType.h>
#include <package/PackageFlags.h>
#include <Resources.h> #include <Resources.h>
#include "support.h" #include "support.h"
@ -447,7 +449,8 @@ PackageInfo::PackageInfo()
fUserRatings(), fUserRatings(),
fScreenshots(), fScreenshots(),
fState(NONE), fState(NONE),
fDownloadProgress(0.0) fDownloadProgress(0.0),
fFlags(0)
{ {
} }
@ -455,7 +458,7 @@ PackageInfo::PackageInfo()
PackageInfo::PackageInfo(const BitmapRef& icon, const BString& title, PackageInfo::PackageInfo(const BitmapRef& icon, const BString& title,
const BString& version, const PublisherInfo& publisher, const BString& version, const PublisherInfo& publisher,
const BString& shortDescription, const BString& fullDescription, const BString& shortDescription, const BString& fullDescription,
const BString& changelog) const BString& changelog, int32 flags)
: :
fIcon(icon), fIcon(icon),
fTitle(title), fTitle(title),
@ -468,7 +471,8 @@ PackageInfo::PackageInfo(const BitmapRef& icon, const BString& title,
fUserRatings(), fUserRatings(),
fScreenshots(), fScreenshots(),
fState(NONE), fState(NONE),
fDownloadProgress(0.0) fDownloadProgress(0.0),
fFlags(flags)
{ {
} }
@ -486,7 +490,9 @@ PackageInfo::PackageInfo(const PackageInfo& other)
fUserRatings(other.fUserRatings), fUserRatings(other.fUserRatings),
fScreenshots(other.fScreenshots), fScreenshots(other.fScreenshots),
fState(other.fState), fState(other.fState),
fDownloadProgress(other.fDownloadProgress) fInstallationLocations(other.fInstallationLocations),
fDownloadProgress(other.fDownloadProgress),
fFlags(other.fFlags)
{ {
} }
@ -505,7 +511,9 @@ PackageInfo::operator=(const PackageInfo& other)
fUserRatings = other.fUserRatings; fUserRatings = other.fUserRatings;
fScreenshots = other.fScreenshots; fScreenshots = other.fScreenshots;
fState = other.fState; fState = other.fState;
fInstallationLocations = other.fInstallationLocations;
fDownloadProgress = other.fDownloadProgress; fDownloadProgress = other.fDownloadProgress;
fFlags = other.fFlags;
return *this; return *this;
} }
@ -524,6 +532,7 @@ PackageInfo::operator==(const PackageInfo& other) const
&& fUserRatings == other.fUserRatings && fUserRatings == other.fUserRatings
&& fScreenshots == other.fScreenshots && fScreenshots == other.fScreenshots
&& fState == other.fState && fState == other.fState
&& fFlags == other.fFlags
&& fDownloadProgress == other.fDownloadProgress; && fDownloadProgress == other.fDownloadProgress;
} }
@ -535,6 +544,13 @@ PackageInfo::operator!=(const PackageInfo& other) const
} }
bool
PackageInfo::IsSystemPackage() const
{
return (fFlags & BPackageKit::B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0;
}
bool bool
PackageInfo::AddCategory(const CategoryRef& category) PackageInfo::AddCategory(const CategoryRef& category)
{ {
@ -554,10 +570,12 @@ PackageInfo::SetState(PackageState state)
} }
float void
PackageInfo::DownloadProgress() const PackageInfo::AddInstallationLocation(int32 location)
{ {
return fDownloadProgress; fInstallationLocations.insert(location);
SetState(ACTIVATED);
// TODO: determine how to differentiate between installed and active.
} }

View File

@ -6,6 +6,8 @@
#define PACKAGE_INFO_H #define PACKAGE_INFO_H
#include <set>
#include <Referenceable.h> #include <Referenceable.h>
#include <String.h> #include <String.h>
@ -183,7 +185,7 @@ typedef List<CategoryRef, false> CategoryList;
typedef List<PackageInfoListenerRef, false, 2> PackageListenerList; typedef List<PackageInfoListenerRef, false, 2> PackageListenerList;
typedef std::set<int32> PackageInstallationLocationSet;
enum PackageState { enum PackageState {
NONE = 0, NONE = 0,
@ -203,7 +205,8 @@ public:
const PublisherInfo& publisher, const PublisherInfo& publisher,
const BString& shortDescription, const BString& shortDescription,
const BString& fullDescription, const BString& fullDescription,
const BString& changelog); const BString& changelog,
int32 packageFlags);
PackageInfo(const PackageInfo& other); PackageInfo(const PackageInfo& other);
PackageInfo& operator=(const PackageInfo& other); PackageInfo& operator=(const PackageInfo& other);
@ -225,11 +228,21 @@ public:
const BString& Changelog() const const BString& Changelog() const
{ return fChangelog; } { return fChangelog; }
int32 Flags() const
{ return fFlags; }
bool IsSystemPackage() const;
PackageState State() const PackageState State() const
{ return fState; } { return fState; }
void SetState(PackageState state); void SetState(PackageState state);
float DownloadProgress() const; const PackageInstallationLocationSet&
InstallationLocations() const
{ return fInstallationLocations; }
void AddInstallationLocation(int32 location);
float DownloadProgress() const
{ return fDownloadProgress; }
void SetDownloadProgress(float progress); void SetDownloadProgress(float progress);
bool AddCategory(const CategoryRef& category); bool AddCategory(const CategoryRef& category);
@ -265,8 +278,11 @@ private:
UserRatingList fUserRatings; UserRatingList fUserRatings;
BitmapList fScreenshots; BitmapList fScreenshots;
PackageState fState; PackageState fState;
PackageInstallationLocationSet
fInstallationLocations;
float fDownloadProgress; float fDownloadProgress;
PackageListenerList fListeners; PackageListenerList fListeners;
int32 fFlags;
}; };

View File

@ -227,31 +227,14 @@ PackageManager::GetPackageState(const PackageInfo& package)
PackageActionList PackageActionList
PackageManager::GetPackageActions(PackageInfoRef package, Model* model) PackageManager::GetPackageActions(PackageInfoRef package, Model* model)
{ {
Init(B_ADD_INSTALLED_REPOSITORIES | B_ADD_REMOTE_REPOSITORIES);
PackageActionList actionList; PackageActionList actionList;
if (package->IsSystemPackage())
bool installed = false;
bool systemPackage = false;
BSolverPackage* solverPackage = _GetSolverPackage(package);
if (solverPackage == NULL)
return actionList; return actionList;
const BSolverRepository* repository = solverPackage->Repository(); int32 state = package->State();
if (repository == static_cast<const BSolverRepository*>( if (state == ACTIVATED || state == INSTALLED) {
SystemRepository())) { actionList.Add(PackageActionRef(new UninstallPackageAction(
installed = true; package, model), true));
// systemPackage = true;
// TODO: Being installed in system doesn't make it a system package.
} else if (repository == static_cast<const BSolverRepository*>(
HomeRepository())) {
installed = true;
}
if (installed) {
if (!systemPackage) {
actionList.Add(PackageActionRef(new UninstallPackageAction(
package, model), true));
}
} else { } else {
actionList.Add(PackageActionRef(new InstallPackageAction(package, actionList.Add(PackageActionRef(new InstallPackageAction(package,
model), true)); model), true));