4

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
Keerthi
  • 466
  • 6
  • 12
  • Never call packages or files "test". Export you stuff. Even without the module error your code would never work. – Volker Nov 24 '19 at 09:06

3 Answers3

5

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!

Nick Corin
  • 2,214
  • 5
  • 25
  • 46
  • 1
    Is it possible to place the replace directive in a separated file module file ? It seems weird and dangerous to have to modify a potentialy versionned file to make some dependencies tests.. – sigz Feb 02 '21 at 23:05
  • 1
    @sigz you are right, you don't want to commit the "replace" lines when you commit your go.mod file. In Go 1.18 there is now a workspace file (go.work) for this purpose. Ie once you are using Go 1.18 use a go.work file instead of the replace clauses, and don't commit go.work. See https://tip.golang.org/doc/go1.18 – Andrew W. Phillips Apr 06 '22 at 02:12
3

cd into github.com/Company/test,

try go mod edit --replace=github.com/Company/mymodule=../mymodule

zzn
  • 2,376
  • 16
  • 30
0

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.

Howard
  • 3,638
  • 4
  • 32
  • 39