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: get -u fails partially first time, succeeds second time when dependencies were refactored #9224
Labels
Milestone
Comments
This is an actual problem that has happened recently, see shurcooL/Go-Package-Store#27 where two people reported running into it. I've also run into this myself for other people's Go code occasionally (but ignored it at the time because running |
dmitshur
added a commit
to shurcooL/go
that referenced
this issue
Dec 9, 2014
You might have to run `go get -u` twice, sorry about that. I've opened issue golang/go#9224 and hope it will be resolved someday. According to godoc.org/github.com/shurcooL/go/gists/gist5892738?importers there are no other users. Make the previously manual test into an automated one.
CL https://golang.org/cl/12192 mentions this issue. |
dmitshur
added a commit
to shurcooL/vcsstate
that referenced
this issue
Dec 27, 2015
You might have to run `go get -u` twice, sorry about that. I've opened issue golang/go#9224 and hope it will be resolved someday. According to godoc.org/github.com/shurcooL/go/gists/gist5892738?importers there are no other users. Make the previously manual test into an automated one.
dmitshur
added a commit
to shurcooL-legacy/Conception-go
that referenced
this issue
Mar 21, 2016
You might have to run `go get -u` twice, sorry about that. I've opened issue golang/go#9224 and hope it will be resolved someday. According to godoc.org/github.com/shurcooL/go/gists/gist5892738?importers there are no other users. Make the previously manual test into an automated one.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Overview
In certain (reproducible and predictable) situations, running
go get -u
will partially fail the first time, but succeed the second time. During the first run, it will succeed to update the repository, but fail to build while printing an erroneous error message about a missing dependency. During the second run, everything will succeed.This happens when Go code is refactored in a way so that one Go package that was previously imported ceases to exist, but it is also no longer imported hence the Go code is valid. For example, if a package that was previously imported is merged into another, or if a package is renamed and now has a new import path.
This is a problem because it hinders ones ability to refactor Go code. We now have ever-more-powerful refactoring tools like
gorename
that are able to help with refactoring. In its todo list is the ability to rename import paths. That ability is already present within another toolgovers
today. Being able to seamlessly improve and refactor Go code is important to allow it to get better. No one can come up with the perfect version the first time around, so it's possible they'll want to refactor after using the package for some time and having a better vision. An implementation detail limitation ofgo get -u
should not hinder that.What does
go version
print?go version go1.4rc2 darwin/amd64
What steps reproduce the problem?
In order to prepare a (minimal) environment where the problem can be reproduced (i.e., it happens when
go get -u
runs and there are updates available), you need the following preparation steps first:go get -d -u github.com/shurcooL/go-get-test-cmd
. It has only one external dependency repogithub.com/shurcooL/go-get-test-lib
which will also be fetched.$GOPATH/src/github.com/shurcooL/go-get-test-lib
folder.git reset --hard master^
to hard resetgo-get-test-lib
repo to previous commit. This will make it so that when we rungo get -u
there will be one update available.go-get-test-lib
repo has 2 commits. We need to pretend that at this time it only has 1 commit, and a new commit is made available later on.That simulates a scenario where a user has an existing version of your Go package and its dependencies, and you decide to refactor one of the dependencies in this way:
https://github.com/shurcooL/go-get-test-lib/compare/master^...master
Now, you are ready to reproduce the problem, follow these steps:
go get -u github.com/shurcooL/go-get-test-cmd
.ls $GOPATH/bin/go-get-test-cmd
and see that it failed to build.go get -u github.com/shurcooL/go-get-test-cmd
a second time.ls $GOPATH/bin/go-get-test-cmd
.What happened?
What should have happened instead?
Everything should've succeeded the on the first run of
go get -u
.Please provide any additional information below.
This happens when Go code is refactored in a way so that one Go package that was previously imported ceases to exist, but it is also no longer imported hence the Go code is valid. However, when a user runs
go get -u
to update, it first parses the previous code to get a list of Go packages, then updates repos and does not re-parse the updated code (to find that a certain dependency is actually no longer imported) before returning an error that the previously imported package doesn't exist.In the reproduce steps above, I used a refactor example where previously
liba
andlibb
were used, butlibb
is merged intoliba
. I would imagine the same issue would happen iflibb
were renamed tolibc
(and imported under new name) for example.This likely affects
/internal/
Go packages too. That means one can not use the argument that "you should not be removing old import path since someone might be importing it" for/internal/
Go packages as they're guaranteed not to be imported by anyone else, and you should be free to refactor them.Workarounds:
go get -u
twice and ignore (possible) problems on first run.go get -u
after 2 months and encounter this problem, it just reduces that chance.The text was updated successfully, but these errors were encountered: