-
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: provide advice for authors of existing packages with version v2.0+ #25967
Comments
Quoting https://research.swtch.com/vgo-module:
Can't vgo leverage the already existing v2.0+ git tags released on Github? Wouldn't it "just work" for packages that don't have any complex transitive dependencies? I just hope that migrating monorepos from golang/dep to vgo (can we expect a migration tool, right?) will be very straight-forward. I hope we won't be blocked by some v2.0+ packages that "just work" but are not really maintained anymore and thus "not ready" for vgo. Any guidance / feedback appreciated. Thanks! |
Have a look at #25810 (comment) |
@VojtechVitek sorry, I was away from keyboard when I sent that last message, hence it was brief. Here is a complete example that I previously posted to Create a module using the
Now because, at the time of writing,
we need to
Now do a build to check all is good:
And check the contents of
|
Hi @myitcv,
This is super confusing to me and I think it will cause a lot of confusion in the Go community. Migrating from golang/dep, I will have to start using some v.0.0.0- pseudo versions instead of v3.3.2, just because vgo can't work properly with git tags. Well,
But other vgo command cannot. The version gets "reverted" to Maybe there's no workaround for this from the vgo's perspective. But in that case, would it make sense to provide some guidelines for the v2.0+ pkg authors and consumers to avoid any confusion? I'm not the only one not getting it right away, see go-chi/chi#302. cc @rsc |
Just to be clear, this is only required under the conditions listed in the bullet points that preceded it (reordered):
As soon as the project is converted to a module, then you're set - no pseudo-versions required. Because when chi is converted to a module, the import path becomes package main
import (
"net/http"
"github.com/go-chi/chi/v3"
)
func main() {
r := chi.NewRouter()
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("welcome"))
})
http.ListenAndServe(":3000", r)
} and your
As was observed in go-chi/chi#302 (comment):
Therefore, any "old" |
Hmm, it's unlikely that upstream v2.0+ packages will stop supporting go 1.10 anytime soon by changing the internal import paths to "/v2" etc. Thanks for clarification! |
@myitcv Paul, would you mind taking a look at go-chi/chi#327 (review) and advice what should be done in order for project authors to support both new (vgo) and old (module unaware) versions of Go assuming the project
Much appreciated! |
@VojtechVitek how many Go versions do you need to support? With 1.9.7 and 1.10.3 now out, any project supporting up to the two last Go versions (which I think is a majority) should be able to switch to Go modules soon. The only potential problem I see is people still using old minor releases like 1.10.2. This is why I'm holding off for a few weeks before porting my v2+ projects to Go modules. I'll probably do the switch once 1.11 is out, at which point backported support will have been out for two full months. If you need to support the latest three major Go versions, waiting until 1.11 is out should also do the trick. This obviously doesn't scale past three major Go versions, but hopefully the set of v2+ packages with that constraint is very small. |
@VojtechVitek as @mvdan points out, if you are happy only supporting Go 1.9.7 (or later) and 1.10.3 (or later) from the 1.9.x and 1.10.x series respectively, and of course Go 1.11 and later, and your project is |
I'm not happy dropping support for Go <=1.10.2, <=1.9.6 and 1.8.x for a long long time. I'm talking year+, maybe until 1.12 is out. Go was always about backwards compatibility ... and now we just break stuff because vgo can't support the existing git tags properly .. and requires new "module" notation instead :( |
Are there particular cases of users not being able to upgrade bugfix/minor versions? If I was maintaining a large open-source project and a bug was reported with Go 1.9.0, my first response would be for them to try with the latest 1.9.x. This is how I understand Go supports older versions. For example, when it is said that the last stable release recieves important bugfixes, that only concerns the latest bugfix version. I wouldn't consider 1.9.0 maintained at this point. Having said that, I understand that it's frustrating that Go modules don't play nice with v2+ projects. Although, I'd note that this is not a breaking change. You are not forced to start using a |
Go 1.10.2 was released 2 months ago as a stable version. We can't just suddenly break the stable builds "just because of vgo support". Personally, I can upgrade few monorepos and I'm done. But not everyone is that lucky.. they just want to upgrade their dependencies to the latest minor/bugfix version to get bug fixes and security patches. That's it. They don't want to worry about some "hidden" difference between Go 1.10.2 and 1.10.3 and spend hours debugging the issue.
Sorry, but that sounds wrong. Backward compatibility is Go's promise, one of the pillars of the language. Any version in the 1.9.x range should behave the same. Quoting from https://blog.golang.org/versioning-proposal:
Yes, we're not forced to do so.. as long as everyone in the community understands they should use Why am I bringing this up? I'm hoping someone will explain the best practices, a guideline for both package authors & consumers. I'm hoping Go will stay stable for the sake of the language and the community. |
As I said before, I'm also on the same boat with a couple of v2+ projects, and I too would like there to be a "best practices" or "transition guide" document published. All I am saying is that I don't consider this a breaking change - it feels like more of a temporary annoyance for part of the libs out there.
Depends on what you mean by "same" :) The only promise made is backwards compatibility. There is no promise that goes forward. If your package works with 1.9.5, there's no guarantee that it will work with 1.9.1. Of course, it is possible for packages to sasy "we support all 1.9.x versions". My point was that, in practice, most projects out there only test against the latest 1.9.x, hence 1.9.0 is in a way unsupported by much of the community. |
This is not strictly true. As outlined above the command is actually:
The command refers to a specific, released version.
There is absolutely nothing that requires you to make This feels like a totally satisfactory story for Just to note, /cc @rsc @bcmills in case there's anything they'd like to change/add. |
Regarding:
And the concern:
I think that has changed recently in CL 124384? Here is a snippet from the CL:
And here is a related snippet from the latest 'go help modules' (from tip today):
So if I am following this particular issue, it sounds like if go-chi does not currently have have a go.mod file but is already at v3.3.2 tag, the require for your 'hello.go' example would no longer end up being a v0.0.0 pseudo-version (which was one of the concerns raised above by @VojtechVitek), and instead would end up being a slightly friendlier:
which is friendlier than the older behavior of ending up with something like:
Here is the new behavior in slightly more detail:
And the go.mod ends up after the build as:
|
Just a small remark, you even don't need to run
|
Hi @mwf, thanks, and good clarification. I had thought part of the example cited here was to specifically use v3.3.2, but given v3.3.2 is currently the latest semver tag for go-chi your comment makes sense (and the original issue reported here was more about "how can pre-existing v2+ packages work at all?"', vs. the "we want to use v3.3.2" was added as a later example). |
@thepudds @mwf Thanks for letting us know about the new So, as far as I understand, the |
That sounds like a very reasonable choice for the go-chi project. I still feel, though, that the more general original issue opened here isn't fully resolved in terms of wanting advice for maintainers of existing v2+ projects. At the risk of writing something wildly wrong, I am going to take an initial attempt at a more comprehensive answer, and I'm hoping someone like @mwf, @myitcv, @mvdan, or @bcmills can jump in with corrections. (In general, there has been a large amount of information written about vgo/versioned modules, but it has also been evolving and tough to track the various changes and what the current advice might be). Apologies in advance if this just ends up being noise, and this could certainly be written better and more succinctly, but in the interests of providing some grist for the mill and trying to move the ball forward, here is a rough draft: Go 1.11 Versioned Modules: Migration and Compatibility Considerations (DRAFT)The Go contributors are focused on providing a smooth migration from prior dependency managers and prior Go versions. Part of the strategy is to allow for phased adoption. Different projects are expected to opt-in at different paces, and packages defined as Go 1.11 modules can be consumed by pre-1.11 Go toolsets if the proper strategies are followed. General migration strategies for v0.x.x, v1.x.x, and v2+ projectsSome strategies for migrating to Go 1.11 modules and supporting older Go versions include:
edit: I had written this overall comment (including options 3 and 4 here) during the vgo period prior to Go 1.11, and at that point in time option 3 or 4 might have been more reasonable, but now that Go 1.11 has been released, I don't believe that either option 3 or 4 would typically be recommended, and hence the Additional strategies for v2+ projectsFor existing projects that are already on v2.0.0 or higher, the above strategies (such as using The primary issue is that v2+ projects that adopt Go 1.11 modules will update their import paths to respect semantic import versioning, with the major version now appearing within the path itself. (In contrast, this issue does not apply to a v0.x.x or v1.x.x Go 1.11 module, because semantic import versioning leaves the import paths unchanged for a v0.x.x or v1.x.x project). For example, an older Go version such as Go 1.8 does not understand how to properly interpret a There are currently three primary solutions for supporting older Go versions in a project on v2 or higher:
As additional experience develops with versioned modules, additional solutions might arise from the community. If you are willing to restrict support to Go 1.9.7+, 1.10.3+, and 1.11+, the additional mechanics to release a v2+ module are as follows (using v2.0.0 as the example):
If instead you would like to support even older Go releases than Go 1.9.7+, 1.10.3+, the additional mechanics to release a v2+ module are:
Finally, even if you chose not to opt-in to Go 1.11 modules now, please start using semantic versioning to tag your releases if not already doing so. This will help the overall ecosystem evolve more smoothly. |
@marwan-at-work had a similar question: “Should package authors with existing v2+ versions bump the major version again when adding a module definition?” I'm planning to discuss with @rsc when he gets back and will post some advice here. |
Our conclusion was that “changing the import path” is definitely a breaking change, and authors with existing |
I think that upgrading a major version only to add support for Go modules is quite severe. Major versions should be bumped for (major) changes in the library interface, not for an administrative detail like adding Go modules (which has nothing to do with the functionality of the code). As upgrading to v3 is not desirable for me, and v1 has already been phased-out (and will not support Go modules), I'm not sure how to proceed with adding support for Go modules. I was at one point convinced that the What is the advice you can give when bumping a major version is not an option, regarding releases, contents of |
@tdewolff from the client perspective, you need to @tdewolff I advice to ignore |
The support for |
@bcmills |
update; that conclusion is available at; https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher |
@komuw I'll one up this and I'll argue that it is dangerous for the solution to such a serious issue be a "by convention" best practice that you must have prior knowledge of and hidden behind a wall of documentation. I will argue that:
|
Utilizing some "version recommendation" features proposed in this issue I think would at least solve 2 in sort of a "two birds one stone" way. #26420 Still sticking to my guns about 1 though ;) |
@CameronAckermanSEL, it is possible to add module support without incrementing the major version. However, the migration process is a bit more delicate: you end up needing to leave forwarding packages at the old import path to ensure that users in Since the package import paths in a So incrementing the major version is, strictly speaking, just a recommendation. It's easier for users and maintainers to reason about, but it's not the only possible approach. |
@bcmills thank you very much for correcting my assumptions, I appreciate this observation because it helps me better understand some of the limitations behind a core prevention measure in the tool. That said, after chewing on it this morning, it seems to me that the damage caused by flubbing it is so severe that perhaps it should just increment the major revision as a low hanging fruit fix. But at the same time, there's probably a better solution for this issue. I do think this is an extremely scary behavior and it makes me nervous to consume packages because I'm not sure if they've opted in correctly. |
So I think we're okay. |
Hi,
I was testing vgo the other day, trying to import some 3rd party dependencies that have version v2.0 or higher released on Github, but I couldn't figure out how.
Example:
Given github.com/go-chi/chi has latest version v3.3.2 released as a git tag on Github,
I'd like to import
github.com/go-chi/chi/v3
in my project, develop against it and eventually vendor it viavgo vendor
.But since github.com/go-chi/chi didn't release a v3 module yet, I get this error:
vgo found version v1.0.0 but couldn't find "v3" subpkg. So I added an explicit version to my go.mod file and tried again:
running vgo again caused a silent side effect:
Hmm, seems like vgo doesn't see any v2.0+ tags? After reading some more blog posts on https://research.swtch.com (since
vgo
CLI help didn't seem to be very helpful / novice user friendly), I confirmed with:Now, I might be missing something, but it's not really clear to me how can I import v2.0+ or v3.0+ of a package (should I say module?) that I don't have any control over and "is not ready yet".
Are there any guidelines for package consumers about this? Are there any guidelines for package authors? I couldn't find anything useful neither in research.swtch.com/vgo-module, nor in the accepted proposal or in the wiki.
// EDIT:
Ahaa, so I can list v3.0+ tags. But how do I use them in my monorepo properly?
The text was updated successfully, but these errors were encountered: