I am new to go and working on an example code that I want to localize.
In the original main.go import statement it was:
import ( "log" "net/http" "" "" ) Now I have common and routers package in /home/me/go/src/myapp
So I converted the import statement to:
import ( "log" "net/http" "./common" "./routers" ) But when I run go install myapp I get these errors:
can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package Also, when I use common and routers instead of ./common and ./routers in the import statement, I get:
myapp/main.go:7:3: cannot find package "common" in any of: /usr/local/go/src/common (from $GOROOT) /home/me/go/src/common (from $GOPATH) myapp/main.go:8:2: cannot find package "routers" in any of: /usr/local/go/src/routers (from $GOROOT) /home/me/go/src/routers (from $GOPATH) How can I fix this?
49 Answers
Well, I figured out the problem. Basically Go starting path for import is $HOME/go/src
So I just needed to add myapp in front of the package names, that is, the import should be:
import ( "log" "net/http" "myapp/common" "myapp/routers" ) 5If you are using Go 1.5 above, you can try to use vendoring feature. It allows you to put your local package under vendor folder and import it with shorter path. In your case, you can put your common and routers folder inside vendor folder so it would be like
myapp/ --vendor/ ----common/ ----routers/ ------middleware/ --main.go and import it like this
import ( "common" "routers" "routers/middleware" ) This will work because Go will try to lookup your package starting at your project’s vendor directory (if it has at least one .go file) instead of $GOPATH/src.
FYI: You can do more with vendor, because this feature allows you to put "all your dependency’s code" for a package inside your own project's directory so it will be able to always get the same dependencies versions for all builds. It's like npm or pip in python, but you need to manually copy your dependencies to you project, or if you want to make it easy, try to look govendor by Daniel Theophanes
For more learning about this feature, try to look up here
Understanding and Using Vendor Folder by Daniel Theophanes
Understanding Go Dependency Management by Lucas Fernandes da Costa
I hope you or someone else find it helpfully
2You should have created your package with go mod init e.g. go mod init
Now in my-package you have a sub module called utils for example.
main.go utils |- randstr.go And your randstr.go looks like this:
package utils func RandStr(n int) string { // TODO: Generate random string.... return "I am a random string" } And then anywhere in your app you would use exported functions from the utils package like this, for example in main.go:
package main import ( "fmt" // "" is the module name at the // top of your `go.mod` "" ) func main() { fmt.Printf("Random string: %s\n", utils.RandStr(20)) } 3Import paths are relative to your $GOPATH and $GOROOT environment variables. For example, with the following $GOPATH:
GOPATH=/home/me/go Packages located in /home/me/go/src/lib/common and /home/me/go/src/lib/routers are imported respectively as:
import ( "lib/common" "lib/routers" ) 8an example:
in
./greetings, dogo mod initfrom another module, do
go mod edit -replace=go get
from the go tutorial
Local package is a annoying problem in go.
For some projects in our company we decide not use sub packages at all.
$ glide install$ go get$ go install
All work.
For some projects we use sub packages, and import local packages with full path:
import "
But if we fork this project, then the subpackages still refer the original one.
As in the question, the folder structure is:
/home/me/go/src/myapp └─ common └─ routers So go to myapp dir
cd /home/me/go/src/myapp Do
go mod init myapp This will create a go.mod file which lets Go know the name of the module myapp so that when it’s looking at import paths in any package, it knows not to look elsewhere for myapp
Then you can do the following in the code:
import ( "log" "net/http" "myapp/common" "myapp/routers" ) Now package common and routers gets imported.
The key is how you name your module in the following command
go mod init <TheNameGiven> Then refer the modules in the inner folder with,
TheNameGiven/folder I have found the best solution here... Read More
Try to change the package name with the go mod init command.
So, I have go 1.17, and I have the same import problem. My project directory is $GOPATH/src/myswagger/app-swagger-test. I ran this command into app-swagger-test dir:
go mod init app-swagger-test go mod tidy In my new go.mod file the package name is app-swagger-test. For example, this import was wrong:
import ( ... "myswagger/app-swagger-test/internal/generated/restapi" "myswagger/app-swagger-test/internal/generated/restapi/operations" ) So I removed go.mod and go.sum. And I ran next commands into app-swagger-test dir:
go mod init myswagger/app-swagger-test go mod tidy After that all imports in the project were imported successfully. In the new go.mod file the first line is:
module myswagger/app-swagger-test Maybe this information is common, but I did not find it. Thanks!