How to Write a Golang Module Without Putting it on the Internet?

published: [nandalism home] (dark light)

Internet Module versus Local Module

golang wants you to import your self-written modules from the internet, and you will probably want to put them there, but just not immediately. golang's solution to this is to pretend that the module is already on the net and then replace the url with a local path in go.mod.

For example, use this path to include your new module src.deckc.hair/nandalism/dbtracer even tho it doesn't actually exist yet. If you try to compile your code with this import, go get will fail to download and build it.

  $ cat yourdbcode.go
  import (
    _ "src.deckc.hair/nandalism/dbtracer"
  )

  // dbpool, err := sql.Open("sqlite3", database_path)
  dbpool, err := sql.Open("dbtracer", database_path)

The Local Module

First you will need to copy the module to your ~/go/src directory e.g. the above module would live at ~/go/src/nandalism/dbtracer.

Then you need to add a replace statement in your go.mod to point to your local module.

  $ cat go.mod
  go 1.18
  require (
    src.deckc.hair/nandalism/dbtracer v0.0.1
  )
  replace src.deckc.hair/nandalism/dbtracer => /home/<youruser>/go/src/nandalism/dbtracer

Now go build will work and build the module locally.

Module in Subdirectory

Create a subdir named like the package name you intend to use, then use go mod init <package name> to create the go.mod. Source files in the subdir should have package <subdir-name.

$ mkdir blogroll
$ ( cd blogroll && go mod init blogroll )
$ ls blogroll/
go.mod  main.go

$ cat blogroll/go.mod
module blogroll
go 1.18

$ cat blogroll/main.go
package blogroll
func NewBlog(a int) int {
  return a*2
}

Now use require/replace in the toplevel go.mod to specify the module. Do this before build or [go mod tidy], otherwise the code will try to download your module. replace also works with subdirectory modules and relative paths. You must still pretend the module lives on the internet and use replace in go.mod. After that go mod tidy will avoid trying to download things from the internet, which are not there, and go build will compile the code in the local subdir.

$ cat toplevel.go
package main
import (
  "src.deckc.hair/sandestin/blogroll"
)
... blogroll.NewBlog(12)

$ cat go.mod
module src.deckc.hair/sandestin
go 1.18
require (
  src.deckc.hair/sandestin/blogroll v1.0.0
)
replace src.deckc.hair/sandestin/blogroll => ./blogroll
Where blogroll is a subdirectory of the toplevel build directory, and should contain files with package blogroll.

site built using mf technology