Go modules without remote repository?
Asked Answered
M

2

7

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?

Mustachio answered 3/6, 2020 at 2:48 Comment(4)
There's some info here about using a local file path in go.mod: medium.com/@adiach3nko/… (in the "Substitute Imported Modules" section). Hope that helps.Miramontes
Can I work entirely outside of VCS on my local filesystem?Macaulay
Use the replace directive.Wrath
1. You should never use an import part like "lib" or "foo/bar" for any of your packages. Such types of import paths should be reserved for the stdlib. 2. You module name should be something like "whatever.you.like/some/folder" 3. A replace directive in the go.mod lets you do whatever you like. 4. The best advice is: Stick to How to Write Go Code and do not try to be clever and do not try do mimic what you might be used from other languages.Tyndale
G
8

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() {
    //...
}

Gamp answered 3/6, 2020 at 6:56 Comment(0)
M
0

assuming code is for your own use only and won't be published

from your src (or root) directory:

$ go mod init <project_name>

use the path from the root when you want to import modules from within other modules:

import ( 
   "project_name/lib" 
)

or

import ( 
   "project_name/package_name" 
)

no need to $ go init mod in the subdirectories.

Monosyllable answered 20/6, 2022 at 21:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.