mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Tell resolver about ECVs of overridden versions
Otherwise trying to use a package with constraint "livedata@1.0.0" when you are loading livedata 1.0.1 from a local package will fail.
This commit is contained in:
@@ -57,6 +57,12 @@ ConstraintSolver.PackagesResolver.prototype._ensurePackageInfoLoaded = function
|
||||
ConstraintSolver.PackagesResolver.prototype._loadPackageInfo = function (
|
||||
packageName) {
|
||||
var self = this;
|
||||
|
||||
// XXX in theory there might be different archs but in practice they are
|
||||
// always "os", "web.browser" and "web.cordova". Fix this once we
|
||||
// actually have different archs used.
|
||||
var allArchs = ["os", "web.browser", "web.cordova"];
|
||||
|
||||
// XXX is sortedness actually relevant? is there a minor optimization here
|
||||
// where we can only talk to self.catalog once?
|
||||
var sortedVersions = self.catalog.getSortedVersions(packageName);
|
||||
@@ -66,10 +72,6 @@ ConstraintSolver.PackagesResolver.prototype._loadPackageInfo = function (
|
||||
|
||||
var unibuilds = {};
|
||||
|
||||
// XXX in theory there might be different archs but in practice they are
|
||||
// always "os", "web.browser" and "web.cordova". Fix this once we
|
||||
// actually have different archs used.
|
||||
var allArchs = ["os", "web.browser", "web.cordova"];
|
||||
_.each(allArchs, function (arch) {
|
||||
var unitName = packageName + "#" + arch;
|
||||
unibuilds[unitName] = new ConstraintSolver.UnitVersion(
|
||||
@@ -121,6 +123,16 @@ ConstraintSolver.PackagesResolver.prototype._loadPackageInfo = function (
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// We need to be aware of the earliestCompatibleVersion values for any
|
||||
// packages that are overridden by local packages, in order to evaluate
|
||||
// 'compatible-with' constraints that name that version.
|
||||
_.each(self.catalog.getForgottenECVs(packageName), function (ecv, version) {
|
||||
_.each(allArchs, function (arch) {
|
||||
var unitName = packageName + '#' + arch;
|
||||
self.resolver.addExtraECV(unitName, version, ecv);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// dependencies - an array of string names of packages (not slices)
|
||||
|
||||
@@ -213,15 +213,16 @@ ConstraintSolver.ConstraintsList.prototype.edgeMatchingVersionsFor = function (
|
||||
}
|
||||
|
||||
if (c.type === "compatible-with") {
|
||||
var uv = resolver.getUnitVersion(packageName, c.version);
|
||||
if (uv) {
|
||||
var thisECV = resolver.getEarliestCompatibleVersion(
|
||||
packageName, c.version);
|
||||
if (thisECV) {
|
||||
if (earliestCompatibleVersion &&
|
||||
earliestCompatibleVersion !== uv.earliestCompatibleVersion) {
|
||||
earliestCompatibleVersion !== thisECV) {
|
||||
// Two constraints name versions with different ECV. Nothing can be
|
||||
// compatible with both!
|
||||
impossible = true;
|
||||
} else if (! earliestCompatibleVersion) {
|
||||
earliestCompatibleVersion = uv.earliestCompatibleVersion;
|
||||
earliestCompatibleVersion = thisECV;
|
||||
}
|
||||
// else the ECV matches, which is great.
|
||||
} else {
|
||||
|
||||
@@ -34,6 +34,16 @@ ConstraintSolver.Resolver = function () {
|
||||
|
||||
// Refs to all constraints. Mapping String -> instance
|
||||
self._constraints = {};
|
||||
|
||||
// Let's say that we that package P is available from source at version X.Y.Z.
|
||||
// Then that's the only version that can actually be chosen by the resolver,
|
||||
// and so it's the only version included as a UnitVersion. But let's say
|
||||
// another unit depends on it with a 'compatible-with' dependency "@A.B.C". We
|
||||
// need to be able to figure out the earliestCompatibleVersion of A.B.C, even
|
||||
// though A.B.C is not a valid (selectable) UnitVersion. We store them here.
|
||||
//
|
||||
// Maps String unitName -> String version -> String earliestCompatibleVersion
|
||||
self._extraECVs = {};
|
||||
};
|
||||
|
||||
ConstraintSolver.Resolver.prototype.addUnitVersion = function (unitVersion) {
|
||||
@@ -78,6 +88,36 @@ ConstraintSolver.Resolver.prototype.getConstraint =
|
||||
new ConstraintSolver.Constraint(name, versionConstraint);
|
||||
};
|
||||
|
||||
ConstraintSolver.Resolver.prototype.addExtraECV = function (
|
||||
unitName, version, earliestCompatibleVersion) {
|
||||
var self = this;
|
||||
check(unitName, String);
|
||||
check(version, String);
|
||||
check(earliestCompatibleVersion, String);
|
||||
|
||||
if (!_.has(self._extraECVs, unitName)) {
|
||||
self._extraECVs[unitName] = {};
|
||||
}
|
||||
self._extraECVs[unitName][version] = earliestCompatibleVersion;
|
||||
};
|
||||
|
||||
ConstraintSolver.Resolver.prototype.getEarliestCompatibleVersion = function (
|
||||
unitName, version) {
|
||||
var self = this;
|
||||
|
||||
var uv = self.getUnitVersion(unitName, version);
|
||||
if (uv) {
|
||||
return uv.earliestCompatibleVersion;
|
||||
}
|
||||
if (!_.has(self._extraECVs, unitName)) {
|
||||
return null;
|
||||
}
|
||||
if (!_.has(self._extraECVs[unitName], version)) {
|
||||
return null;
|
||||
}
|
||||
return self._extraECVs[unitName][version];
|
||||
};
|
||||
|
||||
// options: Object:
|
||||
// - costFunction: function (state, options) - given a state evaluates its cost
|
||||
// - estimateCostFunction: function (state) - given a state, evaluates the
|
||||
@@ -552,19 +592,18 @@ ConstraintSolver.Constraint.prototype.isSatisfied = function (candidateUV,
|
||||
if (self.type === "at-least")
|
||||
return true;
|
||||
|
||||
var myUV = resolver.getUnitVersion(self.name, self.version);
|
||||
var myECV = resolver.getEarliestCompatibleVersion(self.name, self.version);
|
||||
// If the constraint is "@1.2.3" and 1.2.3 doesn't exist, then nothing can
|
||||
// match. This is because we don't know the ECV (compatibility class) of
|
||||
// 1.2.3!
|
||||
if (!myUV)
|
||||
if (!myECV)
|
||||
return false;
|
||||
|
||||
// To be compatible, the two versions must have the same
|
||||
// earliestCompatibleVersion. If the earliestCompatibleVersions haven't been
|
||||
// overridden from their default, this means that the two versions have the
|
||||
// same major version number.
|
||||
return myUV.earliestCompatibleVersion ===
|
||||
candidateUV.earliestCompatibleVersion;
|
||||
return myECV === candidateUV.earliestCompatibleVersion;
|
||||
};
|
||||
|
||||
// Returns any unit version satisfying the constraint in the resolver
|
||||
|
||||
@@ -192,6 +192,10 @@ var CompleteCatalog = function () {
|
||||
// XXX: use a future in the future maybe
|
||||
self.refreshing = false;
|
||||
|
||||
// See the documentation of the _extraECVs field in ConstraintSolver.Resolver.
|
||||
// Maps packageName -> version -> its ECV
|
||||
self.forgottenECVs = {};
|
||||
|
||||
// We inherit from the protolog class, since we are a catalog.
|
||||
BaseCatalog.call(self);
|
||||
};
|
||||
@@ -234,6 +238,12 @@ _.extend(CompleteCatalog.prototype, {
|
||||
self.refresh();
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
var self = this;
|
||||
BaseCatalog.prototype.reset.call(self);
|
||||
self.forgottenECVs = {};
|
||||
},
|
||||
|
||||
// Given a set of constraints, returns a det of dependencies that satisfy the
|
||||
// constraint.
|
||||
//
|
||||
@@ -415,6 +425,11 @@ _.extend(CompleteCatalog.prototype, {
|
||||
_.extend(self.effectiveLocalPackages, self.localPackages);
|
||||
},
|
||||
|
||||
getForgottenECVs: function (packageName) {
|
||||
var self = this;
|
||||
return self.forgottenECVs[packageName];
|
||||
},
|
||||
|
||||
// Add all packages in self.effectiveLocalPackages to the catalog,
|
||||
// first removing any existing packages that have the same name.
|
||||
//
|
||||
@@ -430,7 +445,10 @@ _.extend(CompleteCatalog.prototype, {
|
||||
_.each(self.effectiveLocalPackages, function (dir, packageName) {
|
||||
if (!_.has(self.versions, packageName))
|
||||
return;
|
||||
self.forgottenECVs[packageName] = {};
|
||||
_.each(self.versions[packageName], function (record) {
|
||||
self.forgottenECVs[packageName][record.version] =
|
||||
record.earliestCompatibleVersion;
|
||||
removedVersionIds[record._id] = true;
|
||||
});
|
||||
delete self.versions[packageName];
|
||||
|
||||
Reference in New Issue
Block a user