25

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:

Help!

Inigo
  • 12,186
  • 5
  • 41
  • 70
  • 1
    This relates to the more general question of [How to use a module that is outside of “GOPATH” in another module?](https://stackoverflow.com/questions/52328952/how-to-use-a-module-that-is-outside-of-gopath-in-another-module). – Inigo Feb 28 '19 at 23:30

5 Answers5

42

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:

Hope this helps.

Inigo
  • 12,186
  • 5
  • 41
  • 70
Hamza Anis
  • 2,475
  • 1
  • 26
  • 36
13

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
Csongor Halmai
  • 3,239
  • 29
  • 30
  • 2
    I tested this `GO111MODULE=off` option and it worked. – look Sep 27 '21 at 18:52
  • 2
    Is there a way to do this if I want to have my local package pakk but also have other outside modules? Right now if I turn GO111MODULE=off it looks like outside packages such as "github.com/go-chi/chi" cannot be found – T-coder Oct 28 '21 at 05:13
3

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"
0

go mod init api.com

// "api.com" name your app , it's alike swift 's bundle identifier , your can also "whatever.youlike"

myExample

Eve Tong
  • 21
  • 2
0

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
bitbuoy
  • 353
  • 2
  • 8