Add compatible version support to packagefs

This commit is contained in:
Ingo Weinhold
2011-11-25 06:18:29 +01:00
parent 5c42c97abb
commit c5909fb0d2
6 changed files with 54 additions and 7 deletions
@@ -60,3 +60,23 @@ Dependency::ResolvableVersionMatches(Version* resolvableVersion) const
return resolvableVersion != NULL return resolvableVersion != NULL
&& fVersion->Compare(fVersionOperator, *resolvableVersion); && fVersion->Compare(fVersionOperator, *resolvableVersion);
} }
bool
Dependency::ResolvableCompatibleVersionMatches(Version* resolvableVersion) const
{
if (fVersion == NULL)
return true;
// Only compare the versions, if the operator indicates that our version is
// some kind of minimum required version. Only in that case the resolvable's
// actual version is required to be greater (or equal) and the backwards
// compatibility check makes sense.
if (fVersionOperator == B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL
|| fVersionOperator == B_PACKAGE_RESOLVABLE_OP_GREATER) {
return resolvableVersion != NULL
&& fVersion->Compare(fVersionOperator, *resolvableVersion);
}
return true;
}
@@ -49,6 +49,8 @@ public:
{ return fResolvable; } { return fResolvable; }
bool ResolvableVersionMatches( bool ResolvableVersionMatches(
Version* resolvableVersion) const; Version* resolvableVersion) const;
bool ResolvableCompatibleVersionMatches(
Version* resolvableVersion) const;
const char* Name() const { return fName; } const char* Name() const { return fName; }
@@ -16,7 +16,8 @@ Resolvable::Resolvable(::Package* package)
fPackage(package), fPackage(package),
fFamily(NULL), fFamily(NULL),
fName(NULL), fName(NULL),
fVersion(NULL) fVersion(NULL),
fCompatibleVersion(NULL)
{ {
} }
@@ -25,13 +26,16 @@ Resolvable::~Resolvable()
{ {
free(fName); free(fName);
delete fVersion; delete fVersion;
delete fCompatibleVersion;
} }
status_t status_t
Resolvable::Init(const char* name, ::Version* version) Resolvable::Init(const char* name, ::Version* version,
::Version* compatibleVersion)
{ {
fVersion = version; fVersion = version;
fCompatibleVersion = compatibleVersion;
fName = strdup(name); fName = strdup(name);
if (fName == NULL) if (fName == NULL)
@@ -24,9 +24,11 @@ public:
Resolvable(::Package* package); Resolvable(::Package* package);
virtual ~Resolvable(); virtual ~Resolvable();
status_t Init(const char* name, ::Version* version); status_t Init(const char* name, ::Version* version,
// version is optional; object takes over ::Version* compatibleVersion);
// ownership (even in case of error) // version and compatibleVersion are
// optional; object takes over ownership
// (even in case of error)
::Package* Package() const { return fPackage; } ::Package* Package() const { return fPackage; }
@@ -37,6 +39,8 @@ public:
const char* Name() const { return fName; } const char* Name() const { return fName; }
::Version* Version() const { return fVersion; } ::Version* Version() const { return fVersion; }
::Version* CompatibleVersion() const
{ return fCompatibleVersion; }
void AddDependency(Dependency* dependency); void AddDependency(Dependency* dependency);
void RemoveDependency(Dependency* dependency); void RemoveDependency(Dependency* dependency);
@@ -48,6 +52,7 @@ private:
ResolvableFamily* fFamily; ResolvableFamily* fFamily;
char* fName; char* fName;
::Version* fVersion; ::Version* fVersion;
::Version* fCompatibleVersion;
ResolvableDependencyList fDependencies; ResolvableDependencyList fDependencies;
public: // conceptually package private public: // conceptually package private
@@ -54,7 +54,9 @@ ResolvableFamily::ResolveDependency(Dependency* dependency)
{ {
for (FamilyResolvableList::Iterator it = fResolvables.GetIterator(); for (FamilyResolvableList::Iterator it = fResolvables.GetIterator();
Resolvable* resolvable = it.Next();) { Resolvable* resolvable = it.Next();) {
if (dependency->ResolvableVersionMatches(resolvable->Version())) { if (dependency->ResolvableVersionMatches(resolvable->Version())
&& dependency->ResolvableCompatibleVersionMatches(
resolvable->CompatibleVersion())) {
resolvable->AddDependency(dependency); resolvable->AddDependency(dependency);
return true; return true;
} }
@@ -318,6 +318,20 @@ struct Volume::PackageLoaderContentHandler : BPackageContentHandler {
} }
ObjectDeleter<Version> versionDeleter(version); ObjectDeleter<Version> versionDeleter(version);
// create a version object, if a compatible version is specified
Version* compatibleVersion = NULL;
if (value.resolvable.haveCompatibleVersion) {
const BPackageVersionData& versionInfo
= value.resolvable.compatibleVersion;
status_t error = Version::Create(versionInfo.major,
versionInfo.minor, versionInfo.micro,
versionInfo.preRelease, versionInfo.release, version);
if (error != B_OK)
RETURN_ERROR(error);
}
ObjectDeleter<Version> compatibleVersionDeleter(
compatibleVersion);
// create the resolvable // create the resolvable
Resolvable* resolvable = new(std::nothrow) Resolvable(fPackage); Resolvable* resolvable = new(std::nothrow) Resolvable(fPackage);
if (resolvable == NULL) if (resolvable == NULL)
@@ -325,7 +339,7 @@ struct Volume::PackageLoaderContentHandler : BPackageContentHandler {
ObjectDeleter<Resolvable> resolvableDeleter(resolvable); ObjectDeleter<Resolvable> resolvableDeleter(resolvable);
status_t error = resolvable->Init(value.resolvable.name, status_t error = resolvable->Init(value.resolvable.name,
versionDeleter.Detach()); versionDeleter.Detach(), compatibleVersionDeleter.Detach());
if (error != B_OK) if (error != B_OK)
RETURN_ERROR(error); RETURN_ERROR(error);