-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: should default to use mod=vendor flag if the vendor folder exists #27227
Comments
@JeremyLoy note that while the default is to ignore the vendor directory, you can relatively easily change that behavior with an environmental setting This is a new environmental variable in Go 1.11, where one of the justifications for introducing it was specifically to make it easier to opt in to vendoring given some people would want that regularly (e.g., see #26585 or https://go-review.googlesource.com/c/go/+/126656). From the doc:
One other quick note is that those downloads end up in a shared cached (so even if you don't opt-in to vendoring, it cuts down on how many times you would end up downloading dependencies). |
I strongly agree with this proposal. If a project committed a vendor folder, this is a strong indicator that vendoring should be used by default. I can’t think of a workflow in which a developer would commit a vendor folder but prefer other developers to ignore it by default. In other words, if a project decides to use vendoring, then the whole go tool should default to use vendor first, and download/cache only if not there. |
By the way, this is part of what GOFLAGS was added for: https://go-review.googlesource.com/c/go/+/126656 |
GOFLAGS isn’t the right solution here. This is not a per-user / per-computer decision like “add debug flags”. This is a per-project decision that should affect all users building it. Currently, if a project uses vendoring, there is no way to let all builders use vendoring by default. |
While To put it bluntly, Github is not an artifact repository. At any given time, a repository owner can either
To avoid any of the above damaging your project, vendoring is a necessity, and should be treated as a first class citizen in the There seems to be a rush to remove EDIT: coincidentally, I found out the official Heroku build pack for Go uses this very workaround. It seems like this really should be the default case. |
But we're talking about working in module mode here, correct? Or by "currently" do you mean GOPATH-mode? Because vendoring as a "first class citizen" continues to work in GOPATH mode, it's just that in module mode it is not the default.
There was a similar discussion over at https://twitter.com/_myitcv/status/1033824806930534400. Vendoring (as it was and still is in GOPATH mode) is one way of dealing with this problem. As I suggested, having a separate repo as a module download cache is another, which actually have a number of derivative benefits. As you say, Athens (or indeed anything else that talks the published module protocol) are also solutions, solutions that in some cases try to solve even bigger problems.
I don't think this is quite accurate. In GOPATH mode (the default), vendoring works exactly as it has done up until now. In module mode (the opt in) the behaviour changes. So for the record, in module mode I am against what is being proposed here, not least because of what I wrote above, but also because it confuses/complicates the rule that "vendor directories are totally ignored in module mode" which is particularly important when it to dependencies. |
Yes, I'm speaking about module mode. The point is that "not being the default" for projects that uses vendoring (that is, projects in which developers went through the process of calling
Thanks, but that is largely suboptimal. It requires a custom installation step to be repeated for each user, and also handle and commit binary files into the SCM which are harder to handle (especially with git) and review.
I fail to see how Athens solves the needs of people using vendoring. AFAICT Athens helps with the issue that people can remove/sell GitHub repositories to other parties, and this can break builds and/or even cause security problems. This is not what vendoring is after. Vendoring is required in workflows that need 100% of the source code for a project committed under a single SCM, so that it can be fully audited, versioned, and built completely offline, without any dependency on any third-party service or installation. I deliver code to enterprises that want the code to be complete, not depend on third party services, and fully versioned with their existing code tracking tools. Vendoring solves this problem; Athens doesn't seem to.
You seem against adding a feature for people that need it for the sake of orthogonality. If you don't want or need vendoring, there's nothing in vendoring support that creates problems to you. Just use modules, your download cache, Athens or whatever you prefer. You will never have a |
That's not at all “obvious” to me. In fact, the current structure (in 1.11 module mode) is exactly the opposite: if a developer goes through the steps to commit vendored dependencies in module mode, it could just as easily be because they want to give their users the option to build using those vendored dependencies as an alternative to using modules. Giving their users an option is not at all the same thing as providing an explicit recommendation. Moreover, |
I'm not sure that we can deduce anything from what Go 1.11. It's pretty obvious that vendoring wasn't even plan of the original module plan, and has been retrofitted at some point later in the process given different pressures. What we ended up with is basically non working for many vendoring use cases, hence this bug (and others). Rather than discussing hypothesis made by people that don't vendor, I'd rather somebody that does use vendoring in production shows up and say that they absolutely don't want vendored modules to be used by default unless explicitly opted in (like Go 1.11 does), and explain us why with a small experience report. I for sure know this doesn't work for my use case as already explained in mine, and others have already chimed in.
That's perfectly fine for me at least. In fact, in my use case, vendoring support could go as far as completely subsuming the module download cache and/or |
That's kind of my point, though: you're requesting feedback from one particular subset (package maintainers that choose to use vendoring) and ignoring another (package consumers, who have no choice in the matter in We need experience reports from everyone — including package maintainers and consumers, and including both open-source and enterprise codebases. |
@JeremyLoy, could you give some more information about your use-case?
Vendoring is still supported in Go 1.11, both in |
Please remember that among our gopher values is to “be charitable”. The approach to vendoring in Go 1.11 does seem to have evolved with the implementation, but that doesn't mean it was “retrofitted”. A flag very similar to |
@bcmills I'm currently using Go for enterprise application development, so I can give an experience report for that. You'll have to find someone else for the package maintainer report. We currently vendor our dependencies using We vendor for a variety of reasons, many of which were already stated here, but I will reiterate them for clarity.
we also vendor tools such as gomock, goimports, swagger etc. Now to answer your questions:
no. because with the
no, quite the opposite in fact. I imagined that
yes. Having to set an environment variable or constantly add a flag is a bit of a nuisance, but not a game breaker. The biggest issue to me is that I expected go modules + vendoring to behave exactly like |
I'm sorry if it was borderline harsh, but anything related to "proposals" in Go often leads to a very frustrating experience, so much that I tend to steer away as much as possible from it and focus on where the community experience is vastly superior (eg: compiler development). This said, I still think the quoted sentence is factually true. It was clearly stated in Russ' first blogpost:
and has been repeated other times elsewhere. The vgo design didn't include vendoring; at some point, it was re-added to the picture, but there wasn't any discussion or attempt (at least that I could find) to rethink vendoring in the Go modules world. The fact that a default that doesn't work for people using vendoring was chosen, or that there are large overlaps between the vendor directory and the download cache is probably a consequence of not having fitted vendoring in the picture from day one. |
@rasky I think you are right that the initial set of vgo blog posts initially proposed dropping support for vendoring. However, there was then a fair amount of feedback from the community about the importance of vendoring. As far as I could see, that community feedback was clearly heard by the core Go team, which then resulted in the proposed plan being updated to actually retain support for vendoring with modules. The feedback was discussed in multiple venues, but this might have been the longest thread: https://groups.google.com/d/msg/golang-dev/FTMScX1fsYk/uEUSjBAHAwAJ ...where within a week or so of the initial vgo blog post, the core Go team had switched to proposing retaining vendoring support with vgo/modules based on that community feedback. In any event, sorry if my historical comments are not very interesting. A much more interesting question of course is what should the behavior be in 1.12+. |
Yeah, I can see that. Bear in mind that the module support in Go 1.11 is still preliminary: we know that it has some rough edges, and vendoring is one of them. I think it's important that we figure out a path forward, but it's not clear to me whether that will be to improve vendoring and better integrate it into module mode, or to improve the available module operations and deprecate vendoring entirely. I expect we'll try something in at least one of those directions for 1.12, but it's important that we have enough time to try out the improvements and make sure they work for those use-cases before they become the default. In particular, because vendoring support in module mode is pretty awkward in 1.11, I think it's important not to try to push it as a default: I don't think it's the right design point yet, and I don't want folks to start relying on a design that really needs more thought. |
@JeremyLoy has made some great points here why vendoring is really needed in the software we build. Without vendoring how are you planning to solve these points? Force everyone to host some caching/proxy thingy that would serve the dependencies transparently? What if some of the dependencies disappears and you don't have it in the proxy cache or anywhere else? This would force developers to fix/replace the dependency in their repository. However what if this is related to multiple versions with ongoing support? It would have to be fixed for all of them.. I'm really curious about your future solutions without the vendoring support that would satisfy the points above while at the same time not force us to manage extra things outside of the repository to successfully build our Go programs. |
That is a matter for a separate issue (perhaps #27618, and perhaps others as well). If you have specific requirements, please contribute an experience report describing both your use-case and how you address it today. (As I've said, it's not clear to me whether the solution will be to improve vendoring or to replace it, but experience reports will help either way.) The matter at hand for this issue is whether |
Is there a single experience report, email or comment on GitHub issue that describes a real-world workflow in which the current default is correct? I have not seen any. |
@rasky I don't think we have any experience reports for vendoring with module mode at all. As I've said repeatedly, I think it needs work before we can recommend any particular workflow. For now, if the module support in 1.11 doesn't work for you, don't use it. If you want to influence the future direction of module mode, you need to share your actual use-case instead of just arguing that what we have today doesn't work: your current criticism is not constructive. We already know that what we have today doesn't work for you: we need to know how to make that better. |
@bcmills I added a link to my comments (and by proxy, this issue) to the experience report page you referenced. If you want me to modify the experience report/submit it in a different way etc just let me know! |
My experience with the current vendor behaviour has been as follows: I've written a (partial) drop in replacement for git in Go, primarily so that I can use it on Plan 9 where there's no access to the real git client. A user requested that I vendor my dependencies so that it can be bootstrapped without @0intro's rc script hack, which seemed like a simple enough enough request so I decided to oblige. I copied the files to the vendor directory as I did to vendor with previous versions of Go and it didn't work. I ran "go mod vendor" which appeared to generate some ancilliary files for Go 1.11 like I support this proposal because the current Go 1.11 behaviour:
|
I think That's certainly not happening for 1.12, but it's still on my radar. |
Of those people using modules (because nobody is forced to use modules; modules will only become the default in 1.14) it is demonstrably the case that not everyone has to use As was stated before, for those people whose workflow has been broken/frustrated by a move to modules, yes, that is very unfortunate, but there are competing priorities here and limited resources. A large part of the reason the default will only be switched in 1.14 is:
It is extremely unfortunate at best that that the term "community" continues to be used as a stick by (non-Google) people who feel like they haven't been listened to. Combined with the hyperbole of "forcing everyone", "spending thousands of hours", "wait 6 months for modules to be fully baked": these arguments/points simply become less rather than more convincing to my mind. Contributing specific, constructive feedback/points is the way forward here. Please, let's all move forward on that basis. |
see #31857 |
I support the notion that having a vendor folder would look for dependencies there first, with a resulting error message to the developer that "hey, we checked your vendor folder, but your vendor folder is out of date/missing certain dependencies in Also, there does not seem to be a way to share the vendor folder across several packages in the same repository. For example, instead of |
The way that we deal with that is to create a mono-repo for any projects that are expected to interoperate and share |
@kliche the "shared vendor folder" you describe sounds just like a module cache, except for the fact that a module cache also know the exact version of you dependency. When you use "Go Modules" this is what you get today already. I can't see why you should add third party dependencies to your repo at all with the existing tooling around modules. |
I work on a project that uses a custom source code re-writer to re-write some of the dependencies before using them in a build and vendoring was the easiest way to achieve this. I don't even commit the vendor directory into VCS. It is re-created with (To elaborate on the re-writer, I use a tool to replace all references to protobuf package with gogoproto allowing me to use gogoproto with dependencies that use protobuf internally) |
Agree with the comments about this needing to be a project-wide setting, not a per-user configuration. Is there a reason that |
I stumbled upon this issue while googling and trying to understand why |
@amacneil @andreygrehov please see the very long thread above your comments; this is not a simple issue by any means. If you want to follow progress, see #27227. Asking the same basic questions asked in the original post again is just making the thread more unbearably long for everyone :) |
@mvdan thank you, I re-read this thread and to be fair it still does come across as if the Go team doesn't really understand this use case. However, after some digging through links I came across #33848, where it appears there is a concrete proposal to support automatic vendoring, which is great news. Hopefully others coming across this issue can also follow this new proposal. |
Closing in favor of #33848, which is a concrete proposal intended to implement the requested default behavior. (That proposal explicitly addresses the specific details and interactions that defaulting to |
Duplicate of #33848 |
Note that #33848 now has a prototype implementation for review. |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go version go1.11 darwin/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
What did you do?
go
, there are no files downloaded in$GOPATH/pkg/mod
.go run main.go
to run the application.What did you expect to see?
What did you see instead?
$GOPATH/pkg/mod
, despite the fact that the dependencies were vendoredI know this can easily be fixed by instead
go run -mod=vendor main.go
, but because the go tool is now being advertised as "context aware", I think this would be a good QoL change.The text was updated successfully, but these errors were encountered: