Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

258 lines (187 sloc) 5.18 KB

Using github.com/rogpeppe/gohack

gohack is a tool that helps you make temporary edits to your Go module's dependencies. By default, dependencies are stored in a read-only cache. gohack adds a replace directive to directory where you can "hack" the dependency's code, and then removes the directive when you are done. For more details on replace directives, see the Go modules wiki.

This example shows how to use gohack.

Walk-through

Install gohack:

$ gobin github.com/rogpeppe/gohack
Installed github.com/rogpeppe/gohack@v1.0.0 to /home/gopher/bin/gohack

Create a module:

$ mkdir -p /home/gopher/scratchpad/using-gohack
$ cd /home/gopher/scratchpad/using-gohack
$ go mod init example.com/blah
go: creating new go.mod: module example.com/blah

Add a simple dependency to a main package in our module:

$ cat blah.go
package main

import (
	"fmt"
	"rsc.io/quote"
)

func main() {
	fmt.Println(quote.Hello())
}

In this case, we use a specific version of our dependency:

$ go get rsc.io/quote@v1.5.1
go: finding rsc.io/quote v1.5.1
go: finding rsc.io/sampler v1.3.0
go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: downloading rsc.io/quote v1.5.1
go: extracting rsc.io/quote v1.5.1
go: downloading rsc.io/sampler v1.3.0
go: extracting rsc.io/sampler v1.3.0
go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: extracting golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c

Run as a quick "test":

$ go run .
Hello, world.

Now let's assume we want to tweak the rsc.io/quote package, in particular we want to tweak the Hello function we are using. We use gohack to do this.

"Hack" on rsc.io/quote:

$ gohack get rsc.io/quote
rsc.io/quote => /home/gopher/gohack/rsc.io/quote

Verify our module is using the local "hack" copy:

$ go mod edit -json
{
	"Module": {
		"Path": "example.com/blah"
	},
	"Go": "1.12",
	"Require": [
		{
			"Path": "rsc.io/quote",
			"Version": "v1.5.1"
		}
	],
	"Exclude": null,
	"Replace": [
		{
			"Old": {
				"Path": "rsc.io/quote"
			},
			"New": {
				"Path": "/home/gopher/gohack/rsc.io/quote"
			}
		}
	]
}

gohack puts "hacks" in $HOME/$module; we make our changes there:

$ cd /home/gopher/gohack/rsc.io/quote
$ cat <<EOD >quote.go
package quote

func Hello() string {
	return "My hello"
}
EOD

Rerun our example:

$ cd /home/gopher/scratchpad/using-gohack
$ go run .
My hello

Revert to the original rsc.io/quote:

$ gohack undo rsc.io/quote
dropped rsc.io/quote
$ go run .
Hello, world.

More specific information about subcommands is available via help, for example:

$ gohack help get
usage: get [-vcs] [-u] [-f] [module...]

The get command checks out Go module dependencies
into a directory where they can be edited.

It uses $HOME/gohack/&lt;module&gt; as the destination directory.
(TODO implement directory overriding)

By default it copies module source code from the existing
source directory in $GOPATH/pkg/mod. If the -vcs
flag is specified, it also checks out the version control information into that
directory and updates it to the expected version. If the directory
already exists, it will be updated in place.

Version details

go version go1.12.5 linux/amd64
github.com/rogpeppe/gohack v1.0.0
You can’t perform that action at this time.