Semantics of the Replace Directive

In short:

What is the difference between the replace directive as used in .work and .mod files?


I am looking for a solution to working on multiple packages at once/not having to download dependencies every time I start a new project and have been reading the Go Modules Reference’s entries for mod, and work, files but I cannot tell why the behaviour should be different.

I had found that I am able to do this reasonably well by using replace directives in the go.mod file. However, I’d prefer not to do this because it doesn’t make sense to share a package with a mod file whose validity is bound to the state of a particular developer’s file system and a clumsy fool like me is definitely going to make a mistake with managing this at some point.

I recently learned that it is possible to use replace directives in .work files, which I assumed would help because .work files are not intended to be shipped with importable libraries, but using the directive in this context seems to have no effect on the behaviour of the go mod tidy command; it still proceeds to try to download a package (failing if I’ve not yet posted it online).


setup

go version
go1.18beta2 darwin/amd64

go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/kendfss/Library/Caches/go-build"
GOENV="/Users/kendfss/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/kendfss/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/kendfss/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/kendfss/sdk/go1.18beta2"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/kendfss/sdk/go1.18beta2/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.18beta2"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/bw/pdrs14k158167vwp8ts8vvg80000gp/T/go-build1572228178=/tmp/go-build -gno-record-gcc-switches -fno-common"

Use go.work with the use directive. This allows you to have multiple modules locally, and while you work on a main module inside the workspace, all imports of the main module that are listed in the go.work file as a use directive get loaded from local disk instead of the remote repository.

With the new Workspace mode, the replace directive in go.mod is primarily a way of avoiding to import a broken version of a dependency (alongside the exclude directive). And the replace directive inside a go.work file can be used to override a replace directive in a go.mod file if needed.

So for working on multiple modules locally, workspace mode is now the best option - after all, that’s what it was created for.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.