-
Notifications
You must be signed in to change notification settings - Fork 980
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
explore if this fix header-only package-id #6451
explore if this fix header-only package-id #6451
Conversation
Possibly proposed such test case already exists: But consider adding testcase where At least thats the current conan behavior - whether that should be expected is different thing :) ( I can see cases where one would like such behavior. ) Maybe conan should have a feature something like: 'propagates versioning_schema of dependencies upwards ) - yes I do realise that conan is working differently, just a thought. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, this is more a feature than a bugfix, I wasn't aware of this intended behavior (that's the reason I didn't talk about it in the blogpost about package_ids). Now I understand the direct
in the semver_direct_mode
mode 🎉
This change will affect recipe_revision_mode
and package_revision_mode
modes too, probably expected.
I found some breaking behavior (bugfix or breaking?):
-
Add another package consuming your
libd
, and addself.info.requires.unrelated_mode()
to thelibc
recipe. This PR modifies existing behavior: nowlibd
becomesMissing
too.⚠️ If you useself.info.requires['libb'].unrelated_mode()
inlibc
it doesn't behave the same wayShould this
unrelated_mode
prevent the propagation of the indirect_prefs down the graph?
Hello @jgsogo If I may put my 2cents here I propose to add a 'general' flag enabling this behavior. Now in Ideal world I would: In current world I would: I personally would enable this feature the moment I see it, Why?
|
I have added 2 tests, for the above cases. @jgsogo . The test: def transitive_unrelated_test(self):
# https://github.com/conan-io/conan/issues/6450
client = TestClient()
client.run("config set general.default_package_id_mode=full_version_mode")
# LibA
client.save({"conanfile.py": GenConanfile()})
client.run("create . liba/1.0@")
client.run("create . liba/2.0@")
# libB -> LibA
client.save({"conanfile.py": GenConanfile().with_require_plain("liba/1.0")})
client.run("create . libb/1.0@")
# libC -> libB
unrelated = "self.info.requires['libb'].unrelated_mode()"
client.save({"conanfile.py": GenConanfile().with_require_plain("libb/1.0")
.with_package_id(unrelated)})
client.run("create . libc/1.0@")
# LibD -> LibC
client.save({"conanfile.py": GenConanfile().with_require_plain("libc/1.0")})
client.run("create . libd/1.0@")
# LibE -> LibD, LibA/2.0
client.save({"conanfile.py": GenConanfile().with_require_plain("libd/1.0")
.with_require_plain("liba/2.0")})
client.run("create . libe/1.0@", assert_error=True)
self.assertIn("liba/2.0:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache", client.out)
self.assertIn("libb/1.0:e71235a6f57633221a2b85f9b6aca14cda69e1fd - Missing", client.out)
self.assertIn("libc/1.0:e3884c6976eb7debb8ec57aada7c0c2beaabe8ac - Missing", client.out)
self.assertIn("libd/1.0:9b0b7b0905c9bc2cb9b7329f842b3b7c6663e8c3 - Missing", client.out) Seems to work the same with and without the patch. I might be missing something, please check. |
In your new test, use There are two different things here:
|
I'd say both are totally expected. In the first one, it is different to be unrelated of one of your dependencies, and the other to be completely unrelated to all of your dependencies. In the second one, yes, the behavior is different. Without this PR, it will find a existing binary for a package, even if it is in |
I need to review all this PR again because I was mistaken about the content of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change is needed and it is indeed a bug, but probably it is one of those bugs that people depend on and it will break existing package_ids.
I mostly agree with @fulara here: #6451 (comment)
Sorry @memsharded @jsgogo but with the way things are right now, I think this PR has a potential to break a lot of stuff. If i correctly understand the changes (I dont currently have a way to test conan behavior out of private branches. ) Consider below scenario: global_mode: set to full_package_mode. If i correctly understand the changes done within this PR, In other words my question really is, whats the current conan behavior of inheriting of versioning_schema from transitive dependencies? Inheriting from the tree of dependencies should be maybe based of scanning the whole tree and taking a minimum from the dependencies? I think for header_only library below should still be valid (maybe) def package_id: Is this good idea? I dont know. |
You can easily test Conan from any repo/branch, for example for this PR you can use:
|
Thanks a lot, @fulara, for sharing all your feedback about this issue. Your understanding is right, there is no inheritance of the package_id mode across dependencies. Each package depends on all the requirements (also transitive requirements) and a recipe can override the package_id mode for all of them ( We might modify the graph model for Conan 2.0 and it is an open issue: https://github.com/conan-io/conan/projects/8, a lot of things can change, but they should be moved to a different issue and grouped together. For now, I totally agree that this PR is a bug fix, but we need an opt-in for this new behavior (it will be the default when using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@memsharded, please, add an opt-in for this new behavior
thanks @jgsogo for that hint about testing custom packages, that was helpful. I stand by my opinion after testing it. see below example. (Now I only need to learn to run your unit tests so mb with next iteration it will be easier :) for you. Example:
conan create:
Because libc depends now by 'default_package_id_mode' on liba. So even though User went out of their length (thats what we are doing now, because we dont like depending on global package_id_mode. ) to define versioning_schema on every single of the direct dependencies they had, they ended up having the dependency liba be defaulted into default_package_id. Actually Now that I am aware of this, I could implement a workaround into our conan wrappers, we will always define a versioning_schema for everything, automatically ( fetch it from our db ), by iterating over self.requires object. So if this solution is inline with your expectation of the behavior, I'll manage. :) However I think the behavior following this PR will be very confusing to some people out there. |
Running the test suite should be easy too:
If you need anything else, let me know (you can write to me in Slack too if you prefer) |
Yes, I agree with you. I will introduce an opt-in to be able to apply the bug-fixed behavior, and not change anything otherwise. |
Added general.fix_transitive_package_id=1 to opt-in to this behavior. Please review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I think that the changelog should categorize it as a feature, and we will need clear docs for this one.
For CONAN_V2_MODE
(#6490) I will consider it a bugfix and the user won't be able to run the buggy behavior, I think this is the way to go.
I agree, changed the Changelog already. Should I change then the |
To be honest, I don't know how to name that config parameter. I don't like the |
Okay, so I finally had the tiem to pick this up again.
We are doing something exactly like this ( maybe it will be actually presented on conan-days by one of my colleagues. ) but only on direct_dependencies. How do I get to a list of all requires component after this PR? Because I have to, I cant have default_package_id. There is no documentation of When I try to iterate over self.into.requires i get:
When brieflly skimming through the code I found this:
Seems like it uses _data which obviously is a private, so is there no way for me to do it?
|
Hi @fulara I think you could try to use something like: def package_id(self):
for pkg_name in self.info.requires.pkg_names: # Iterate all info.requires
req_info = self.info.requires[pkg_name ]
# You can set the mode
req_info.minor_mode()
# no representation of the mode, but you have access to
# self.name, self.version,self.user, self.channel, self.package_id , self.recipe_revision, self.package_revision
# You can deduce the mode from this data It is not very straightforward, but at least not using private data. Regarding 2) I am not sure it is a good idea. If you mean that when LibB-(depends on)->LibA, and LibA is setting a certain mode, then suddenly LibB starts using that mode, then I think it might not be a good idea. If LibA has a mode "unrelated" or "header-only", that doesn't mean that its dependents should also have this mode. This will also raise a bunch of issues regarding diamonds (conflicts). If it is a way of propagating upstream (lets use the mode of LibB in LibA and all its dependencies, I think I don't see it either, for the same reason. I would say that propagation in the graph shouldn't be the approach for this issue. If what you want is to build your own custom |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is ready, I'd like to read the docs before approving
(And we should open a new issue targetting 2.0 to make this the default behavior --> probably something for CONAN_V2_MODE
)
thanks @memsharded for that, I will test it out and probably do that. Further on mine 2) following your comments.
Anyway, thanks for this fix, I will be incorporating that into my environment when 1.23 comes out. |
Hello @memsharded Just a note, using your proposed code:
Causes all transitive dependencies to appear in the requires section in conaninfo (basically mimics the behavior after this patch enabled ) in 1.21.0 I was worried that it would change the way |
Yes, as long as the transitive dependencies are not cleared with something like
Yes, the |
@memsharded well. Okay - it seems that it was my misunderstanding again, so they were transitive already, Today we have tested our new version and we received scary Anyway: I am waiting for 1.23.0! |
I've just seen this PR after reading the release notes for v1.23. Isn't that basically the partial implementation of #4038 (i.e. only special case for header-only packages)? |
Nop, I don't think so. Actually the opposite, this feature recovers the effect that upstream dependencies have over consumers packageID, when there are header-only dependencies in the middle. It does not change how the The docs contain a graphic in conan-io/docs#1575, maybe that one is useful to illustrate the problem that this PR is resolving. |
Exactly that. From the discussion on #4038, the header-only package is always treated as all its dependencies are So, from the example in the documentation, with terminology from my comment in #4038, the |
Oh, yes, in that regard yes, that is true, |
So, in a way #4038 is a generalization over that, as it also allows for non-header-only packages to have that same behaviour (e.g. some features of my package |
But that is already the behavior of other |
Changelog: Feature: Implement a new package-ID computation that includes transitive dependencies even when the direct dependencies have remove them, for example when depending on a header-only library that depends on a static library.
Docs: conan-io/docs#1575
Close #6450
#tags: slow
#revisions: 1