Log in

Adam Israel
Making OS X, Go, and Brew play happy 
13th-Nov-2014 12:28 am

GO and OS X

I’m doing a little hacking with juju actions before they land in a stable release but I ran into some hurdles getting Go working with the brew-installed version. Trying to install Go packages failed with a bunch of ‘unrecognized import path’ errors. Here’s how I fixed it.


Even though you can install Go via brew, there’s more to be done to get it working. Go relies on two environment variables: GOPATH, and GOROOT. GOROOT is the path where Go is installed, and GOPATH is the directory you’ve created for your code workspace (which I’ve defaulted to $HOME/go).  We then need to tell our shell where to find these installed executable and run them first1.

cat << EOF > ~/.bash_profile
# Go go gadget Go!
GOVERSION=$(brew list go | head -n 1 | cut -d '/' -f 6)
export GOPATH=$HOME/go
export GOROOT=$(brew --prefix)/Cellar/go/$GOVERSION/libexec

Now you can run something like to have easier access to docs:

$ go get code.google.com/p/go.tools/cmd/godoc
$ godoc gofmt

    Gofmt formats Go programs. It uses tabs (width = 8) for indentation and
    blanks for alignment.

    Without an explicit path, it processes the standard input. Given a file,
    it operates on that file; given a directory, it operates on all .go
    files in that directory, recursively. (Files starting with a period are
    ignored.) By default, gofmt prints the reformatted sources to standard


    gofmt [flags] [path ...]

    The flags are:

        Do not print reformatted sources to standard output.
        If a file's formatting is different than gofmt's, print diffs
        to standard output.
        Print all (including spurious) errors.
        Do not print reformatted sources to standard output.
        If a file's formatting is different from gofmt's, print its name
        to standard output.
    -r rule
        Apply the rewrite rule to the source before reformatting.
        Try to simplify code (after applying the rewrite rule, if any).
        Do not print reformatted sources to standard output.
        If a file's formatting is different from gofmt's, overwrite it
        with gofmt's version.

    Debugging support:

    -cpuprofile filename
        Write cpu profile to the specified file.

    The rewrite rule specified with the -r flag must be a string of the

    pattern -> replacement

    Both pattern and replacement must be valid Go expressions. In the
    pattern, single-character lowercase identifiers serve as wildcards
    matching arbitrary sub-expressions; those expressions will be
    substituted for the same identifiers in the replacement.

    When gofmt reads from standard input, it accepts either a full Go
    program or a program fragment. A program fragment must be a
    syntactically valid declaration list, statement list, or expression.
    When formatting such a fragment, gofmt preserves leading indentation as
    well as leading and trailing spaces, so that individual sections of a Go
    program can be formatted by piping them through gofmt.


    To check files for unnecessary parentheses:

    gofmt -r '(a) -> a' -l *.go

    To remove the parentheses:

    gofmt -r '(a) -> a' -w *.go

    To convert the package tree from explicit slice upper bounds to implicit

    gofmt -r 'α[β:len(α)] -> α[β:]' -w $GOROOT/src/pkg

    The simplify command

    When invoked with -s gofmt will make the following source
    transformations where possible.

    An array, slice, or map composite literal of the form:
        []T{T{}, T{}}
    will be simplified to:
        []T{{}, {}}

    A slice expression of the form:
    will be simplified to:

    A range of the form:
        for x, _ = range v {...}
    will be simplified to:
        for x = range v {...}


   The implementation of -r is a bit slow.

Homebrew Gotchas

Homebrew installs the go formula with a bin/ directory, which symlinks to the go and gofmt binaries in libexec/. Other binaries, such as godoc, will be installed to libexec but are not symlinked to bin/. Adding go/$GOVERSION/libexec, instead of go/$GOVERSION/bin, to PATH makes sure we’re looking in the right place, and this setup will survive a version upgrade.

1: It would probably be better to create a script that would toggle the PATH to include/exclude my $GOPATH/bin in $PATH. I’m using this to run the latest cutting edge version of juju, but I can see the need to switch back to using the released version of juju, without having to hack my ~/.bash_profile

[Crossposted from Adam Israel. If you'd like to comment, you can do so either here or there.]

13th-Nov-2014 05:37 am (UTC)
how are you liking go? one of Amy's colleagues wrote some glue code for her in go, so I had to get that working, but I haven't really looked at it past that....

juju looks...interesting. I think Amazon just announced something similar for ec2? http://aws.amazon.com/codedeploy/ (and maybe http://aws.amazon.com/config/ ? ... brain not holding things much, so this is as much a question of "is this what juju is?" as anything... )
13th-Nov-2014 05:41 am (UTC)
I haven't done too much with Go yet, but I plan to hack around with it a bit. Our core product (juju) is written in Go, and there's some bits of functionality I'd like to see working, so that's enough of a reason to give it a spin.

Juju's a 'cloud orchestration' kit, usable against just about any cloud provider. From my local laptop, I can spin up and monitor a cluster of web servers. Takes me two minutes, and it does all the hard work of provisioning the right instances, bootstrapping the machines and installing the services I want.
13th-Nov-2014 05:57 am (UTC)
very nifty :)


starting to appreciate the cloud a little (although not the $ involved). but the scale problems being solved...and the right sorts of redundancies...yes.
This page was loaded Mar 1st 2017, 5:56 pm GMT.