-
-
Notifications
You must be signed in to change notification settings - Fork 260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multiple APIs and version numbers per package #3512
Comments
I quite like this idea. I think a more common use-case for a feature like this, would be to support relying on a subset of the public API that doesn't change during a breaking version bump, though. For example, if you only need
allowing you to freely upgrade
to make sure these are grouped together in the compat section. I also don't know if it's technically possible to register a package with a dot in the name, in which case |
A couple notes, Everything that is possible with this is also possible to do by adding wrapper packages that re-export subsets of the wrapped package's public and/or private API and which specify an
That's an interesting use-case, thanks for bringing it up! I'd denote it Sub-APIs may be added and removed in non-breaking releases of the main package's API without issue. The resolver would assume that a package with a dependency on
I don't think this is possible. |
I want to depend on a package's internals and still safely benefit from automatic update propagation using SymVer. To do this, I want the ability to be able to define multiple APIs for a single package.
Let's consider a case study. DataStructures.jl defines
DataStructures.MultiDict
, and many public functions to work with it including modification and queries. Now let's say I'm making a package and have an uncommon use case that warrants usingDataStructures.MultiDict
s but also requires a specialized high-performance implementation of an obscure operation that DataStructures.jl doesn't support. I read the implementation ofDataStructures.MultiDict
and write some self contained code that takes aDataStructures.MultiDict
, and efficiently performs my operation by directly manipulating its internal fields. Now I have several choices: 1) add my code to the public API of DataStructures.jl 2) add the internal fields of DataStructures.MultiDict to the public API of DataStructures.jl 3) use the internals and declare a dependency on the exact version of DataStructures"=0.18.13"
requiring me to manually green-light all updates to DataStructures.jl before users of my package can use them 4) use the internals and, declare permissive compat bounds such as"^0.18.13"
, and hope for the best even though it would be totally valid for DataStructures.jl to change their internals and break my code in0.18.14
.There are cases when none of these are great options. I'd like to add yet another option: declare a dependency on
DataStructures.DictInternals
.In implementation, packages may declare additional version numbers in their Project.toml, like so
And define the scope of "DictInternals" in their documentation. In this example, let's say the API of
DictInternals
includesDataStructures.MultiDict
, including all its fields and inner constructors, but does not include any other functions.Other packages can depend on these alternate version numbers in addition to or instead of the primary version number with
Now, in writing my package, I declare a dependency on DataStructures with version
"0.18.13"
and also declare a dependency on DataStrucutres.DictInternals with a version"2.0.6, 3"
(carrot specifiers are implicit).Now, if DataStructures.jl makes a non-breaking change that also doesn't change dictionary internals, they can release it as
If they make some changes to dictionary internals that were not covered by their well-defined
DictInternals
API, then they can also releaseBut if they remove a field or add, remove, or change any invariants covered by DictInternals (such as the interpretation of a
UInt8
metadata field), then that is a breaking change in DictInternals. For example, if they change from storing keys and values in separate arrays to storing them inline together, that would be breaking to DictInternals, even if it doesn't affect DataStructure.jl's public API. In this case, they would release:In the first two cases, Pkg would automatically mark my package as compatible with the new version of DataStructures.jl because there were no breaking changes. In the last case, Pkg would mark my package as incompatible but still mark everyone who doesn't depend on DictInternals's packages as compatible.
The text was updated successfully, but these errors were encountered: