-
Notifications
You must be signed in to change notification settings - Fork 33
Versions and Constraints
In Buckaroo Constraints are filters on commits:
Consider following Dependency Graph:
Root -> A@1.0
Root -> B@1.0
A@1 -> C@1.0
B@1 -> C@2.0
Should this fail or succeed?
When analyzing the C++ ecosystem we discovered that this is a very common situation.
Developers resolve this situation in two ways:
- make one of the packages private
- ignore the conflict and hope for the best
Despite C++ ABI being very sensitive to changes the latter approach works surprisingly often.
To understand why we need to look behind into the packages. As soon as we do this it becomes evident:
git ls-remote https://github.com/boostorg/asio
e62ac5aa6be84aad5a6f2ce83b9650dde29fcfad refs/tags/boost-1.64.0
e62ac5aa6be84aad5a6f2ce83b9650dde29fcfad refs/tags/boost-1.64.0-beta1
e62ac5aa6be84aad5a6f2ce83b9650dde29fcfad refs/tags/boost-1.64.0-beta2
d53033eec64f806986f01641ee70bbf11c5db8cc refs/tags/boost-1.65.0
d53033eec64f806986f01641ee70bbf11c5db8cc refs/tags/boost-1.65.1
310f245a35a20af59a4cd0030626a4de23c7309c refs/tags/boost-1.66.0
25dc6780c2c73dd6a4d74e65e854fc0f705cbb60 refs/tags/boost-1.67.0
25dc6780c2c73dd6a4d74e65e854fc0f705cbb60 refs/tags/boost-1.68.0
Notice how the commit hash doesn't change across multiple versions.
This means boost-asio@1.68.0
is identical to boost-asio@1.67.0
.
Often Library authors maintain a set of (co-dependent) libraries in a mono-repository. This makes it easy to implement, test and deploy new features quickly. For simplicity often there is only one SemVer maintained for all libraries and the libraries are packaged and released seperatly.
Buckaroo models Constraints as filters on Version Sets. Two version are considered equal if the sourcecode yield the same hash. In other words: if two package versions are structurly equivalent, they are considered as the same package.
This leads to some counter-intuitive results like
boost-asio@all(1.67.x 1.68.x branch=develop)
is resolvable because there is a commit on branch develop that is tagged as 1.67.0 and 1.68.0
As computing the hash of a project - especially if you have to fetch the source code first - we use the git commit hash when possible.
Given that Buckaroo's manifest is part of the project and the version is fully determined by Git, it is sensible not to maintain a version-string inside your project.
As the discovery of package-versions is expensive and asynchronous,
Buckaroo models package-versions as asyncSeq
.
Logical operations like all
and any
are implemented as intersection and merges over those streams.
Furthermore there are different strategies for fetching specific versions that satisfy a constraint.
For instance finding tag=v1.67
is very easy as tags are advertised commits and discoverable via git ls-remote
.
On the other hand, finding a specific commit revision=c0ffee
is very difficult as we don't know which branch-tip is closed to that commit.
Unfortunately there is no way of querying a remote git server for this information.
However Buckaroo uses several heuristics to avoid a full clone, eg. known conventions and information stored in lockfiles.