Using localy stored modules

The highest Hierarchy: Modules

Your go projects is defined by the modulename. The modulename is defined in the file go.mod in the first line as module modulepath.

Let’s assume you creating a library or a programm called instance Your modulename could be just a name like instance.

If you locally create a small script and never want to share any of the libraries, that would work.

md instance
cd instance
go mod init instance
cat go.mod

Creates a go.mod:

module instance

go 1.23.2

Usually you take the github path of your project for the module name, so that get the module with the whole path in other projects: go get $wholepath.

That can be just one module per github repository, or you use multiple modules in one monorepo.

Example for a repository which includes multiple go modules:

  • Repository: https://github.com/megaproaktiv/g4-source
  • Path: https://github.com/megaproaktiv/g4-source/tree/main/m01/infra/instance
  • Modulename: github.com/megaproaktiv/g4-source/m01/infra/instance The repository g4-source contains a module in m01/infra/instance.

Modules

Packages

Within the module there can be multiple packages. It works best if the packagename == the directory name.

But it is possible to have a different package and directory name.

Using other modules

Other modules are imported with go get modulename. so e.g. if you want to use the ec2 service module:

go get github.com/aws/aws-sdk-go-v2/service/ec2

This will result in a require github.com/aws/aws-sdk-go-v2/service/ec2 entry in you go.mod file

See the result in the same go.mod file github.com/megaproaktiv/g4-source/blob/main/m01/infra/instance/go.mod

So other modules are referenced as url in go.mod.

Replace

If you do not want to use the module from github, use replace to override/replace the github url with an local file path. This path can be relative.

Now in our instance module we want to use a mapping module from our local drive.

module github.com/megaproaktiv/g4-source/m01/infra/instance

go 1.23.2

replace github.com/megaproaktiv/g4-source/m01/infra/mapping => ../mapping

require (

	github.com/megaproaktiv/g4-source/m01/infra/mapping v1.0.0
)

For multiple values you add multiple replace lines.

Using a local shared library/module from projects in a monorepo

In a directory infra I want to have three modules:

  • One module to create a AWS vpc, called vpc
  • One module tp create an AWS EC2 instance, called instance
  • One shared module to manage mappings of logical and physical ID, called mapping

The base directory looks like this:

├── instance
├── mapping
└── vpc

Each module has its own go.mod file:

├── instance\go.mod
├── mapping\go.mod
└── vpc\go.mod

In the mapping\go.mod the mapping modulename is defined:

module github.com/megaproaktiv/g4-source/m01/infra/mapping

go 1.23.2

There is a mapping.go includes:

package mapping

...
type Infrastructure struct {
	VpcId           string `json:"vpc_id"`
...
}

In the other module instance in main.go I can use this type:

import (
  ...
	"github.com/megaproaktiv/g4-source/m01/infra/mapping"
	...
)


func main() {
	...
	var infraMap *mapping.Infrastructure = &mapping.Infrastructure{}
...
}

This works, because in └── vpc\go.mod there is the matching replace directive:

replace github.com/megaproaktiv/g4-source/m01/infra/mapping => ../mapping

Disclaimer

The g4 modules are from a project with my initials “gg” and “generative” and “go” i am working on. At the moment do not try to make too much sense out of the code… .