Fixing Sublime Text 2 and GoSublime

I’m still using Sublime Text 2 because it works well for me. I also use the GoSublime plugin to trigger go fmt and goimports on every save. This broke when GoSublime updated recently.

ETA: As of 2016/05/18 this broke again, still working out why.

** ETA2: I never got Sublime Text 2 to work properly with GoSublime. However, upgrading to Sublime Text 3 was painless and GoSublime works properly again!**

The fix: Instead of using the Package Manager, manually clone down the git repo and check out and older version (hat tip these folks).

Step 1: Uninstall GoSublime through the Package Manager.

Step 2: Rename or delete the GoSublime folder in /Users/<USERNAME>/Library/Application\ Support/Sublime\ Text\ 2/Packages.

Step 3: Pull down the GoSublime repo.

Step 4: Check out commit 852a15fb933

Notes on Go, part 7 of ∞

Coming to Go from Ruby has been an experience and a half. A lot of the things I’ve stubbed my toes on are either vocabulary things, or things that I don’t know about because I’ve never really used a statically typed language before.

A map is a hash table is a ruby hash

Lets start by paying a visit to Wikipedia, the repository of all modern knowledge.

Default values are unexpected

In Go, some types have a default value (probably to deal with the whole static typing thing???). For example, the default value of a boolean is false.

Similarly, ints also have a default value of 0.

So if I initialize a map of strings and ints, I get a number back, even if that key doesn’t exist in the map.

Multiple returns strike again

To solve the default value problem, Go offers optional multiple returns when querying a map/hash.

Now, when I query the map, I can then check the value of ok, which will return false if the key didn’t actually exist in the map.

The multiple return collection is optional. If I remove the ok assignment, Go will not complain.

make() vs literal syntax

There are two ways to initialize a map. You can use the make() syntax:

Or you can use the ‘literal’ syntax, which I’ve used the the previous examples. Arbitrarily, I like the literal syntax. Maybe I just like curly braces.

Resources

A Tour of Go
Go maps in action
Go By Example
Effective Go

Notes on Go, part 6 of ∞

To deal with the idiosyncratic failing test issues from my last go post, I got to do a bunch of stuff with our monorepo and learn a bit more about the Godep tool, and now I know more about why the stuff at the end of this post works.

The solution to my problem was to update the version of sqlmock that I was using. One of the potential issues with monorepos is that if you update a package, you have to update it across the entire monorepo, because of how Go dependencies work. One solution to this problem is to make whoever wants to change versions do all the updates across the repo. Another (less ‘Go’) solution is to have two versions of the dependency in your project. Which is what we did.

It took me a few tries to get everything down in a way that made both Godep and git happy, so here is my recommendation on the order of steps to take.

  1. Checkout your master branch and make sure it is up to date.

  2. Make sure your local Godeps/_workspace is up to date by running the godep restore command. I think this is the one I was having the most trouble with, because ‘restore’ is not what I think I want to do, conceptually. The restore command is (I think) making your local Godep/_workspace match what is in the Godep.json file. So if you’ve messed added ore removed a whole bunch of stuff, and want to start over, the ‘restore’ command is an accurate reflection of what you are doing, but it also works as an ‘update’, which is conceptually what I thought I wanted to do.

  3. Check your git status and make sure you don’t see anything unexpected. In my case, I didn’t expect to see really anything in my status because our Godep folder is checked into git.

  4. If you haven’t already, do a godep get PACKAGE/I/WANT.

  5. Update the import statement(s) in your actual *.go file(s).

  6. To save this into your dependencies, use godep save -r ./.... The -r flag takes care of re-writing any import statements to now point to your Godep/_workspace folder. The ./... makes sure it checks the current folder and all folders inside of it to catch any new imports.

  7. Again, check your git diff. At this point, I expected to see:

– the import changes
– the new package in Godep/_workspace

If it all looks good, commit!

  1. If this update was a breaking version change, now go back and fix your code that it compiles and runs again.

  2. Finish the thing that sent you down this rabbit hole in the first place!

