-
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: satisfy import by adding require of available replacement #26241
Comments
I just came across a specific use case for this: when developing against submodules within the same repository. It's useful to be able to modify and use code within the submodule (and from other external modules) before pushing and tagging the changes. In fact, it's important for any development process when developing across modules and without a network. |
I feel that the require with a real version requirement is still neccessary if both modules may be required by a third. Otherwise, the solved version may be too low because it wasn't expressed by the go.mod. My team has been using replaces with relative paths to great effect on repos which contain multiple modules to allow unpublished changes to be immediately used elsewhere by the repo. However, it does become a pain point as each individual module being included (even transitive modules which are not in the requires) need such a statement. One idea I am thinking of is to allow "wildcard replaces" to avoid dozens of replace statements, rather, this would only need a single "replace github.com/my/proj/* => ./" (or any other relative path back to the repo root) in each module's go.mod. Then, github.com/my/proj/a and github.com/my/proj/b would be both be replaced by a relative path, along with any future required dependencies with the shared package prefix. |
Are you referring to different major version requirements here? |
No, the minor or patch. |
Then I don't follow, because without the The one case I think we would need to be distinguish is different major versions. Maybe this points to us being able to specify replace statements with only the major version, e.g.:
which would leave a require for |
When the tool only sees and can update to publicized versions of a module, and when you have multiple modules in the same repo which reference each other as dependencies, it is not possible to update one module in a backwards-compatible way and use the new features or bug fixes in another module of the same repo without pushing and tagging the module. The replace works around this, however you must be careful that you still publish and bump the version of the dependency, and the required version of the dependency used in other modules of the repo, before publishing other versions (otherwise, to your importers, the replacement doesn't happen and the required version would be too low). On a large repo with many modules which all depend on each other in complex ways, this makes the module versioning workflow untenable without replacements, even without ever making a single breaking change. I haven't yet hit any situations where I needed or wanted to replace an older major with newer major version, and I don't think that would be something worth pursuing. Replacements only apply locally to the module you build directly from, which would cause my package imports to refer to older and incorrect packages, and would not match the import that consumers of my modules should use. |
@rsc the one case that might make this more important to include for Go 1.11 is where the dependency is against a major version number e.g.
|
Just a quick comment that people continue to run into this (in Slack, mailing list, etc.), so seems worthy to at least consider doing something here... |
@thepudds Yes, I think this is one of the two most duplicated issues with modules. It seems pretty clear that we need to fix it by 1.12. 🙂 |
I think I may have run into a manifestation of this problem while trying to solve a predicament I'm in, which I wrote out here. Let's say I have three files (Sorry I couldn't put this in a gist, it didn't like having a directory in the name of one of the files):
package main
import "abc.xyz/bar/example/inner"
func main() {
inner.Success()
}
package inner
import "fmt"
func Success() {
fmt.Println("success!")
}
module abc.xyz/foo/example
replace abc.xyz/bar/example => ./ Theoretically this setup could work, the dependency solver could see that In that reddit post I linked I described in greater detail how this would help. The TLDR is that anyone who has a package like |
@mediocregopher if you'll excuse the bullet point form of response:
|
@myitcv no problem! Thanks for responding
I don't believe anyone is, I did the v3.0.0 tag just to test something out, I should probably delete it though so no one makes that mistake though.
That was supposed to be a simplified use-case of the actual one I'm running into. I didn't want to drive the discussion too far off-course, but maybe it just added confusion. My actual problem lies in that So I can only do one or the other right now, and I'll have to just leave it
Hopefully that clears it up a bit, and sorry if this is driving the topic too far off course. |
This is not completely accurate. It will break for people using You could always do the rename, leave current Let's continue the conversation in https://github.com/mediocregopher/radix.v3 however to avoid sidetracking this issue on the specifics of your case. |
I'm not sure whether this will make 1.12 — I didn't get to a fix before the freeze, and it's not obvious to me whether the fix will be small enough to make the cut after. |
Change https://golang.org/cl/152739 mentions this issue: |
As it turns out, the fix was small enough. 🙂 |
Change https://golang.org/cl/153157 mentions this issue: |
Updates #26241 Change-Id: I8ffac13d9cc1ee4d4de8fcd2042a7fa60fca567b Reviewed-on: https://go-review.googlesource.com/c/153157 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Fedora 30 ships golang 1.12 which has an important fix for handling non-VCS based go modules: golang/go#26241 Projects like Kubernetes specify "sub-modules" such as k8s.io/api, which point to a path within the repo. In previous version, golang tries to fetch those from the Internet causing unnecessary delays. Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
#25053 and at least one other issue I've lost got tripped up by having to write both a replace and a require statement to get at local code. I wonder if we could avoid that confusion by having the import satisfier check for a relevant replacement in go.mod and if one exists, try to use it directly instead of doing the network lookup at all. If the replacement is version-less then we could make up a version like v0.0.0-0.
The text was updated successfully, but these errors were encountered: