Adam Israel (stonetable) wrote,
Adam Israel
stonetable

Making OS X, Go, and Brew play happy

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.

STOP, GO, STOP

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
PATH=$GOROOT/bin:"${PATH}"
EOF

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

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

    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
    output.

    Usage:

    gofmt [flags] [path ...]

    The flags are:

    -d
        Do not print reformatted sources to standard output.
        If a file's formatting is different than gofmt's, print diffs
        to standard output.
    -e
        Print all (including spurious) errors.
    -l
        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.
    -s
        Try to simplify code (after applying the rewrite rule, if any).
    -w
        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
    form:

    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.

    Examples

    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
    ones:

    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:
        s[a:len(s)]
    will be simplified to:
        s[a:]

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

BUGS

   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.]

Tags: go, homebrew, juju, os x
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 3 comments