Support for version ranges and other expressions
See original GitHub issueThis is a feature to summarize and discuss implementation details and UX for the so called “Installing latest version or supportint 1.X”: https://github.com/conan-io/conan/issues/15.
Ongoing work can be followed in: https://github.com/conan-io/conan/pull/640
It is also related to the issue: https://github.com/conan-io/conan/issues/548 and related work by @Prinkesh
Lets outline this feature and the proposed approach:
- It will allow package recipes and consumers to specify a “version expression” instead of an exact version. The syntax proposed for it would be
MyPackage/[expression]@user/channel
, where the[]
are literal. - User/channel are not to be evaluated or changed. They are intended for very different use cases, and an installation of a package from another (lets say, testing) channel or user, doesn’t seem desirable at all.
- Typical syntax could be, e.g.:
MyPackage/[>1.2, <1.8]@user/channel
, or something like that. Still not defined, but this concerns me very little. Of course, expressions like~3.0.0
as suggested by @DEGoodmanWilson can also be supported. - By default, it will evaluate against the local conan cache, i.e. installed packages, so if it finds matching installed packages for the given expressions, it will use them. If they are not found, it will check in the remotes, in order, like a normal
conan install
- That means, that for a given install with all the packages in the local cache, re-running
conan install
will not make any connection or query to any remote to try to resolve/update such version expressions - If a check in the remotes for newer versions is desired, that can be done with the
conan install --update
argument. Such argument will ignore the locally installed packages and directly query the remotes, in order to retrieve the best matching version to the given expression. - The usual ABI compatibility rules still apply for a given package, and must be defined as such in the package
conan_info()
method. That means, that if a package A has a dependency toB/[b-version-ranges]@user/channel
, and using different versions of B inside A (like if B is a header only being embedded in a shared A library), generates a different binary for A, then the required specification will still be necessary inconan_info()
. This is not a simple task, but it is exactly the same as right now with versions overrides, only the package creator can know about the package binaries compatibility regarding its dependencies. - It will work locally and incrementally for each package, from downstream, starting from the user project, moving up in the dependency graph. When a package recipe is retrieved while building the graph, its dependencies will be evaluated using the version expressions found in its
requires
, and will move up in the graph. Further version ranges up in the graph might satisfy such requirement or fail, but they will not re-define the version. A global SAT solver for the full graph would be extremely complicated to implement given the complexity of the dependencies, as they can, and often are, conditional on the specific settings like OS. Keeping the current policy, which is that the downstream packages and lately the final consumer is the one defining the versions, makes the most sense, due to the nature and typical flows with C and C++ projects.
Help wanted: It would be extremely useful if someone could contribute with part of the logic. I have already started with the scaffolding and global approach, but the evaluation of the version ranges and expressions would be a completely isolated functionality, easy to implement regarding conan, but will require a good effort.
Looking forward feedback, thanks!
Issue Analytics
- State:
- Created 7 years ago
- Reactions:3
- Comments:18 (12 by maintainers)
With this new feature, is there a way to freeze the dependencies of a project, for example before a release, as shrinkwrap does it for an npm project?
If we want to go with a syntax compatible with SemVer, FWIW, we should consider just using this module directly: https://github.com/podhmo/python-semver