Make sure 'meteor add foo' gives the same constraint to the solver as
'foo' from .meteor/packages: namely, '>=0.0.0' not
'unconstrained' (since the first rules out rcs and the second doesn't)
They are then parsed and provided to underlying HTTP package. We have to
parse them so that signing of requests works properly. In addition,
nonce used in the request is stored in the response so that user can
verify JWT payloads returned from the server.
This reverts commit 080f6f60dd.
Unfortunately, this broke all packages that were published with
`api.versionsFrom('METEOR-CORE@0.9.0-atm')` that used one of these
packages.
Also removes 'update --minor' and 'add --force'.
In the constraint solver, previousSolution (ie, .meteor/versions) was
intended to be used for three purposes:
(a) The *heuristic* used in the state graph walk to decide what state
to look at next:
- VERY STRONGLY prefers not to downgrade *root* dependencies or
change them to incompatible newer versions
- Kinda Strongly prefers not to upgrade root dependencies far
- mildy prefers not to change transitive dependencies (in any
direction)
(b) Actual *constraints* are added to the set of constraints we are
trying to solve, which state that *root* dependencies are not
to be downgraded. Additionally, in most invocation contexts,
constraints are added that say that *root* dependencies are
not to be upgraded to incompatible versions (1.3.0 -> 2.0.0).
The only contexts that lack the secondary constraints are
part of 'update --minor', and 'add --force'.
(c) A more recent change (past few weeks): When running the constraint
solver, we actually run the core constraint solving algorithm
twice. The first time, we add *equality* constraints for all
of the previous versions. If that succeeds, great! We're not
changing any versions (we may add packages that we didn't have
before or drop packages that are no longer needed, though).
Otherwise, we run the constraint solver again without the equality
constraints.
However, due to a bug introduced in May in 0760ffbc36, (b) actually
*never happened*. The commit was the one that intended to make the
(b) constraints only be for root dependencies. But the line:
if (! _.contains(dependencies, uv.name))
is comparing 'uv.name' (something like 'foo#web.browser') to
'dependencies' (a list of things like 'foo'). So in fact, it thinks that
no dependencies are root and doesn't apply the constraints.
That's actually good, because this code is used in many more places than
just 'meteor update', and applying these things as strong constraints
would actually be problematic; eg, it would break 'meteor --release
slightlyolderrelease'!
In addition, the `update --minor` flag was actually not implemented (it
was not in the command declaration).
So for now, we're removing this dead code. We may reintroduce 'update
--minor' or 'add --force' later. We trust that the heuristic will do a
decent job of preventing unnecessary downgrades or incompatible upgrades
while still allowing you to run updates to an older version, eg.
(And in the future, we may change 'meteor update' to use the constraint
solver to figure out which release to update to, rather than going for
the latest one that there exists any solution for.)
We now throw more specific errors, consistent between both tools and
package-version-parser (copy-and-pasted code, sadly, but we really do
have to make this check before uniload-from-checkout).
It now no longer has N nested 2-element hashmaps; the 2-element split
happens at the top level in the JS object. And a nested hash_map is now
just a set (it's great that we can rely on the interned-ness of
constraints!)
8% benchmark speedup and less code.
Instead of recalculating the "edge versions", just keep the list of
alternatives for each dep sorted and look at the first and last.
Provides another 25% speedup to the benchmark, deletes a lot of
code, *AND* removes the one part of the constraint solver that tries to
have a deep understanding of the different constraint types other than
the "is this constraint satisfied" function (ie, makes it easier to add
more constraint types later).
Instead of having two different spots where we do special checks to see
if a piece of the state might have only one alternative, we just ensure
that the ResolverState itself always eagerly converts one-alternative
dependencies into choices.
Factor out the "state" into its own class, ResolverState. The big
difference from the previous state object: it actually explicitly tracks
the set of potential UnitVersions for every active dependency. This
essentially replaces the DependencyList class.
Because we always know exactly how many options there are for a given
dependency, we can both generalize and simplify the "propagate
transitive exact deps" optimization. That optimization only worked on
"foo@=1.2.3" dependencies, which meant it didn't apply in any other
situation where there was only one possible package to choose. But there
are a whole lot of other situations like that: local packages, packages
that just don't have many versions, packages that already have a lot of
constraints applied to them, etc. By tracking the set of potential
alternatives, we can just make sure to always expand 1-alternative units
first. We also maintain the aspect of the optimization where we don't
need to call the cost function until we've actually gotten to a state
with multiple neighbors.
This keeps #2410 fixed as well.
I've removed the constraintAncestor support as part of this refactoring,
so some error messages may be worse than they were before. But this
should set me up pretty well to improve error messages tomorrow.
We haven't yet decided how we want to do versioning for packages that
mostly just wrap non-Meteor code that has its own version numbers. We
might stick to totally-unrelated version numbers (and maybe add a
"wrapped version" field that gets displayed in the upgrade/downgrade
messages?), or change to matching upstream versions (with techniques for
dealing with changes to packaging, a la debian_revision), or something
different.
But since changing to match upstream versions is a possibility, let's
make sure that that operation won't be viewed as a "downgrade" by
updating the wrapped packages whose upstream versions are 0.*.
Introduces a "Patience" class which lets CPU-bound operations like the
constraint solver yield every so often, and print messages if an
operation (CPU-bound or not) are taken or not.