Skip to content
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: [modules + gopath] replace fails for subpackage - please save our beloved GOPATH #31365

FredFoo opened this issue Apr 9, 2019 · 4 comments


Copy link

@FredFoo FredFoo commented Apr 9, 2019

What version of Go are you using (go version)?

$ go version 1.12.2

Does this issue reproduce with the latest release?

I guess this is the latest release, afaik, humbly :)

What operating system and processor architecture are you using (go env)?

go env Output

What did you do?

in GOPATH/src

- mypackage
  - subpackage
- hlog

Using GOPATH I was importing hlog in main.go and subcode.go

import (

I started to convert to modules and run go mod init in mypackage and hlog, setting GO111MODULE=on for the future.

I edited go.mod in mypackage to show this for hlog:

require (
	git.private.home/Dumper/hlog v0.0.0

replace git.private.home/Dumper/hlog => ../hlog

What did you expect to see?

Would like to see mypackage compile.

What did you see instead?

subpackage/subcode.go:12:2: unknown import path "hlog": cannot find module providing package hlog

It seems that the information in the go.mod does not spread into subpackages, although go.mod nicely lists all dependencies, even the ones from subpackages.

Additional discussion

I am actually unhappy with the main feature of the GOPATH being eyed for chopping: the fact that you can refer to all local packages in src using a short import path. I think this is a really important feature to actually be able to build many projects. I dont even want to start writing down all the problems using url mapped importpaths for everything outside the current module scope. Just this one:

Imagine I would turn hlog into a url mapped import. If I need to make a change to this - because my team is responsible for it - I would start with forking it in our git repository and then what?

  • Refer to it with a path that contains my username?
  • Pull the dependency from the master repo and then checkout my fork, do my changes, push, pull request, wait for the changes to be merged, update the dependency, compile my code? Come on, that cannot be the your idea.

I would vote for a GO111MODULE=both: Imports are searched for in the GOPATH/src and in the modules cache. If imports can be found in GOPATH, they are excluded from module dependency management.

If I miss something and there is an article out there explaining why modules cannot be created in the GOPATH, please point me to it. I googled a lot, but no luck.


This comment has been minimized.

Copy link

@FredFoo FredFoo commented Apr 10, 2019

BTW, my current workflow is this now:

  • setup the environment using GOPATH
  • create an alias for the go command: alias gomod='GO111MODULE=on go mod'
  • initiate with gomod init
  • download deps with gomod download
  • create vendor directory using gomod vendor

Everything else like build or install is done using the normal go command.

If you introduce new or delete existing dependencies in your code, name them in your go file's import statement and then run

  • update deps with gomod tidy
  • update vendor with gomod vendor

So far I am happy with this, because I will get to use propper dependency management, witch can be automated, does not need additional tools like dep and gives me a simple way to a clean vendor directory.

But if you drop the search-for-imports feature of the GOPATH - me fucked! :))

@FredFoo FredFoo changed the title cmd/go: [modules + gopath] rewrite fails for subpackage - please save our beloved GOPATH cmd/go: [modules + gopath] replace fails for subpackage - please save our beloved GOPATH Apr 10, 2019

This comment has been minimized.

Copy link

@jayconrod jayconrod commented Apr 10, 2019

Hey @FredFoo, you'll need to include module paths in your import declarations. If you have a go.mod file in hlog, it should contain the line module git.private.home/Dumper/hlog, and you'll need to import that package with import "git.private.home/Dumper/hlog".

Avoid using replace directives for remapping imports. replace directives have two main uses: 1) you need to use a temporary fork of an upstream module (e.g., because you're waiting for a bug to be fixed) and 2) you want to use another module in the same repository at HEAD instead of a published version (useful for making changes in multiple modules with a single commit). In both cases, you need to import packages in replaced modules with the original import paths.

You can find more information at:

At this point, we're not going to make significant changes to the way modules work, so I'll close this issue.

@jayconrod jayconrod closed this Apr 10, 2019

This comment has been minimized.

Copy link

@FredFoo FredFoo commented Apr 10, 2019

@jayconrod, that is exactly what I was afraid of!
With GOPATH for more than 8 years it was fine to use import "hlog". I have used this package in nearly a every binary I wrote. And I have a number of other packages (libraries) that also would be checked out from my internal code repo if needed. I know that some people might say I should not work like this, but I some of them smoke and I dont tell them they need to stop just to satisfy my view of the world.

What you do is telling me that I should change hundreds of import statements in hundreds of files to use modules and the dependency management. And when GOPATH goes away should becomes must or all my builds fail.

And that is because you want me to forget what was the truth yesterday - hail GOPATH! - and only accept what you say is the truth today - hail Github!. I dont understand why this must be so imperative.

Say you come up with the idea you can get rid of the PATH variable in the shell, because you can always call a binary with the full path! I would say fine, you dont have to use PATH if you type fast and love typing - use export PATH="" and you get what you want. Why in the world would there even be a thought that the PATH feature has to be dropped and EVERYONE now has to type full paths to call binaries?

I dont get it. Thinking of the wave of unnecessary work coming up I feel sick. So I am asking why? WHY? If there is a blog post or whatever that helps me understand, please point me to it!

BTW, I know its not you personally, please believe me when I say I do not want to offend you :))


This comment has been minimized.

Copy link

@FredFoo FredFoo commented Apr 10, 2019

Oh, and regarding the bug that I seem to have found.

Would it not hit in the same way if I use the replace statement as intended? I would perhaps also not work for subpackages - at least the information you linked to and which I read before did not state anywhere that replace is not supposed to work for subpackages in your modules. Or should modules not have subpackages at all? Did not read about that either in those documentations.

So why close it if it is probably still broken?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.