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.

Tips and Tricks: Intermediate Git configuration

There are several ‘levels’ at which you can configure git. The three I know about are:

  • repository-level
  • repository branch-level
  • global

They are slightly self explanatory.

  • repository branch-level means that the configurations/aliases are applied ONLY to a specific branch in that repository. I haven’t had a need to use this one yet, so I can’t tell you a ton about it.
  • repository-level means that the configurations/aliases are applied ONLY to that repository, but to all branches on that repository. This can be configured to use different email addresses to different projects (ex: work email vs personal email), among other things.
  • global means that the configurations/aliases are applied to ALL git repositories on your system.

So, how do we set this up?

From the command line

Most of the tutorials on how to set up aliases give the command line version.

In your git repository, you can type git config XXX (where XXX is filler for whatever configuration you want to set). To set the configurations globally, you can type git config --global XXX. Adding the --global flag sets it for all git repositories. Some examples:

git config --global user.name "Clare Glinka"
– This sets my name as “Clare Glinka” for all repos.

git config --global user.email myemail@example.com
– This sets my email as myemail@example.com for all repos.

git config merge.ff false
– disables fast-forward merges by default at the repository level. Fast-forward merging will be disabled for all branches in that repo. Adding the --global flag will disable fast-forward merging for ALL repos.

You can check out other configuration settings in the Git documentation on customizing your git configuration and the git-config manual page.

Now that we’ve set some configs, how do we look at them? (because nothing is real till we see the output, right?)

git config --list will list all the configuration settings for your current directory/branch, including things like your remotes.

git config --list --global will list all the configurations settings for your system. For me, this is a much shorter list, since it does not include things like remotes.

Edit .gitconfig

There is another way to set configurations that I find a little easier to look at sometimes. That is checking out the .gitconfig file. For your global settings, .gitconfig lives in your ~ directory, and you can open it up and edit it with your favorite text editor. You can check out your repository-level configuration file by looking at REPO/.git/config.

References

First-Time Git Setup
Customizing Git Configuration
git-config Manual Page
StackOverflow: Can I make fast forwarding be off by default in git?
Git Tip: git config user name and email for local (not global) config

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 "github.com/THING/code" 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!

Writing regular expressions in the context of a new programming language

One of the things that is kind of annoying about regular expressions is that every programming language implements them slightly differently. If you can, find someone who can give you the low-down in this new language. Otherwise, you’ll have to stick with googling, which can take a while to figure out what you need. I’ll get you started with a few languages.

General Resources

Two of my favorite and most helpful resources:

  • RegExPlanet.com: lets you test regular expressions in many different languages.
  • Regex Cheat Sheet: has a pretty comprehensive general overview of regex syntax.

Regular Expressions in Ruby

One of the easiest ways to get started with regular expressions in Ruby is via Rubular.com. This site provides a way to test regular expressions against any text, as well as a quick cheat sheet to help. RegExPlanet.com also has a Ruby tester that is in beta.

Regular Expressions in Java

For help with Java, I really like using the tester at RegExPlanet.com. It does two really cool things.

  1. Different Java methods (apparently) use regular expressions differently. RegExPlanet.com shows if and how a regular expression will work with each of the methods.
  2. RegExPlanet.com also provides the ‘Java string’ for use in Java methods. In Java, we have to escape the backslashes with additional backslashes. This can get pretty confusing very quickly, so having RegExPlanet.comgenerate that string for me is very helpful.

Regular Expressions in JavaScript

Using regular expressions in JavaScript was where I really began using the pattern modifiers. If a regular expression is between two forward slashes, pattern modifiers are the letters that come after the last forward slash.

/hello/i

This regular expression will match the word ‘hello’ as well as capitalized ‘Hello’, and all caps ‘HELLO’. It will even match the super fancy ‘hElLo’, if you are into crazy stuff like that. The i modifier tells the regular expression to be case-insensitive.

Another really useful modifier for regular expressions in JavaScript is g, which stands for ‘global’. In JavaScript, regular expressions will find the first time it matches a pattern and then stop. Using the g modifier tells it to find ALL the instances where a string matches the given pattern.

Tips and Tricks: Useful Regular Expressions

I’ve learned a whole lot about regular expressions over the last year and a bit, and there are two ‘phrases’ for lack of a better term that are sort of like the nuclear option or like a blunt object, but will get me most of where I need to go.

Phrase 1: .*?

This is one of the most useful regular expression ‘phrases’ I’ve learned. It selects zero or more of any kind of character, including spaces, but isn’t greedy. (That just means that it’ll stop the first time it sees whatever is put after the question mark). The key limitation of this phrase is that it will not include new lines (though the exact implementation varies from language to language).

Phrase 2: .+?

Related to the first phrase, this one selects one or more of any kind of character, including spaces, but isn’t greedy. This is useful when something has to exist, but can be any number of things. Like the one before it, this (usually) doesn’t include new lines.

Phrase 3: [\s\S]*?

