This question already has answers here:
How to use a module that is outside of "GOPATH" in another module?
(2 answers)
Closed 3 years ago.
I've been unsuccessful in importing a package from a local project (a Go module). Here is a brief of what I'm trying:
I created a Go module package like so:
$ cd
$ mkdir mymodule
$ cd mymodule
$ go mod init github.com/Company/mymodule
Then I added hello.go under the mymodule with a little function
// mymodule/hello.go
package mymodule
func sayHello() string {
return "Hello"
}
go build was successful.
Note that the module is not pushed to github repository yet. I want to use (and perhaps test) mymodule before I push to github. So I created another package, like so:
$ cd
$ mkdir test
$ cd test
$ go mod init github.com/Company/test
Then, created a new file test.go under the test directory and in there I try to import mymodule, like so:
// test/test.go
import (
"fmt"
"github.com/Company/mymodule"
)
func testMyModule() {
fmt.Println(mymodule.sayHello())
}
But go build of test fails with the below error. What gives?
cannot load github.com/Company/mymodule: cannot find module providing package github.com/Company/mymodule
When resolving dependencies in your go.mod, Go will try to resolve the third-party modules by fetching them from the remote URL that you've provided.
The remote URL, unless you've pushed it to GitHub for example, doesn't exist. This is when you get an error like this:
cannot load github.com/Company/mymodule: cannot find module providing package github.com/Company/mymodule
There is a work-around for local modules, you can use the replace keyword in your go.mod file.
replace github.com/Company/mymodule v0.0.0 => ../mymodule
This will let Go know where to find your local dependency. Just make sure to use the correct relative path to your module.
Once your local tests are complete and you've pushed your module to a repository, then you can remove the replace line from your go.mod and use
go get -u github.com/Company/mymodule`
to get the module correctly working alongside your current project.
As a side note, functions and variables in Go packages should start with a capital letter to be accessible from outside the package itself.
Good luck!
cd into github.com/Company/test,
try go mod edit --replace=github.com/Company/mymodule=../mymodule
The go.mod in test module could be:
module github.com/Company/test
require github.com/Company/mymodule v0.0.0
replace github.com/Company/mymodule v0.0.0 => ../mymodule
go 1.12
PS. sayHello function name must be capitalized. Then it becomes public and exportable to the other modules.
Related
I have a monorepo with multiple modules within it. Some of the modules are libraries, others are entry points that will produce binaries.
Here's my workspace project:
https://github.com/alshdavid/go-workspace-example
I have my "bar" library here which I would like to make available for import by consumers outside of this mono repo.
package main
import (
"fmt"
"github.com/alshdavid/bar"
// Or maybe: "github.com/alshdavid/gotest/modules/bar"
)
func main() {
fmt.Println(bar.Bar)
}
Trying to install the package from the workspace git repo results in failure.
go get github.com/alshdavid/gotest
go get github.com/alshdavid/gotest/modules/bar
go get github.com/alshdavid/bar # worth a shot
Is there an argument I should pass to go get that instructs to to look for a module in a nested folder or should I instead set up a pipeline that pushes my nested module to its own repository?
You must be working inside a module i.e. ran: go mod init in each of your modules in your mono repo.
For example, in your case I am assuming you have module named bar and you want to import module bar inside another module e.g. foo.
A module has a go.mod file. Inside go.mod file of your foo module you can add the following:
replace github.com/alshdavid/bar => ../bar
You can read more about this here
I just needed the complete path in the go.mod file
Just 3 days experience in Go language. Hope an example will be more apt to understand my confusion.
root#freebsd1:/usr/home/arun/go-start/src/test2 # go mod init f1/f2/f3/f4/f5/hello
go: creating new go.mod: module f1/f2/f3/f4/f5/hello
root#freebsd1:/usr/home/arun/go-start/src/test2 #
Here in above example go mod init is creating all these folders(f1/f2/f3/f4/f5/hello)?. I searched a lot, couldn't find any such folders in system. Then what is the significance of this path.
Even though below command will not run if this path is not mentioned as it is
# go install f1/f2/f3/f4/f5/hello
--:EDIT:--
May be this will help someone later ( Just walk through the steps to understand this in a proper way, especially for newbies )
I am planning to create a program 'calculator' and will upload in GitHub later.
I will keep the functions in different packages like sum,multiply etc
first step #go mod init github.com/go-arun/calculator( Don't confuse here , this is just an assumption that, in future I may create a repository in github for this project )
created folder sum(one of the package folder , and created sum.go inside )
See those in by system:
1.
root#debian1:/home/arun/lab# go mod init github.com/go-arun/calculator
go: creating new go.mod: module github.com/go-arun/calculator
root#debian1:/home/arun/lab# cat go.mod
module github.com/go-arun/calculator
go 1.15
2.
root#debian1:/home/arun/lab# cat sum/sum.go
package sum
import "fmt"
func Sum(num1,num2 int)(){
fmt.Println(num1+num2)
}
3.
root#debian1:/home/arun/lab# cat main.go
package main
import(
"github.com/go-arun/calculator/sum"
)
func main(){
n1 := 10
n2 := 10
sum.Sum(n1,n2)
}
4.
root#debian1:/home/arun/lab# tree
.
|-- go.mod
|-- main.go
`-- sum
`-- sum.go
go mod init does not create those folders. You pass the "module path" to go mod init which is recorded in the go.mod file it creates.
The "module path" is the import path prefix corresponding to the module root. The module path and the relative path to the module root together form the complete import path which must be unique in an app.
So for example if your module contains a folder named foo (and a package foo in it), it is imported by a path being modulepath/foo. In your case it would be f1/f2/f3/f4/f5/hello/foo.
It is allowed for moduleA to contain a foo package, and also for moduleB to have a foo package. When used / imported, first would be imported like moduleA/foo the latter like moduleB/foo, so it's unambiguous which one you're importing. The module path is like a namespace.
It's recommended to use a module path that corresponds to a repository you plan or will publish your module to, so when you do, go get will be able to automatically fetch, build and install your module. For example you may choose a module path github.com/bob/hello, so when you publish your module, everyone can get it by simply using import "github.com/bob/hello" in their app.
Also note that you don't need to publish your code to a remote repo before you can build it. But it's still recommended to follow this pattern so you'll have less work to make it work in the future if you decide to publish it. Nothing to lose here.
More in the docs: Command go: Defining a module
Also: How to Write Go Code: Code organization
I've created a library as the module for personal use outside of "GOPATH" in "database" folder with this command "go mod init database," and I don't know:
How to use/import this module in another module?
OS: Windows 7, Go: v1.11
The easiest and working out-of-the-box solution is to put your database package / module into a VCS (e.g. github.com), so other packages (inside other modules) can simply refer to it by importing it like:
import "github.com/someone/database"
If you do so, you don't even have to fiddle with the go.mod files manually, everything will be taken care of by the go tool: it will automatically recognize and resolve this dependency, download and install the required package, and will also update go.mod automatically.
Staying entirely on local disk
If you don't want to use a VCS (e.g. you're just experimenting or you haven't decided what to use yet), then you can still do it. The how is detailed in the official Go Wiki: Can I work entirely outside of VCS on my local filesystem?
So you created a database folder outside of GOPATH, and you created a module in it. And you created another module, let's call it main, and you want to use this database package.
What you must do is:
go.mod of your main module must list the database package as a "requirement". Give a temporary VCS name to your database package:
require (
example.com/me/database v0.0.0
)
You must tell the go tool where this package is located, because the full package name we used is just a temporary / fantasy name. Use the replace directive to make this database package point to a folder on your local disk; you may use absolute and relative paths:
replace example.com/me/database => ../database
And that's all.
Working example
Let's see a working example. Let's create a pretty module. Create a pretty folder with 2 files in it:
pretty.go:
package pretty
import "fmt"
func Pretty(v ...interface{}) {
fmt.Println(v...)
}
go.mod (can be created by running go mod init pretty):
module pretty
Now let's create another, main module. Let's create a folder osinf (it may be whatever) next to the pretty folder. 2 files in it:
osinf.go (note we intend to use our pretty package / module, we import it by "example.com/me/pretty"):
package main
import "example.com/me/pretty"
func main() {
pretty.Pretty("hi")
pretty.Pretty([]int{1, 3, 5})
}
go.mod:
module main
require example.com/me/pretty v0.0.0
replace example.com/me/pretty => ../pretty
And that's all.
Running go run osinf.go in the osinf folder, the output is:
hi
[1 3 5]
Run:
go mod init yellow
Then create a file yellow.go:
package yellow
func Mix(s string) string {
return s + "Yellow"
}
Then create a file orange/orange.go:
package main
import "yellow"
func main() {
s := yellow.Mix("Red")
println(s)
}
Then build:
go build
https://golang.org/doc/code.html
In my Go project, I want to break out some generic functionality into a Go module, separate from the main project. I'm doing this outside of GOPATH in keeping with go's future. I don't want to publish the module on GitHub or anywhere else.
All my attempts to import this module into the main project result in:
cannot find module for path X
I've run go mod init X in the module's folder. The contents of its go.mod file is:
module X
Building or installing this module seems to do nothing. I've found no sign of it in $GOPATH/pgk/mod.
I've tried a variety of import statements:
import "X"
import "../x" (relative path to the module directory)
import "../x/X" (path to the directory + module name)
Help!
So you wrote a Go "library" module X which:
you don't want to publish on GitHub or elsewhere
you want to import and use in your project (the "main" module).
Use a replace directive along with require
In your main module's go.mod, add the following lines:
require "X" v0.0.0
replace "X" v0.0.0 => "{local path to the X module}"
The path should point to the root directory of X. It can be absolute or relative.
To import package util from module X:
import "X/util"
(You don't import modules. You import packages from modules.)
Explanation
Go's module functionality is designed for publicly published modules. Normally, a module's name is both its unique identifier and the path to its public repo. When your go.mod declares a module dependency with the require directive, Go will automatically find and retrieve the specified version of the module at that path.
If, for example, your go.mod file contains require github.com/some/dependency v1.2.3, Go will retrieve the module from GitHub at that path. But if it contains require X v0.0.0, "X" isn't an actual path and you will get the error cannot find module for path X.
The replace directive allows you to specify a replacement path for a given module identifier and version. There are many reasons you'd want to do this, such as to test changes to a module before pushing them to the public repo. But you can also use it to bind a module identifier to local code you don't ever intend to publish.
More details in the Go Modules documentation:
Can I work entirely outside of VCS on my local filesystem?
When should I use the replace directive?
Hope this helps.
If you don't want to use Go modules, you don't need to. As of Go v1.13, by default, go modules are used. Therefore, you need to tell explicitly if you don't want to do this.
Example:
main.go:
package main
import (
"fmt"
"./pakk"
)
func main() {
fmt.Println("Hello" + pakk.World())
}
pakk/pakk.go:
package pakk
func World() string {
return " world"
}
In this case, running go run main.go will output
build command-line-arguments: cannot find module for path .../pakk
but running
GO111MODULE=off go run main.go
will output
Hello world
Spent 4 days figuring this out. Very disapointed, but the way to import ./X
is as following:
first issue this magic command:
go mod init poop/strawberry/monkey
then you can EASILLY import your ./X folder:
import (
"poop/strawberry/monkey/X"
)
Folder structure:
./X/X.go
./main.go
./go.mod
contents of go.mod:
module poop/strawberry/monkey
this is the awesome solution from go module creators
https://go.dev/ref/mod#go-mod-init
module path: A path that identifies a module and acts as a prefix for package import paths within the module. For example, "golang.org/x/net"
go mod init api.com
// "api.com" name your app , it's alike swift 's bundle identifier , your can also "whatever.youlike"
myExample
Error ? Go cannot resolve the path to your modules, this is probably from misconfiguration or (not configuring) of the "go.mod" file used for project dependency tracking.
Solution lets assume your project folder looks like below;
/
|-- folderOne/
|-- folderTwo/
|-- folderThree/
|-- main.go
And the main.go script imports the modules folderOne,folderTwo and folderFour's script (folderfour.go) imports the module folderThree.
folderOne:
execute in the commandline:
go mod init github.com/../folderOne (i.e path from github.com folder to folderOnes)
The go mod init command creates a go.mod file to track your code's dependencies
folderTwo:
execute in the commandline:
go mod init github.com/../folderTwo (i.e path from github.com folder to folderTwos)
The go mod init command creates a go.mod file to track your code's dependencies
folderThree:
execute in the commandline:
go mod init github.com/../folderThree (i.e path from github.com folder to folderThrees)
The go mod init command creates a go.mod file to track your code's dependencies
folderFour:
execute in the commandline:
go mod init github.com/../folderThree (i.e path from github.com folder to folderFour)
Go to the folderFours script and import the module folderThree i.e
import "github.com/../folderThree"
in folderfours commandline:
$ go mod edit -replace github.com/{pathto}/folderThree=./folderThree**
then execute: go mod tidy
in your projects root folder execute the command: go mod init github.com/../ProjectRootDirectory (i.e path from github.com folder to ProjectRootDirectory)
then to import the modules, i.e folderThree, folderTwo, folderOne
execute the following at the projects root folder(ie folder with main.go)
$ go mod edit -replace github.com/{pathto}/folderOne=./folderOne
$ go mod edit -replace github.com/{pathto}/folderTwo=./folderTwo
$ go mod edit -replace github.com/{pathto}/folderFour=./folderFour
then execute;
$ go mod tidy
and then
$ go run main.go
I'm trying to initialize a new go project with go module (using go 1.11). I don't plan to publish it in github or elsewhere, it is just a temporary/test project with only main package.
Whenever I try to run go mod init in a directory (that's outside my $GOPATH), I get this error:
go: cannot determine module path for source directory /Users/... (outside GOPATH, no import comments)
Is it not possible to init module without using git (or other VCS)? Or is there any workaround?
Is it not possible to init module without using git (or other VCS)? Or
is there any workaround?
Yes, it is possible to init the modules without using VSC, initializing the module does not have to do anything with git or any other VCS.
This error occurs when the module name is not entered while init the module so to generate a module modulename write this command.
$ go mod init modulename
The content of the go.mod would be
module modulename
EDIT:
To use the modules from local repository use the replace directive
In your main module where you are checking your local module add the following lines
replace "X" v0.0.0 => "{location To your local module}"
require "X" v0.0.0
And then in your main project, import package util from module X you can simply do:
import "X/util"
Now when you will do go build it will look for this local module on the location you have given in the mod file of the main project.
For more explanation