Add compatible version support to packagefs

This commit is contained in:
Ingo Weinhold 2011-06-27 03:59:27 +02:00
parent 71120ca73d
commit 89f1807be6
6 changed files with 54 additions and 7 deletions

View File

@ -60,3 +60,23 @@ Dependency::ResolvableVersionMatches(Version* resolvableVersion) const
return resolvableVersion != NULL
&& 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;
}

View File

@ -49,6 +49,8 @@ public:
{ return fResolvable; }
bool ResolvableVersionMatches(
Version* resolvableVersion) const;
bool ResolvableCompatibleVersionMatches(
Version* resolvableVersion) const;
const char* Name() const { return fName; }

View File

@ -16,7 +16,8 @@ Resolvable::Resolvable(::Package* package)
fPackage(package),
fFamily(NULL),
fName(NULL),
fVersion(NULL)
fVersion(NULL),
fCompatibleVersion(NULL)
{
}
@ -25,13 +26,16 @@ Resolvable::~Resolvable()
{
free(fName);
delete fVersion;
delete fCompatibleVersion;
}
status_t
Resolvable::Init(const char* name, ::Version* version)
Resolvable::Init(const char* name, ::Version* version,
::Version* compatibleVersion)
{
fVersion = version;
fCompatibleVersion = compatibleVersion;
fName = strdup(name);
if (fName == NULL)

View File

@ -24,9 +24,11 @@ public:
Resolvable(::Package* package);
virtual ~Resolvable();
status_t Init(const char* name, ::Version* version);
// version is optional; object takes over
// ownership (even in case of error)
status_t Init(const char* name, ::Version* version,
::Version* compatibleVersion);
// version and compatibleVersion are
// optional; object takes over ownership
// (even in case of error)
::Package* Package() const { return fPackage; }
@ -37,6 +39,8 @@ public:
const char* Name() const { return fName; }
::Version* Version() const { return fVersion; }
::Version* CompatibleVersion() const
{ return fCompatibleVersion; }
void AddDependency(Dependency* dependency);
void RemoveDependency(Dependency* dependency);
@ -48,6 +52,7 @@ private:
ResolvableFamily* fFamily;
char* fName;
::Version* fVersion;
::Version* fCompatibleVersion;
ResolvableDependencyList fDependencies;
public: // conceptually package private

View File

@ -54,7 +54,9 @@ ResolvableFamily::ResolveDependency(Dependency* dependency)
{
for (FamilyResolvableList::Iterator it = fResolvables.GetIterator();
Resolvable* resolvable = it.Next();) {
if (dependency->ResolvableVersionMatches(resolvable->Version())) {
if (dependency->ResolvableVersionMatches(resolvable->Version())
&& dependency->ResolvableCompatibleVersionMatches(
resolvable->CompatibleVersion())) {
resolvable->AddDependency(dependency);
return true;
}

View File

@ -318,6 +318,20 @@ struct Volume::PackageLoaderContentHandler : BPackageContentHandler {
}
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
Resolvable* resolvable = new(std::nothrow) Resolvable(fPackage);
if (resolvable == NULL)
@ -325,7 +339,7 @@ struct Volume::PackageLoaderContentHandler : BPackageContentHandler {
ObjectDeleter<Resolvable> resolvableDeleter(resolvable);
status_t error = resolvable->Init(value.resolvable.name,
versionDeleter.Detach());
versionDeleter.Detach(), compatibleVersionDeleter.Detach());
if (error != B_OK)
RETURN_ERROR(error);