This ‘phrase’ is even more ‘powerful’ than the one above. This one selects zero or more of any kind of character, including all kinds of whitespace (yes, also new lines), but again, isn’t greedy. I used this one a LOT for a while, especially in Java.

Get creative

I was having trouble getting a regular expression to select an section of HTML that was broken up onto different lines irregularly 1. Finally I figured out that I wanted to use \s*? (zero or more whitespace characters, not greedy) to account for the different amounts of spacing, but not to pick up any letters or other characters.


  1. yes, I know regex is not the tool of choices for HTML, but my hands were a bit tied on this project 

Tips and Tricks: Gem pristine

A while ago, some friends and I were doing some code exploration inside gems, trying to figure out how they worked. All was well and good until we had changed everything and broke the gem. Here are a few great commands for playing around with this stuff, and then resetting it when you are done so everything on your system still works the way it is supposed to.

To open a gem in your default text editor and poke around it’s squishy inner bits:

bundle open GEMNAME

EX:

bundle open rake

Once you are done playing around and just want things to go back to the way they were, there are two good commands to know.

For when you have bundler set up to install gems to a local vendor directory, and that is the gem you were playing with:

bundle exec gem pristine GEMNAME

Or if you want to restore all the possible versions of a gem:

gem pristine GEMNAME

Happy hacking!

Markdown for Readme’s

It seems a lot of people crank about writing documentation, so I wasn’t looking forward to writing some for Wikiwhat, but I knew it was important, not just to for the sake of doing it, but because as the n00biest of n00bs, I wanted someone with no idea of how things work to be able to use our gem easily, on the off chance anyone would want to use it. However, it turned out that writing the documentation for Wikiwhat was way easier than writing lab reports or manuscripts, and I had a lot of fun doing it.

If you have never used markdown before, this page is a good summary of the basics of markdown syntax.

Use Mou

Mou is a great Markdown editor that shows you what you markdown will look like as you are writing it. I found this really helpful as I was experimenting with the different formatting options in Markdown. It can also do a bunch of other fancy things. The one catch is that it does not currently support Github-flavored Markdown, so Github-specific Markdown will not be rendered correctly. To check anything Github-specific, you will have to check out one of the Github-flavored markdown previewers.

Make Internal Links

This one tripped me up for a while, but it’s secretly really easy.

[Google](http://google.com)

gives a link to google like so:

Google

But I wanted to make links within a page, so someone reading the README could jump to the section they wanted to read without scrolling though the whole page. Github makes this easy by turning any header into an internal anchor point!

[Usage](#usage)

will make a link to the ‘Usage’ header lower down on the page. If the header text is more than one word, the text is converted to all lowercase with dashes (-) replacing the spaces, like so:

[A Header With Multiple Words](#a-header-with-multiple-words)

Specify the language

You will probably want to have code examples in your README. Github will syntax-highlight them for you correctly if you tell it what language it is. When you make a code fence, specify the language immediately after the first ‘fence’ for correct syntax hilighting.

```ruby
<ruby code>
```

Tips and Tricks: JSON in IRB or Pry

Trick one: Parse your raw JSON objects when you pull them in.

For our Ruby Gem project, we were pulling down JSON-formatted data from the Wikipedia  API. To successfully work with JSON in IRB, I imported the object with an HTTP gem and then parsed the JSON data with the JSON gem. EX:

require 'json' 
require 'rest_client' 
JSON.parse(RestClient.get <URL>)

Which gives us a nice Hash output that looks like this:

{"query-continue"=&gt;
    {"images"=&gt;
        {"gimcontinue"=&gt;"736|Citizen-Einstein.jpg"}},
    "query"=&gt;
        {"pages"=&gt;
            {"-1"=&gt;{"ns"=&gt;6, "title"=&gt;"File:1919 eclipse positive.jpg", "missing"=&gt;""},
             "-2"=&gt;{"ns"=&gt;6, "title"=&gt;"File:Albert Einstein's exam of maturity grades (color2).jpg", "missing"=&gt;""}}}}

Without parsing, the information was still in JSON format, a thing that looked like:

"{\"query-continue\":{\"images\":{\"gimcontinue\":\"736|Citizen-Einstein.jpg\"}},\"query\":  ...

with extra quotation marks and all the backslashes, and Ruby got pretty cranky about trying to work with that string.

Trick Two: ‘puts’ your JSON

For another project, I was converting hashes into JSON, and I was getting a bit frustrated. I was quite certain that I was converting the hash into JSON correctly, but I kept getting extraneous backslash-escaped quotation marks in my JSON returns like before.

"{\"query-continue\":{\"images\":{\"gimcontinue\":\"736|Citizen-Einstein.jpg\"}}, ...

Thanks to some StackOverflow googling, I realized/remembered that this was because I was directly calling the JSON in the console, instead of puts-ing it from within the script I was running. When I used a puts statement inside the script, I could see that my output was actually formatted correctly, as I expected. Using puts in the console also worked to show me the JSON with it’s correct formatting.

puts <JSON>

instead of

<JSON>