Notes on Go, part 5 of ∞

Problem: We’re working in a Go monorepo. I’ve been writing tests for one package in one service in said monorepo. When I run
godep go test ./directoryofinterest,
I get the following (positive) message:
ok github.com/path/to/my/directoryofinterest 0.019s.

When I run
godep go test ./directoryofinterest -v,
I get several failure messages in the main part of the output, and the last two lines are
FAIL
and
ok github.com/path/to/my/directoryofinterest 0.021.

This is definitely some unexpected behavior.

Working through some of the 11th chapter of The Go Programming Language has surfaced a few idiosyncrasies.

  1. Running go test from the directory where the tests are returns 2 lines, whereas running go test ./directoryofinterest from one directory up returns only one line.

  2. When you get the 2 lines, one is a PASS or FAIL message, and the second is the ok message.

BUT WHYYYY???

Fun fact: it’s because i”m using an old version of Data Dog’s sqlmock.

After updating sqlmock to the current version, I get the expected behavior when running the tests.

Running the go test ./directoryofinterest now returns 1 line when tests pass with the ‘ok’ message. Running the same command with failing tests returns multiple lines with the details of the failure, and the final line contains the FAIL message.

Notes on Go, part 4 of ∞

I learned a fun thing about the html/template package in Go. When compiling your program, it does not check the validity of your template.

I was working through the Writing Web Applications tutorial, and I made the following mistake:

<h1>{{.Title</h1>

There is supposed to be a set of closing brackets after Title.

<h1>{{.Title}}</h1>

However, when I compiled and ran my program, I didn’t get any error messages until I tried to access /view/test. Then, it blew up with a panic message. Reading through the stack trace pretty quickly implicated the Template package, and it was a relatively quick problem to solve.

Notes on Go, part 3 of ∞

Here are my notes on how multiple returns work.

package main

import &quot;fmt&quot;

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

func main() {
    results := split(17)
    fmt.Println(results)
    fmt.Println(split(17))
}

Returns prog.go:12: multiple-value split() in single-value context (Check it out on the Go Playground)

package main

import &quot;fmt&quot;

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

func main() {
    resultsx, resultsy := split(17)
    fmt.Println(resultsx)
    fmt.Println(resultsy)
    fmt.Println(split(17))
}

Returns:

7
10
7 10

(Check it out on the Go Playground)

If a function returns multiple things, you are required to give each of those things a name if you are going to save them to a variable. The exception (so far) is if you directly pass the function to another function that can handle that sort of thing.

If you don’t want to save one of the returns, you can assign it to _, which basically says ‘I know there is going to be something here, throw it out immediately’.

Notes on Go, part 2 of ∞

Why aren’t my test running?

The command go test will only pick up tests in the directory that the command is being run in. To have it find tests in sub-folders, try the command go test ./.... This searches recursively through the sub-folders and finds the hiding tests and runs them.

Tests still aren’t running? If you are using godep to manage dependancies, you can try:

godep get

Still getting error messages á la:

somefolder/some_test.go:10:2: cannot find package &quot;github.com/THING/code&quot; in any of:
    /usr/local/Cellar/go/1.5.1/libexec/src/github.com/THING/code (from $GOROOT)
    ~/code/go/src/github.com/THING/code (from $GOPATH)

Try the following series of commands from the root directory of your project.

godep restore
rm -rf Godeps
godep save ./...
godep go test ./...
go test ./...

Stay tuned for an actual explanation of why any of this works when I figure it out!

Notes on Go, part 1 of ∞

When writing tests in Go, there are a few useful ways to get info printed out to the screen.

  • t.log

Inside the test, you can log stuff using t.log. This will only show up if you use the -v flag when running go test.

  • fmt.PrintLn

Inside the actual program itself, you can print things using an fmt.Print command, and running the tests with the -v flag.

Basically, the -v flag is your friend when you want to see things in your go tests!