so here is what my directory is:
go
|-src
|-ppppppSample
|-newFolderOne
|-firstSample.go
|-hello.go
|-go.mod
and here is the content of hello.go
package main
import (
"fmt"
jjj "ppppppSample/newFolderOne"
)
func main() {
fmt.Println("start to test")
fmt.Println(jjj.FirstVVVV)
}
here is the content of firstSample.go
package newFolderOne
var FirstVVVV = "Im first SSSSSSSSSSSS"
and here is my go.mod's content
module mmmmmppppp
go 1.15
when giving it the cmd go run hello.go, the terminal came out with like this:
D:\Users\eien_zheng\go\src\ppppppSample>go run hello.go
hello.go:5:2: package ppppppSample/newFolderOne is not in GOROOT (C:\Go\src\ppppppSample\newFolderOne)
So here is my question:
(since I'm new for golang, I wish you guys could understand and tolerate some of my misunderstanding)
According to my understanding to Go module (maybe it's wrong), the Go module's function is gonna let some kind of online resource be downloaded to the directory GOPATH/pkg/mod instead of existing in GOROOT.
No matter which directory your project in, your project can still import those resource from GOPATH/pkg/mod if you init Go module.
But!!, in my understanding, it still can use package system to import package around project directory, in the meantime import online resource by Go module system.
How is that when I do (mod init) for hello.go, then it loses the (basic package import function) for this project?
|--src
|--sample
|--newFolder
|-firstSample.go (package xyz)
|--hello.go (package main import(xyz "sample/newFolder")
|--go mod (module sample go 1.15)
go mod should reference the root folder , here the root folder is |--sample
module sample
go v1.xx
inside hello.go;
package main
import ( xyz "sample/newFolder")
and make sure exported functins or variables use camelCase aka starts with BlockLetters.
Import packages within a module using the module's path:
package main
import (
"fmt"
jjj "mmmmmppppp/newFolderOne"
)
...
Run it on the Playground.
Related
i am sure this has been asked many, many times: »How can i create and manage my go-packages locally without for example github ?«
I need to convert a couple of tools that were written in Perl to golang and i am fighting with golang's package management, simple example:
I wrote the main-package, containing the main function and a couple of other functions.
Now i want to move a group of functions into another package:
Created another package in the same directory and moved the group of
functions there
Built the package and the binary-file was created
Tried to import this package into the main package and miserably
failed. "PackageName", "./PackageName" "[fullpath]/PackageName" all
fails
For starters: How can i import a package from the local file-system?
Run go mod init <module_name> in the dir where you want to store all your code.
Example: go mod init auth-api
This will create a go.mod file in your root folder.
You can create a separate folder for each package.
Your dir structure looks like this.
package_1
-- file_1_1.go
-- file_1_2.go
package_2
-- file_2_1.go
-- file_2_2.go
-- file_2_3.go
main.go
go.mod
Here package_1 contains the file_1_1.go and file_1_2.go. Start these files with package package_1
Ex:
// file_1_1.go
package package_1
import "fmt"
func SayHelloFromPackage_1(){
fmt.Println("Hello from Package 1")
}
Now you can use that function in main.go:
// main.go
import "auth-api/package_1" // auth-api is our module name (go mod init auth-api)
func main() {
package_1.SayHelloFromPackage_1()
}
I'm following tutorials and I think I may have missed something.
I have a Go project located at:
/Users/just_me/development/testing/golang/example_server
The contents are:
main.go
package main
import "fmt"
func main() {
fmt.Println("hi world")
}
I have a ~/go directory.
go env shows:
GOPATH="/Users/just_me/go"
GOROOT="/usr/local/Cellar/go/1.12.9/libexec"
I installed the suggested packages in VSCode.
When I save my main.go I get:
Not able to determine import path of current package by using cwd: /Users/just_me/development/testing/golang/example_server and Go workspace:
/Users/just_me/development/testing/golang/example_server>
How do I fix this?
Since your package is outside of $GOPATH, you may need to create a module file.
You'll need to init your go module using
go mod init your.import/path
Change the import path to whatever you like.
This way you set the import path explicitly, which might help fix it.
The resulting go.mod file looks like this:
module your.import/path
go 1.14 // Your go version
So if the go.mod file is in the same directory as a main.go file, you can now import submodules from it:
E.g. main.go:
package main
import (
"your.import/path/somepackage" // Import package from a subdirectory. This only works if `go.mod` has been created as above
)
func main() {
somepackage.SomeMethod()
}
And in somepackage/whatever.go:
package somepackage
import "fmt"
func SomeMethod() {
fmt.Println("Success!")
}
if you are using vs code, check if the go and code runner extensions are enabled, if enabled, try disabling and enabling again, and if not, install and enable, and download all requested packages.
I'm trying out Go's new modules system and am having trouble accessing local packages. The following project is in a folder on my desktop outside my gopath.
My project structure looks like:
/
- /platform
- platform.go
- main.go
- go.mod
// platform.go
package platform
import "fmt"
func Print() {
fmt.Println("Hi")
}
// main.go
package main
import "platform"
func main() {
platform.Print()
}
go build main.go tells me
cannot find module for path platform
Let me define this first modules are collections of packages. In Go 11, I use go modules like the following:
If both packages are in the same project, you could just do the following:
In go.mod:
module github.com/userName/moduleName
and inside your main.go
import "github.com/userName/moduleName/platform"
However, if they are separate modules, i.e different physical paths and you still want to import local packages without publishing this remotely to github for example, you could achieve this by using replace directive.
Given the module name github.com/otherModule and platform, as you've called it, is the only package inside there. In your main module's go.mod add the following lines:
module github.com/userName/mainModule
require "github.com/userName/otherModule" v0.0.0
replace "github.com/userName/otherModule" v0.0.0 => "local physical path to the otherModule"
Note: The path should point to the root directory of the module, and can be absolute or relative.
Inside main.go, to import a specific package like platform from otherModule:
import "github.com/userName/otherModule/platform"
Here's a gentle introduction to Golang Modules
I would strongly suggest you to use go toolchain which takes care of these issues out of the box. Visual Studio Code with vscode-go plugin is really useful.
Problem here is that Go requires relative paths with respect to your $GOPATH/src or module in import statement. Depending on where you are in your GOPATH, import path should include that as well. In this case, import statement must include go module path in go.mod
GOPATH
Assume your project resides here:
$GOPATH/src/github.com/myuser/myproject
Your import path should be:
import "github.com/myuser/myproject/platform"
VGO
Assume your go.mod file is:
module example.com/myuser/myproject
Your import path should be:
import "example.com/myuser/myproject/platform"
As someone new to go I didn't immediately understand the accepted answer – which is great, by the way. Here's a shorter answer for those very new people!
In go modules/packages are expressed as urls that you import in your code:
import your.org/internal/fancy_module
But wait! My code isn't at a url, what's happening??
This is the cleverness of go. You pretend there's a url even when there isn't one. Because:
This makes including easier as no matter where your file is located the import uses the same url (the code stays the same even if the files move!)
You can have packages that having naming conflicts. So google.com/go-api/user doesn't conflict with the definitions at your.org/internal/user
Someday you might publish a url on GitHub and all the code will just work
That's all great Evan, but how do I import a relative path?
Good question! You can import by changing your go.mod file to have this line:
module fancy_module
go 1.16
replace your.org/fancy_module => ../path/to/fancy_module
Given the Golang Project structure
/
- /platform
- platform.go
- main.go
- go.mod
To access the methods or structs...etc (which are public) from local packages of /platform is simple, shown below
// main.go
package main
import (
p "./platform"
)
func main() {
p.Print()
}
this should work
I have a go Project with the following directory structure
utils(pkg)
| auth.go (has a function names test1)
controllers(pkg)
| login.go (has a function names test2)
I am trying to access function test1 from login.go. Here is what I have done
import "../utils"
func test2(c *gin.Context) bool{
utils.test1()
}
But I always get Unresolved reference test1. I am new to go . Can anyone help why I am getting this error?
No there is no relative import in Go.
you should use the absolute path considering GOPATH:
The GOPATH environment variable specifies the location of your workspace. It is likely the only environment variable you'll need to set when developing Go code. To get started, create a workspace directory and set GOPATH accordingly. see: https://golang.org/doc/code.html#GOPATH
Import paths
An import path is a string that uniquely identifies a package. A package's import path corresponds to its location inside a workspace
or in a remote repository (explained below).
The packages from the standard library are given short import paths
such as "fmt" and "net/http". For your own packages, you must choose a
base path that is unlikely to collide with future additions to the
standard library or other external libraries.
If you keep your code in a source repository somewhere, then you should use the root of that source repository as your base path. For
instance, if you have a GitHub account at github.com/user, that should
be your base path.
Note that you don't need to publish your code to a remote repository
before you can build it. It's just a good habit to organize your code
as if you will publish it someday. In practice you can choose any
arbitrary path name, as long as it is unique to the standard library
and greater Go ecosystem.
Example:
This example assumes you have set GOPATH=/goworkdir in your OS environment.
File: goworkdir/src/project1/utils/auth.go
package utils
func Test1() string {
return "Test1"
}
File: goworkdir/src/project1/controllers/login.go
package controllers
import "project1/utils"
func Test2() string {
return utils.Test1()
}
File: goworkdir/src/project1/main.go
package main
import (
"fmt"
"project1/controllers"
)
func main() {
fmt.Println(controllers.Test2())
}
Now if you go run main.go you should see output:
Test1
This is now different since the introduction of go modules, from go 1.11.
Thus, if you switch to go modules, and if your module is called "m", then the idiomatic way to do relative imports in your project tree would be to use: import "m/utils" and import "m/controllers" in places where you need to import those packages in your project.
For details, see:
https://github.com/golang/go/wiki/Modules#do-modules-work-with-relative-imports-like-import-subdir
GoLand users - by default these forms of imports appear as errors in the IDE. You need to enable Go Modules integration in settings
Here is another example project structure with file contents required to import correctly:
test1/
utils/
texts.go
main.go
go.mod
with following contents:
go.mod:
module mycompany.com/mytest
go 1.15
utils/texts.go (to make a function visible from a different package, it needs to start with an uppercase letter):
package utils
func GetText() string {
return "hello world"
}
main.go (only the full import name is supported, there is no shortcut to import from the same module easier):
package main
import (
"fmt"
"mycompany.com/mytest/test1/utils"
)
func main() {
fmt.Println(utils.GetText())
}
Given this directory configuration:
.
├── controllers
│ └── login.go
├── main.go
└── utils
└── auth.go
File main.go:
package main
import "./controllers"
func main() {
controllers.Test2("Hello")
}
File controllers/login.go:
package controllers
import "../utils"
func Test2(msg string) {
utils.Test1(msg)
}
File utils/auth.go:
package utils
import . "fmt"
func Test1(msg string) {
Println(msg)
}
Result works:
$ GO111MODULE=auto go build -o program main.go
$ ./program
Hello
So what you wanted to do works. The only difference is that I've used upper case function names, because it's required to export symbols.
I think you can just crate a vendor directory next to your source file, which acts like a relative GOPATH, and then create a relative symlink, which links to the package you want to import inside the vendor directory, and then import the package as if the vendor directory is your $GOPATH/src/.
It's possible as of Go 1.16, although still not as straightforward as it could be, by editing the go.mod file to resolve the package name to a relative path:
if you have a hello and a greeting packages side by side (hello contains main.go):
<home>/
|-- greetings/
|--go.mod <- init this as infra/greetings
|--greetings.go <- let's say that this package is called greetings
|-- hello/
|--go.mod <- init this as whatever/hello
|--main.go <- import infra/greetings
then edit hello's go.mod file and get the package:
go mod edit -replace infra/greetings=../greetings
go get infra/greetings
go mod tidy
There's a full example in the official documentation but hey, this might change again in the next version of Go.
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"
"github.com/foo/bar/myapp/common"
"github.com/foo/bar/myapp/routers"
)
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?
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"
)
If 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
You should have created your package with go mod init e.g. go mod init github.com/my-org/my-package
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 project you would use exported functions from the utils package like this, for example in main.go:
package main
import (
"fmt"
// "github.com/my-org/my-package" is the module name at the
// top of your `go.mod`
"github.com/my-org/my-package/utils"
)
func main() {
fmt.Printf("Random string: %s\n", utils.RandStr(20))
}
Import 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"
)
an example:
in ./greetings, do go mod init example.com/greetings
from another module, do go mod edit -replace=example.com/greetings=../greetings
go get example.com/greetings
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 "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage
But if we fork this project, then the subpackages still refer the original one.
Follow instructions here https://go.dev/doc/tutorial/call-module-code
Mainly you need the replace call in your go.mod file.
module example.com/hello
go 1.16
replace example.com/greetings => ../greetings
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.
Another approach, available since go1.18, is to use a go.work file.
First, the local common package has to be a module, so provide a go.mod file inside the common folder:
module common
go 1.18
You can now create a go.work file in the root of your directory manually or call go work init, then go work use . and finally go work use ./common. It will look like this:
go 1.18
use (
.
./common
)
Finally you can import the package in your code by name
package main
import "common"
Just remember to not commit your go.work files :)
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!