Dependancy Management with go.mod
#Reading
- https://go.dev/wiki/Modules
- https://go.dev/wiki/PackagePublishing
- Go Package, Go
- using replace in
go.mod
#go mod
# go mod <command> [arguments]
go mod init <name>
# Updates all dependencies to lastest minor.patch version. (https://stackoverflow.com/q/66753231)
go get -u ./...
# vendore deps
go mod vendor
# update dependency (to minor.patch)
go get -u <url>
# why we have this dependency?
go mod why github.com/sirupsen/logrus
go mod graph | grep logrus
# editing
# remove from require
go mod edit -droprequire github.com/sirupsen/logrus
# add to repalce block
go mod edit -replace github.com/sirupsen/logrus=./logrus/local
# Dependencies
# downlaod missing
go mod tidy
# verify dependencies have expected content
go mod verify
#Troubleshooting
If case if go mod why useless, first resolve all go.mod versions on dependecies, then find what uses it.
# - ./dependancies/check_go_mod.py -
##!/usr/bin/env -S uv run --script
# /// script
# dependencies = [ 'rich' ]
# ///
import asyncio
import pathlib
import re
from rich.console import Console
from rich.table import Table
go_version = re.compile(r"go (.*?)$", re.MULTILINE | re.DOTALL)
def get_go_mod_path(path: pathlib.Path) -> str | None:
if not path.exists():
return None
return str(path)
def get_go_mod_version(path: pathlib.Path) -> str | None:
if m := go_version.search(path.read_text()):
return m.group(1)
return None
async def main():
root = pathlib.Path(".")
home = pathlib.Path.home() / "go/pkg/mod"
table = Table(title="Star Wars Movies")
table.add_column("Package", justify="right", style="magenta")
table.add_column("Version", style="cyan")
table.add_column("Path go.mod", style="cyan")
table.add_column("Version go.mod", style="cyan")
goMod = root / "go.mod"
pattern = re.compile(r"require \((.*?)\)$", re.MULTILINE | re.DOTALL)
for req in pattern.findall(goMod.read_text()):
for req in req.strip().splitlines():
parts = req.split("//")[0].split()
if len(parts) == 2:
package, version = parts
suffixes = package.split("/")
pathToGoMod = home / f"{'/'.join(suffixes[:-1])}/{suffixes[-1]}@{version}/go.mod"
path, goVersion = None, None
if _path := get_go_mod_path(pathToGoMod):
path = _path
if _version := get_go_mod_version(pathToGoMod):
goVersion = _version
table.add_row(package, version, path, goVersion)
console = Console()
console.print(table)
if __name__ == "__main__":
asyncio.run(main())
# Then find whats uses this dependency.
cd ~/go/pkg && grep -R "github.com/user/pkg"
#GOPROXY
- Using
GOPRIVATEenvironment variable controls which modules the go command considers to be private (not available publicly). - Using
GOPROXYenvironment variable we can tell what proxy for dependencies can be used. GONOPROXYandGONOSUMDBenvironment variables accept the same kind of glob list and override GOPRIVATE for the specific decision of whether to use the proxy and checksum database, respectively.
#Resources
https://go.dev/wiki/GoGetProxyConfig https://jfrog.com/blog/why-goproxy-matters-and-which-to-pick/
#Vendoring
We can save all our dependecies with go mod vendor.
# wouln't work with go.work, need to turn it off with GOWORK=off
GOWORK=off go mod vendor