43

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

Reza Mousavi
  • 4,420
  • 5
  • 31
  • 48
samadadi
  • 3,100
  • 7
  • 25
  • 37
  • 1
    You import it by the package name declared in the mod.go file. Note that you cannot import modules you can only import packages. Also note that there is no notion of "local" package. – Volker Sep 14 '18 at 09:38
  • package is outside of gopath so go build tool does not recognize it so can't build the module. – samadadi Sep 14 '18 at 09:43
  • Go 1.11 with GO111MODULE=on (the default if outside of GOPTH) can build anywhere. You really must provide much more details about your problem. – Volker Sep 14 '18 at 10:02
  • Go 1.11 builds modules based on "go.mod" file. So the question is how to address "database" module in the "go.mod" file? – samadadi Sep 14 '18 at 10:10
  • 2
    You don't. Put it in your GOPATH. Don't fight the tools. – Jonathan Hall Sep 14 '18 at 10:20
  • 1
    No, this is all wrong. You do not "build a module", you build packages. The go.mod just describes which version your module has and (optionally) if packages imported by one of your packages in your module require specific versions. `go build` will build your package and if your package wants to import "foo/bar" than you must `import "foo/bar"`. If foo/bar v3.4.5 must be used: add a line in go.mod. Just run go build. Go build will download any dependencies (by looking at the import statements) and build. no mod.go involved here. – Volker Sep 14 '18 at 10:21
  • If you need further help: Please describe _exactly_ what your setup is, including all code, what command you run in which directory and what the exact error messages are. – Volker Sep 14 '18 at 10:22
  • There is absolutely a problem with my question, but what i'm trying to say is: how to import a package that is outside of "GOPATH"? Is it possible at all with go v1.11? – samadadi Sep 14 '18 at 10:34
  • Uhm, just out of curiosity: why would one want to maintain code outside of GOPATH? Makes everything harder and nothing easier. And for switching environments, one could use various GOPATHS... So why?!? – Markus W Mahlberg Dec 03 '18 at 07:13
  • Hello sir. It's just matter of choice. The downside of using various GOPATHs is that you should manage gopath environment variable list yourself. Maybe somebody likes this approach & somebody does not. Thanks to Go module system, there is no need to manage various GOPATHs & everybody has a choice. – samadadi Dec 04 '18 at 13:58

2 Answers2

92

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]
icza
  • 389,944
  • 63
  • 907
  • 827
  • 1
    Thank you so much. This is exactly what i needed. – samadadi Sep 14 '18 at 10:56
  • @samadadi you should mark the answer as "accepted" to give icza credit and also to increase the visibility of the answer. See https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Inigo Mar 28 '19 at 04:08
1

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

Zombo
  • 1
  • 62
  • 391
  • 407