Search code examples
gomulti-modulego-modules

Go modules without remote repository?


I'm trying to get Go modules working without involving a remote repository.

src is a local directory that contains all my projects, also projects that are written in other languages than Go. For simplicity I have only show the two directories relevant for my question:

src
 ├── client
 │   ├── go.mod
 │   └── main.go
 └── lib
     ├── go.mod
     └── lib.go

The go.mod files are created by running the command go mod init client in src/client and go mod init lib in src/lib.

src/client/main.go:

package main

import "lib"

func main() {
    lib.Hello()
}

src/lib/lib.go:

package lib

import "fmt"

func Hello() {
    fmt.Println("Hello World")
}

What I'm trying to do is using the library lib.go in my main.go, but no matter what I put in the import path, this error is shown:

main.go:3:8: package lib is not in GOROOT (/usr/lib/go/src/lib)

Go version is go1.14.3

How do I correctly import Go code from local folders?


Solution

  • You can use replace directive.

    Project structure:

    root
     ├── client
     │   ├── go.mod
     │   └── main.go
     └── lib
         ├── go.mod
         └── lib.go
    

    go.mod of root/lib module:

    module github.com/owner/root/lib
    
    go 1.13
    

    go.mod of root/client module:

    module github.com/owner/root/client
    
    go 1.13
    
    require github.com/owner/root/lib v0.0.0
    
    replace github.com/owner/root/lib => ../lib
    

    This is terrible, do you really have to do this for every import if there is no VCS?

    No. replace directive replaces the contents of a specific version of a module and includes packages that belong to substitute module.

    root
     ├── client
     │   ├── go.mod
     │   └── main.go
     └── lib
         ├── utils
         │   └── util.go
         ├── libs
         │   └── lib.go
         └── go.mod
    
    package main
    
    import (
        "github.com/owner/root/lib/utils"
        "github.com/owner/root/lib/libs"
    )
    
    func main() {
        //...
    }