-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
cmd/go: pass information on incompatible versions to consuming modules #26829
Comments
Isn't what the |
@ucirello great question. The answer is no according to the docs. Specifically, it says:
|
@gopherbot, please add labels modules |
@mattfarina OK - I am not the one equipped to debate on this. But it does seem Again, I am not the one equipped to debate on this, so I could be missing something important. |
@ucirello You bring up some valid questions that are worth discussing and going deeper on. I'm happy to expand for future readers. To expand on the example... if you had... App -> modD -> modA -> modB If modB had the issue and modA had the And, since it only works for the current main module, if modA or modB were libraries without a main it would not work for their testing situations, either. |
If this issue is just about marking releases as insecure / buggy, then this is a duplicate of #24031 (comment) . If this issue is about code review and diffing changes, then I have a few thoughts. I'd like make a to address some of the issues you mentioned with code review, but I don't it should be part of If this issues is about the lack of a way for |
When modB has a bug and make a release to correct it, it will increment at least the patch number. Then |
@kardianos This is similar to #24031 (comment) but not the same. In this case the latest release has a problem with it. There is no newer release to include information about a previous buggy release. There are numerous reasons this could happen. For example,
The design in #24031 (comment) is one where a module, in this case modB, describes information about its previous releases. The modules modA and modD in the examples here have no way to communicate information themselves. The design in #24031 (comment) would work if module maintainers were always on the ball and got releases for issues out quickly. In practice people simply don't do that all the time which is where the problem comes in. Don't we need to be fault tolerant of people? If so, how would that work? How can the ecosystem route around an issue in a release where the maintainer(s) of the module aren't handling it? I believe any solution to this problem should be part of |
@flibustenet How do people handle a long time before a bug fix release to modB? How do they work around that situation? |
@mattfarina If I understand you correctly, I think it is not a goal to protect against every possible way bad imports can land in your code, rather the idea is to provide the necessary primitives to handle them (in this case, Although the modules implementation does not address this concern you put forward directly, it does offer the necessary primitives and the Thus, if this case you put forward is important, other use cases are also important (like having a tool that indicates that an update is available for both transitive and intransitive dependencies) - but neither are necessarily dealt by Personally, I am working on a tool that crystalizes into the main's Edit: Added last paragraph. |
I'm pretty sure @mattfarina would have seen all these given his role in glide, etc., but for other people that might land here, briefly adding some more specific URLs to some conversations about related possible future directions (either previously considered or still being considered):
As far as I am aware, there is a strong desire to do something here, but still an open question as to the exact mechanism(s). It seems like there is very likely a successful path forward that is possible here, but given its significance, this seems like an important area for the community to discuss, analyze, offer possible solutions, etc. (My 2 cents, anyway...) |
@thepudds I'd like to add some more detail to your possible future directions...
That's already touched on over at #24031 (comment) and in the blog series. That setup requires the author of modB to take an action. The problem here is when the maintainer of modB isn't taking an action.
As I noted in the original issue, a problem arises here with information disclosure. If Google operates this site they are in the business of many things. A competitor to Google would be leaking the sets of dependencies they use to Google by using Go. That's not going to be acceptable for many.
Another case where the author of modB takes an action. The case here is when the author of modB does not take an action or has not taken one, yet. The ecosystem needs to route around the issue they face until action is taken. |
@mattfarina Regarding your last point, I had added a comment #24031 (comment) that at least attempted to outline how the author of modB wouldn’t be required to take an action in this scenario you outlined here? But I could very easily be off base here… |
I agree that it would be nice if Google didn't run this service. But even if they did we could design it so that the complete set of information was downloaded to the local system, and then queried. Although it would grow over time I can't imagine that it would ever be very large. |
@mattfarina and more than any other point I might make, I do strongly agree with your points here around this being an extremely important use case to handle well. |
@ianlancetaylor I've learned a little about this...
This is a good idea and would likely scale in data for some time. There are other problems in a system like this and I'm curious how those would be solved. Here are a couple that immediately come to mind:
|
Even not trolls, how about a situation where modA vX as a part broken by modB vY but in an other situation maybe an App use only a little part of modA and modB and will not be affected with this incompatibility ? That said, how often do we meet this kind of situation ? And how was it handled ? Do you have some examples with other languages ? |
It is my understand you are asking "How do we communicate broken releases for transitive dependencies?" Is this correct?
I don't know what you mean by this. Or rather, in my mind the current design is fault tolerant of people, so what do you mean by this?
When you say this, are you implying that displaying broken releases to the developer should be a You are well aware of the Go modules design. I'm assuming you aren't saying that modA can automatically prevent App from getting the latest modB if requested. I'm assuming you want to determine how to best record and communicate breakage as an advisory notice. But please correct me if I'm wrong so we can be on the same page. |
@kardianos I think part of the problem is there is wiggle room on some of this an opinions. I will try to limit those to be more clear.
I think we have different opinions on this. It's the details below or surrounding this we should discuss to be explicit. I will try to be more clear on that. We need to deal with lazy developers. Specifically those who do not look at the details of their transitive dependencies and may not look at changes to their explicit ones often after they are included. This includes when they perform updates to them. The case can be when a chain of lazy developers are involved. For example, App -> modD -> modA -> modB In this situation imagine you had the case where App and modD developers were these lazy developers who didn't look at the details. modA may know about the issue and even document it. But, the developers of modD and App may not read the docs or changelogs. They may not even look at a diff either. This way of updating dependencies is common.
I'm attempting to not suggest an implementation. Rather, I am trying to share the details on the need. Others can design a solution. There are no assumptions on how this should be handled in what I'm saying. If anything, I will try to ferret out more details on a proposed solution but those are from others and I'm trying not to propose one.
This is a good question. This is really targeted at the user experience so the information should be displayed in a way that helps to prevent them from getting into a bad state. With that in mind, I would suggest displaying it for commands like The goal would be to aide the end user in situations where they would need it. |
If we suppose that Then it suffices for the author of “App” to run (I've already suggested that in #26420 (comment).) |
@bcmills What about apps that do not have releases. For example, say one has a SaaS and the tip of master is what is running in production. A CI/CD pipeline could even auto-deploy. If I read #26420 right, it's about releasing software that others can consume. For example, looking for API level changes. In a SaaS (especially a private codebase) these don't matter. Would it be better to catch these issues at build time since the running build is the things being affected? That way someone running a dev build of a releasable codebase would also have the notifications. |
I'm sure you could have a No, it would not be better to catch this during build time. Building is for, well, building and debugging, and running, not going out to the network and checking. |
@mattfarina mentioned elsewhere that this issue #26829 is about how a consumer of modules route around where module authors have yet to fix bugs, and that #24031 is really a separate issue. At the risk of committing a large faux pas, I am therefore moving some of my commentary from #24031 to here and updating my comments here to more clearly target the #26829 usecase outlined in the opening comment above. Setting all that aside, using the start of @mattfarina’s example from #26829:
My understanding of part of the goal here in #26829 is how a consumer of modules can easily be notified of an incompatibility where module authors have yet to fix bugs, or in particular using this example:
... which I think is targeting the use case outlined here in #26829? Mechanism still TBD, but perhaps the mechanism (if I've followed the discussion in #24031) to target the use case here in #26829 might be something like:
But sorry if this is off base or just noise... edit: made slightly more explicit comment (now in bold above) about where the mechanism discussed in #24031 (comment) could kick in for the initial problem scenario outlined here in #26829 by @mattfarina. |
In other words, in that scenario outlined in my immediately prior comment: By checking in and releasing a new modA with a new With this mechanism, this incompatibility information could be communicated using the same core mechanisms of releasing code (and hence the information moves with the same strengths and weaknesses of how the code itself is communicated). In this example, it is the author of modA who both determines there is a problem and communicates the details of the problem, which is good because it is modA that directly depends on modB, and hence the author of modA is much better positioned to determine there is a bug in modB than the less-directly-connected author of 'App' (who is the integrator in this scenario, and who is integrating modB as an indirect dependency and as such the author of 'App' is likely not very aware of exactly how modA interacts with modB. Of all the different actors here, the author of 'App' is likely least well positioned to determine modB is buggy, though the author of 'App' might be the first actor here to experience the pain induced by a buggy modB when 'App' doesn't work). The author of modA and the author of 'App' do not need to rely on any immediate action by the author of the buggy modB, which is good because maintainers can be busy or otherwise might not be able to act for days or weeks or months. Ultimately, hopefully the story has a happy ending when the buggy modB is eventually fixed and released, but no one needed to wait for that to occur. In any event, it seems the mechanism outlined in #24031 (comment) could be used in the scenario outlined by @mattfarina here, but perhaps there is a much better or different solution that would be more appropriate. edit: couple typos |
@kardianos This is all brought on by bugs in dependencies. If someone discovers the effects of a bug, does work trying to debug it, and the information is captured but it's not exposed until you use a releaser tool the information isn't being used in a needed context. When |
Most builds won't require dependencies from outside the local module cache, so either you'd be adding a lot more network latency to typical Seems better to have an explicit “yes, check the network for warnings” step, so that you can run it and be confident that there really aren't any warnings (rather than “well, if I added something new maybe it will warn me...”). |
@bcmills doesn't this depend on implementation detail? A few thoughts, quickly thrown together and off the top of my head:
Just some ideas around the experience. |
proposal: create a mechanism to report issues discovered in package dependenciesThis proposal is similar to #24031 (comment) but rather then for reporting a module's own bugs, this reports problems with the current module interacting with dependent module versions. There are roughly two general ways we could solve this:
While I don't have any concrete design specs, I do have a few ideas. They are: ... Edit: to be clear, I'm trying to re-cap what I understand from the above conversation. This is not my proposal. |
proposal: inform the developer of any stated version exclusion used by dependencies at build timeThis relies on the previous proposal XXX for fetching and reporting the list of modules. This pertains to the UX. Whenever a One advantage of bundling it in with Edit: to be clear, I'm trying to re-cap what I understand from the above conversation. This is not my proposal. |
The workflow I'm envisioning for CI tools is, roughly:
The That doesn't require any annotation mechanism beyond issuing a patch release with an exclusion in the |
@bcmills If I'm running a SaaS where the internals of the app code are private why do I want to use |
If you're running SaaS where the internals of the app code are private, then API incompatibilities should be nonexistent: you should have only binaries and internal packages anyway. You still care about detecting incompatibilities among the other modules you use. That said, perhaps there should be a way to tell |
Consider the following case where you have an app with a dependency on a module (modA) that has a dependency on another module (modB).
App --> modA --> modB
modB is released with a bug. For the examples sake, the bug causes goroutines to not be garbage collected and the number to continue to grow. This bug has been experienced in a real world application.
The developer of modA realizes this bug exists and sets the minimum version to the last stable release that does not contain the bug.
The developer of the App decides to update the dependencies to the latest releases (e.g.,
go get -u ./...
). Alternatively, the apps developer could import a second dependency (modC) that also depends on modB but at the latest release because they did not catch the bug. Some bugs don't show up on tests but rather in long running situations which is why I choose the goroutine example.There is currently no way for the author of modA to pass along information that modB has a bad releases. We need a way to communicate that information for those periods where that release is in the wild and one to use.
Existing tools like glide and dep let you say not to use a release. This is idea shows up in most other languages dependency management as well (e.g.,
!=1.2.3
).An idea was suggested, rather quickly and off the cuff, by @rsc to setup a web service to hold the information on buggy versions that should not be used. There are a few constraints that make this idea difficult:
This is a problem because of two things:
How will the Go toolchain handle this situation?
The text was updated successfully, but these errors were encountered: