-
Notifications
You must be signed in to change notification settings - Fork 990
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
[question] Overriding user and channel of a dependency in 2.0 #13742
Comments
I think the previous A different story is that this probably wouldn't be a recommended approach. User/channel shouldn't be a versioning strategy, just part of the name. If it is a different software code, it should be a different version, if it is not different code, it should have the same binary name, and its "maturity" controlled by where it is, in which server repository it is hosted, and dependency resolution can be done against those, or explicitly pinning the revision of the thing to do. But this would be a deviation of the original issue, so please check that PR and that overrides still work and let us know. |
Thanks for the reply @memsharded. The Considering the following conanfile: class Foo(ConanFile):
name = "foo"
version = "0.1.0"
def requirements(self):
self.requires("pkg/[>=1.0.0 <2.0.0]@user/stable") I use git flow to manage my libraries. This has the following implications:
Because a number of my packages are inter-related, co-development of these packages can be useful and so the way I was approaching this was to use: conan create . user/testing --require-override=pkg/1.1.0@user/experimental (in this case, the I'm pretty happy with this process - I feel as though it semantically maps reasonably well to git flow, and was supported in 1.x. To address some of your comments:
I disagree with this. This assumes a new version is released for every commit (every change to the code base), if a new package is being built for every commit. This is the approach we apply on the
Could you illustrate what a workflow like this would look like? My best guess is: conan create . --user=user --channel=testing -r=experimental-repo --build=pkg/1.1.0 But this has a lot of ambiguity in it. If I don't have every other dependency in my local cache, then I'm not able to be explicit about which maturity level each dependency has - all of the missing ones will be pulled from My use case would be satisfied by bringing conan lock create . which would give:
And then when a dependency needs to be overridden: conan lock add --require-override pkg/1.1.0@user/experimental which would modify this as follows:
then one could build using the updated lockfile: conan build . -l conan.lock (in my testing where trying to insert an older version, i.e. if i used |
Thanks for the detailed explanation, I think I understand the case a bit better. I'd also say that Conan 2.0 is also promoting more standard versioning strategies, in the case that you are describing, it could be like:
Please let me know if this helps. |
Thanks @memsharded that's a useful response. I hadn't considered using a pre-release tag to mark development versions - it's a good idea. I think it will probably solve my immediate requirement, but I'll give it some road testing to make sure it covers my use cases before closing this issue. It would also mean that when building locally, I can't differentiate between my local builds and what I've obtained from the server, which is a useful distinction to make because the contents of our server comes only from CI builds. The only other gripe that I have with that solution is that it's very semver specific. There are other versioning schemes which won't preserve this kind of ordering, many of which are adopted by libraries throughout the conan index. This means that we'll only be able to override packages that conform to semver using this method. It also assumes that I have control over the versioning scheme of my (or my organisations) libraries, which may not always be the case, so it's limited in those respects. |
Conan 2.0 has made version range resolution more flexible, so it will understand things like But yes, in any case, as to create a new channel anyway it can only happen in the |
Changelog: Omit Docs: Omit Close #13742
This has been closed as a result of merging #13745, if there is any further comment when you give the above a try please re-open or create a new ticket. Thanks! |
@memsharded I've been thinking about this a bit more. It does strike me that being able to override using user/channel would be a more general, less opinionated solution (in the sense that it doesn't force you to couple the versioning scheme with package variants). Is there a specific objection to this functionality from the conan team? Why was it removed? Also, after having thought about it a bit more, it strikes me that this would fit reasonably well within a "virtual recipe" paradigm as described/requested in:
They're different, of course, but if you look at the fundamental principles, there's scope for a consistent approach:
This would mean that the default case is that all packages essentially have from conan import ConanFile
class MyPkg(ConanFile):
name = "mypkg"
version = "1.0"
provides = "mypkg" # explicit for demonstration, but would be the default case and not explicitly specified Which would allow overriding a package in the tree that varies on version, user or channel or any combination of these. But then also, it can contribute into a different interface (which is the current from conan import ConanFile
class MyPkg(ConanFile):
name = "mypkg"
version = "1.0"
provides = "jpeg" # also mypkg, can override packages matching `mypkg` or ones that also provide `"jpeg"` Just some thoughts. Edit: I just saw that this actually seems to already be the case? Could this be used to define the override mechanism?
|
I think there are 2 different things in this thread
Overrides are a very problematic case because it introduce variability points in places where it is almost impossible to recover the information when it is necessary. Let me put an example, and the challenge for lockfiles (that #13597 is trying to solve, and we have been working in previous PRs to provide support for this one, quite a lot of effort) that it defines:
The opinionated solution was previously the Conan one, that clearly deviated from the known good practices around versioning and versioning standards. At least for "maturity" level, the pre-releases are quite a standard approach across different technologies. Also, it is important to highlight that Conan 2.0 hasn't removed the overrides, they are still very possible and the test in #13745 proves it keep working. They are possible in recipes, it has been removed from CLI args, because that makes it yet another level of un-traceability, because those values are no longer capture anywhere. They do not exist in profiles, conf, recipes, lockfiles... they only exist in the caller (CI), which makes things more complicated to track, reproduce by developers, etc. Note that we are even discouraging
This is because we have saw many users during the last years struggling with using channel for this purpose, while a more standard versioning approach with pre-releases, version ranges, etc, seems to have better results in the majority of cases. A completely different issue is the
Not really, the name is just assigned to the |
Thanks for the detailed reply @memsharded, really appreciate you taking the time to engage on this.
Shouldn't this be resolved when the dependency graph is being constructed? My thought was that this is where the conan client provides the visibility over the entire chain, and tracks that there's an override from The way I would expect this to work is that overriding (in the safe context) would trigger a re-evaluation of the tree and resolve all overrides to a coordinate in the valid solution space. What I mean here, is that I would expect that you can only override to a version that lies within the intersection of all version ranges in the dependency graph (in the case of version). There's also an argument for an override in the unsafe context, in which you can override to a version outside of the intersection, with the caveat that here be dragons. Perhaps these two are being conflated in the language we're using here. I would also expect that this is how lockfiles work - they are a specification of a coordinate in the solution space of combinations of versions/settings/options (I think this has been collapsed down to just versions for conan 2?) for each package and would generally always require tree computation. I think there's also value in being able to specify a coordinate outside of the valid solution space (without guarantees that it would lead to a meaningful tree) for users who have information that can't be captured by conan's dependency model.
I agree with you that package maturity is perhaps better represented as a version (my opinion), however I disagree with your assessment that the previous defaults were more opinionated. Imposition of "best practices" is definitionally an opinion, because what "best practices" are is subjective and will change as standards and technologies evolve and if you provide only one way to achieve a thing, then you won't be robust to the changing landscape. Whilst you or I may not consider it "best practice", It's a common practice to use different release channels to represent software maturity, especially where projects have not opted for semver. I'm a fan of semver - this isn't an attack, I'm just stating that this decision means that if they use conan, they would need to shoehorn semver principles into their package versioning to achieve a similar distinction between maturity levels because conan is coupling this to versioning scheme where it doesn't necessarily need to be. I've seen your statements with regards to this refer to the removed ability to perform package promotion between channels (using
The resolution here is that packages that use release channels have to be built multiple times - there's no native promotion process, and I think that's fine. It's a small inefficiency, but it's fine - that's the tradeoff with the package immutability guarantee. Especially because in an
Appreciated - traceability is an issue. I would be extremely happy if overrides made it to lockfiles. As described above, if you think about a lockfile as the specification of a coordinate in the solution space of the dependency tree, this makes it the ideal place to perform a package override. I take your point that it isn't "that simple" if changing the dependency tree doesn't impact something like the package id to trigger a rebuild of the dependencies the depend on the overwritten one.
Yes, I can appreciate the difficulty that there's been in establishing workflows around this. It took me a while to work out how to approach it as well. In my mind it seems like there is a place for both though. To illustrate, I've had a chance to experiment with your suggestions and they've been really useful - so thanks for that. I think that they resolve most of my immediate use case, however there are a few things to highlight. First is that when I'm tinkering with a recipe or a bit of code, it doesn't necessarily constitute a new release, but my experimentation. To address this in the past, I would normally export this as
Not conflicting here is important, because I want to be confident that
I like the first two, but I don't like the third so much. This has the following implications:
To address this, we have Additionally, this only really works for in-source recipes. For out of source recipes, where a I could do something like
Fair enough. I see it as a generalization of the same concept, but that of course has no consideration for the implementation details, so if it's not workable it's not workable. Still, given that the This has gotten quite lengthy and I'm not 100% sure I've been perfectly clear about the gaps that I still see. If you think there's value in breaking this out into discrete use cases, I'm happy to do so, just let me know. |
I just thought that I'd also add, the practical barrier that I see at the moment is that given the following lockfile:
Beyond that, I think that there are some useful helper functions that could be added the |
|
For tracking, relates to #9097 |
What is your question?
Is there a mechanism of overriding a user and channel in a dependency in conan 2? This was possible in 1.x, and was a useful feature in the following cases without modifying the conanfile:
pkg/x.y.z@userA/stable
vspkg/x.y.z@userB/stable
vspkg/x.y.z@_/_
)pkg/x.y.z@user/stable
vspkg/x.y.z@user/experimental
)I'm aware that lockfiles have notionally replaced the
--require-override
syntax, however these only seem to be appropriate for overriding versions of a dependency. Attempting to useconan lock add --requires pkg/x.y.z@user/experimental
when the recipe containsself.requires("pkg/x.y.z@user/stable")
just continues to installpkg/x.y.z@user/stable
.If there is no mechanism for this, what's the intended replacement to manage these workflows?
Have you read the CONTRIBUTING guide?
The text was updated successfully, but these errors were encountered: