The Coding Mant.is

Smashing Through Code

Code spelunking to build a CF Plugin — 5-December-2014

Code spelunking to build a CF Plugin

This is a quick “how to” for how Long found the information he needed to build the cf info plugin.

Following a trail of breadcrumbs

Determine the requirements:

  1. Print the currently targeted org and space
  2. Print the API version and endpoint
  3. Print the user id of the current user (similar to whoami in *nix OSes).

Fulfilling the requirements:

This information comes from cf target, so first we’ll take a look in target.go.

  • Line 83 in target.go prints the current session information as reported from ui.go.
  • Line 196 in ui.go references a UserEmail method.
  • Line 175 of ui.go shows that config is actually from the core_config package.
  • There are a few *.go files in the core_config package, but searching this repository for UserEmail shows that the method is defined in config_repository.go on lines 199-204.
  • UserEmail requires a struct, called ConfigRepository.
  • ConfigRepository is built from the NewRepositoryFromPersistor method. (You can tell this both by the return &ConfigRepository on line 23 or by noting that NewRepositoryFromPersistor returns all the fields needed by the struct – i.e. data, mutex, initOnce, persistor, and onError.)
  • NewRepositoryFromPersistor is returned from the method above it, NewRepositoryFromFilepath.

How to get the file path? Searching for CF_HOME (environmental variable storing the home directory) shows that it is defined in config_helpers.go. Now what to do with that information:

  • The DefaultFilePath is defined using either $CF_HOME/.cf or $HOME/.cf ($HOME is the user’s home directory in Unix environments).
    • As a sanity check, if you are using a Unix environment run echo $CF_HOME. If it is non-empty, then run less $CF_HOME/.cf/config.json. If it is empty, run less $HOME/.cf/config.json. You should see the configuration file that cf target uses to report the org, space, and API information (there is other information in there as well).
  • Recall that UserEmail is defined in lines 199-204 of config_repository.go. You can see that config_repository.go also has the other information we wish to pull – the org (OrganizationFields), space (SpaceFields), API endpoint (ApiEndpoint), and API version (ApiVersion).

What to do with all of that

Basically everything in reverse. You supply the default file path, which is config.json, to NewRepositoryFromFilepath. config.json has the org, space, API endpoint, API version, and Access Token. The existing cf code decodes the Access Token and the UserEmail method extracts the email address from that information. Everything is just pulled directly from the repository you just defined.

Addendum: What is going on to get that email anyway?

Let’s take a quick look in config.json. The 7th line should be the Access Token, which should look similar to this:

"AccessToken": "bearer eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI3NzI2ZDE2MS1hNWUzLTQwZjMtYTEzYy00OTlmMDNjOTBhZGIiLCJzdWIiOiI2Y2I5MTA0Yy1hZTMxLTQxYTMtOGQ4MS1jYjUxZjg0MTk5ZTMiLCJzY29wZSI6WyJjbG91ZF9jb250cm9sbGVyLmFkbWluIiwiY2xvdWRfY29udHJvbGxlci5yZWFkIiwiY2xvdWRfY29udHJvbGxlci53cml0ZSIsIm9wZW5pZCIsInBhc3N3b3JkLndyaXRlIiwic2NpbS5yZWFkIiwic2NpbS53cml0ZSJdLCJjbGllbnRfaWQiOiJjZiIsImNpZCI6ImNmIiwiZ3JhbnRfdHlwZSI6InBhc3N3b3JkIiwidXNlcl9pZCI6IjZjYjkxMDRjLWFlMzEtNDFhMy04ZDgxLWNiNTFmODQxOTllMyIsInVzZXJfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsImlhdCI6MTQxNzgxMTU3NywiZXhwIjoxNDE3ODEyMTc3LCJpc3MiOiJodHRwczovL3VhYS41NC4xNzQuMjI5LjExOS54aXAuaW8vb2F1dGgvdG9rZW4iLCJhdWQiOlsic2NpbSIsIm9wZW5pZCIsImNsb3VkX2NvbnRyb2xsZXIiLCJwYXNzd29yZCJdfQ.XNaYq8rxpvwWx9kySIDqbKs0BuyeOMMwAPb5YQaT-9MIyr3YalCE_2gTg-fl0xulj4u-VoNme3OGZ2T3tFFUfBKgo3U7R_pl5OpcaetKslbvKtYpne7N30KMQySMqVVVooGqlReoI_n5m5O7ZIASiG8P1QtwuVrZPkPhbjsGfBE",

Source: The above is the access token from a now-destroyed TryCF instance.

This is a JSON Web Token (JWT). You can read about JWT here. For now, all I really care about is that its structure is <header>.<claims>.<signature>. The <claims> section of the above token is between the two periods:

eyJqdGkiOiI3NzI2ZDE2MS1hNWUzLTQwZjMtYTEzYy00OTlmMDNjOTBhZGIiLCJzdWIiOiI2Y2I5MTA0Yy1hZTMxLTQxYTMtOGQ4MS1jYjUxZjg0MTk5ZTMiLCJzY29wZSI6WyJjbG91ZF9jb250cm9sbGVyLmFkbWluIiwiY2xvdWRfY29udHJvbGxlci5yZWFkIiwiY2xvdWRfY29udHJvbGxlci53cml0ZSIsIm9wZW5pZCIsInBhc3N3b3JkLndyaXRlIiwic2NpbS5yZWFkIiwic2NpbS53cml0ZSJdLCJjbGllbnRfaWQiOiJjZiIsImNpZCI6ImNmIiwiZ3JhbnRfdHlwZSI6InBhc3N3b3JkIiwidXNlcl9pZCI6IjZjYjkxMDRjLWFlMzEtNDFhMy04ZDgxLWNiNTFmODQxOTllMyIsInVzZXJfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsImlhdCI6MTQxNzgxMTU3NywiZXhwIjoxNDE3ODEyMTc3LCJpc3MiOiJodHRwczovL3VhYS41NC4xNzQuMjI5LjExOS54aXAuaW8vb2F1dGgvdG9rZW4iLCJhdWQiOlsic2NpbSIsIm9wZW5pZCIsImNsb3VkX2NvbnRyb2xsZXIiLCJwYXNzd29yZCJdfQ

If you paste that information into Base 64 Decode, you can see the user’s credentials – including the email field. (For TryCF the user_name and email are both admin.) If you paste in the above and decode it, you will see:

{"jti":"7726d161-a5e3-40f3-a13c-499f03c90adb","sub":"6cb9104c-ae31-41a3-8d81-cb51f84199e3","scope":["cloud_controller.admin","cloud_controller.read","cloud_controller.write","openid","password.write","scim.read","scim.write"],"client_id":"cf","cid":"cf","grant_type":"password","user_id":"6cb9104c-ae31-41a3-8d81-cb51f84199e3","user_name":"admin","email":"admin","iat":1417811577,"exp":1417812177,"iss":"https://uaa.54.174.229.119.xip.io/oauth/token","aud":["scim","openid","cloud_controller","password"]}

Feel free to try it with your own Access Token! :)

[From my work blog here.]

PS – It’s not a Wednesday, but most of my work related blog posts are going to be Wednesday so to keep it all together…

How To Install Go on Digital Ocean with a CentOS7 Droplet — 3-December-2014

How To Install Go on Digital Ocean with a CentOS7 Droplet

I will mostly be following the instructions from here, but instead of Ubuntu I am going to try CentOS.

Getting Started

All you will need to start, aside from the obvious internet connection, is a Digital Ocean account. I’ve found that the $5/mo. plan is really good for learning.

Spin up your droplet

This is actually pretty straightforward. Your regional preferences may differ, but here are what my settings looked like:

You’ll immediately see a progress bar to show you how quickly the droplet is being started:

Actually, it took less than 60 seconds total to completely spin that up. This is my first experience with Digital Ocean, so I’m pretty impressed with that.

Once the droplet is up and running, you will receive an email similar to this one, that will include your login credentials:


Yes, that is Google Inbox. It’s shiny, right?

Use these to SSH into your new droplet:

$ ssh digital-ocean
The authenticity of host '[address] ([address])' can't be established.
RSA key fingerprint is [key].
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[address]' (RSA) to the list of known hosts.
root@[address]'s password:
You are required to change your password immediately (root enforced)
Changing password for root.
(current) UNIX password:
New password:
Retype new password:
[root@centos-dev ~]#

(Note that I updated my ~/.ssh/config file to include the hostname and user name for this droplet and provided it the alias digital-ocean. If you do not do this, then you can simply SSH into the address provided in the credentials email.)

Create a new user

According to the Ubuntu instructions provided, the next step is to create a new user account. Pretty straightforward, but since the commands are a little different for CentOS7, I am using Digital Ocean’s Initial Server Setup with CentOS 7 instructions. Here I am creating a new user, providing that user with superuser privileges, and changing accounts into the new user account:

[root@centos-dev ~]# adduser quinn
[root@centos-dev ~]# passwd quinn
Changing password for user quinn.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@centos-dev ~]# gpasswd -a quinn wheel
Adding user quinn to group wheel
[root@centos-dev ~]# su quinn
[quinn@centos-dev root]$

To create your own user, simply replace quinn with your desired username.

Installing Go

The Ubuntu instructions use apt-get for this, but CentOS does not have apt-get available. But we’re in luck! We can just run sudo yum install golang (or run the command as root) to install the latest release of Go (yes, there is a lot of output):

[quinn@centos-dev root]$ sudo yum install golang

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for quinn:
Loaded plugins: fastestmirror
base                                                     | 3.6 kB     00:00
extras                                                   | 3.4 kB     00:00
updates                                                  | 3.4 kB     00:00
(1/4): extras/7/x86_64/primary_db                          |  35 kB   00:00
(2/4): base/7/x86_64/group_gz                              | 157 kB   00:00
(3/4): updates/7/x86_64/primary_db                         | 4.8 MB   00:01
(4/4): base/7/x86_64/primary_db                            | 4.9 MB   00:01
Determining fastest mirrors
 * base: mirror.ash.fastserv.com
 * extras: mirrors.advancedhosters.com
 * updates: mirrors.lga7.us.voxel.net
Resolving Dependencies
--> Running transaction check
---> Package golang.x86_64 0:1.3.3-1.el7.centos will be installed
--> Processing Dependency: golang-src for package: golang-1.3.3-1.el7.centos.x86_64
--> Processing Dependency: golang-bin for package: golang-1.3.3-1.el7.centos.x86_64
--> Running transaction check
---> Package golang-pkg-bin-linux-amd64.x86_64 0:1.3.3-1.el7.centos will be installed
--> Processing Dependency: golang-pkg-linux-amd64 = 1.3.3-1.el7.centos for package: golang-pkg-bin-linux-amd64-1.3.3-1.el7.centos.x86_64
--> Processing Dependency: golang-pkg-linux-amd64 = 1.3.3-1.el7.centos for package: golang-pkg-bin-linux-amd64-1.3.3-1.el7.centos.x86_64
--> Processing Dependency: gcc for package: golang-pkg-bin-linux-amd64-1.3.3-1.el7.centos.x86_64
---> Package golang-src.noarch 0:1.3.3-1.el7.centos will be installed
--> Running transaction check
---> Package gcc.x86_64 0:4.8.2-16.2.el7_0 will be installed
--> Processing Dependency: cpp = 4.8.2-16.2.el7_0 for package: gcc-4.8.2-16.2.el7_0.x86_64
--> Processing Dependency: glibc-devel >= 2.2.90-12 for package: gcc-4.8.2-16.2.el7_0.x86_64
--> Processing Dependency: libmpfr.so.4()(64bit) for package: gcc-4.8.2-16.2.el7_0.x86_64
--> Processing Dependency: libmpc.so.3()(64bit) for package: gcc-4.8.2-16.2.el7_0.x86_64
---> Package golang-pkg-linux-amd64.noarch 0:1.3.3-1.el7.centos will be installed
--> Running transaction check
---> Package cpp.x86_64 0:4.8.2-16.2.el7_0 will be installed
---> Package glibc-devel.x86_64 0:2.17-55.el7_0.1 will be installed
--> Processing Dependency: glibc-headers = 2.17-55.el7_0.1 for package: glibc-devel-2.17-55.el7_0.1.x86_64
--> Processing Dependency: glibc-headers for package: glibc-devel-2.17-55.el7_0.1.x86_64
---> Package libmpc.x86_64 0:1.0.1-3.el7 will be installed
---> Package mpfr.x86_64 0:3.1.1-4.el7 will be installed
--> Running transaction check
---> Package glibc-headers.x86_64 0:2.17-55.el7_0.1 will be installed
--> Processing Dependency: kernel-headers >= 2.2.1 for package: glibc-headers-2.17-55.el7_0.1.x86_64
--> Processing Dependency: kernel-headers for package: glibc-headers-2.17-55.el7_0.1.x86_64
--> Running transaction check
---> Package kernel-headers.x86_64 0:3.10.0-123.9.3.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package                       Arch      Version               Repository  Size
================================================================================
Installing:
 golang                        x86_64    1.3.3-1.el7.centos    extras     2.6 M
Installing for dependencies:
 cpp                           x86_64    4.8.2-16.2.el7_0      updates    5.9 M
 gcc                           x86_64    4.8.2-16.2.el7_0      updates     16 M
 glibc-devel                   x86_64    2.17-55.el7_0.1       updates    1.0 M
 glibc-headers                 x86_64    2.17-55.el7_0.1       updates    650 k
 golang-pkg-bin-linux-amd64    x86_64    1.3.3-1.el7.centos    extras      11 M
 golang-pkg-linux-amd64        noarch    1.3.3-1.el7.centos    extras     6.6 M
 golang-src                    noarch    1.3.3-1.el7.centos    extras     5.5 M
 kernel-headers                x86_64    3.10.0-123.9.3.el7    updates    1.4 M
 libmpc                        x86_64    1.0.1-3.el7           base        51 k
 mpfr                          x86_64    3.1.1-4.el7           base       203 k

Transaction Summary
================================================================================
Install  1 Package (+10 Dependent packages)

Total download size: 51 M
Installed size: 181 M
Is this ok [y/d/N]: y
Downloading packages:
(1/11): cpp-4.8.2-16.2.el7_0.x86_64.rpm                    | 5.9 MB   00:01
(2/11): gcc-4.8.2-16.2.el7_0.x86_64.rpm                    |  16 MB   00:02
(3/11): glibc-devel-2.17-55.el7_0.1.x86_64.rpm             | 1.0 MB   00:01
(4/11): glibc-headers-2.17-55.el7_0.1.x86_64.rpm           | 650 kB   00:00
(5/11): kernel-headers-3.10.0-123.9.3.el7.x86_64.rpm       | 1.4 MB   00:00
(6/11): golang-1.3.3-1.el7.centos.x86_64.rpm               | 2.6 MB   00:00
(7/11): libmpc-1.0.1-3.el7.x86_64.rpm                      |  51 kB   00:00
(8/11): golang-pkg-bin-linux-amd64-1.3.3-1.el7.centos.x86_ |  11 MB   00:01
(9/11): mpfr-3.1.1-4.el7.x86_64.rpm                        | 203 kB   00:00
(10/11): golang-src-1.3.3-1.el7.centos.noarch.rpm          | 5.5 MB   00:01
(11/11): golang-pkg-linux-amd64-1.3.3-1.el7.centos.noarch. | 6.6 MB   00:06
--------------------------------------------------------------------------------
Total                                              5.5 MB/s |  51 MB  00:09
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : mpfr-3.1.1-4.el7.x86_64                                     1/11
  Installing : libmpc-1.0.1-3.el7.x86_64                                   2/11
  Installing : cpp-4.8.2-16.2.el7_0.x86_64                                 3/11
  Installing : kernel-headers-3.10.0-123.9.3.el7.x86_64                    4/11
  Installing : glibc-headers-2.17-55.el7_0.1.x86_64                        5/11
  Installing : glibc-devel-2.17-55.el7_0.1.x86_64                          6/11
  Installing : gcc-4.8.2-16.2.el7_0.x86_64                                 7/11
  Installing : golang-src-1.3.3-1.el7.centos.noarch                        8/11
  Installing : golang-pkg-linux-amd64-1.3.3-1.el7.centos.noarch            9/11
  Installing : golang-1.3.3-1.el7.centos.x86_64                           10/11
  Installing : golang-pkg-bin-linux-amd64-1.3.3-1.el7.centos.x86_64       11/11
  Verifying  : cpp-4.8.2-16.2.el7_0.x86_64                                 1/11
  Verifying  : golang-pkg-bin-linux-amd64-1.3.3-1.el7.centos.x86_64        2/11
  Verifying  : golang-1.3.3-1.el7.centos.x86_64                            3/11
  Verifying  : gcc-4.8.2-16.2.el7_0.x86_64                                 4/11
  Verifying  : golang-src-1.3.3-1.el7.centos.noarch                        5/11
  Verifying  : kernel-headers-3.10.0-123.9.3.el7.x86_64                    6/11
  Verifying  : glibc-devel-2.17-55.el7_0.1.x86_64                          7/11
  Verifying  : mpfr-3.1.1-4.el7.x86_64                                     8/11
  Verifying  : glibc-headers-2.17-55.el7_0.1.x86_64                        9/11
  Verifying  : libmpc-1.0.1-3.el7.x86_64                                  10/11
  Verifying  : golang-pkg-linux-amd64-1.3.3-1.el7.centos.noarch           11/11

Installed:
  golang.x86_64 0:1.3.3-1.el7.centos

Dependency Installed:
  cpp.x86_64 0:4.8.2-16.2.el7_0
  gcc.x86_64 0:4.8.2-16.2.el7_0
  glibc-devel.x86_64 0:2.17-55.el7_0.1
  glibc-headers.x86_64 0:2.17-55.el7_0.1
  golang-pkg-bin-linux-amd64.x86_64 0:1.3.3-1.el7.centos
  golang-pkg-linux-amd64.noarch 0:1.3.3-1.el7.centos
  golang-src.noarch 0:1.3.3-1.el7.centos
  kernel-headers.x86_64 0:3.10.0-123.9.3.el7
  libmpc.x86_64 0:1.0.1-3.el7
  mpfr.x86_64 0:3.1.1-4.el7

Complete!

Now the moment of truth:

[quinn@centos-dev root]$ go version
go version go1.3.3 linux/amd64

Awesome.

Environmental Variables

If you check your environmental variables, you will see that references to Go are “mysteriously” missing:

[quinn@centos-dev root]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[quinn@centos-dev root]$ echo $GOPATH

[quinn@centos-dev root]$

In CentOS you have a ~/.bash_profile file that you can update to handle this. By default, it will look a little something like this:

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

Update the file to include $GOPATH and make sure to append the bin subdirectory of your $GOPATH to your $PATH variable:

export GOPATH=$HOME/go
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$GOPATH/bin

After you source your ~/.bash_profile file, you should now have the appropriate values for these variables:

[quinn@centos-dev root]$ source ~/.bash_profile
[quinn@centos-dev root]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/quinn/.local/bin:/home/quinn/bin:/home/quinn/go/bin
[quinn@centos-dev root]$ echo $GOPATH
/home/quinn/go

Excellent.

Note: You can also see all of your Go environment information using go env:

[quinn@centos-dev bin]$ go env
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/quinn/go"
GORACE=""
GOROOT="/usr/lib/golang"
GOTOOLDIR="/usr/lib/golang/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

Installing Git & Mercurial

In order to “get” revel (next step) we need both git and hg (Mercurial). To install, simply run:

[quinn@centos-dev ~]$ sudo yum install git
[quinn@centos-dev ~]$ sudo yum install hg

For brevity, I am not including the output. The install is actually very speedy (rock on Digital Ocean!), but there were a lot of dependencies in both cases.

Sidenote: How to determine if you need Git, Hg, or both
For me, it was a case of trial and error. When I attempted to “get” revel with out both Git and Hg, I received an error that I did not have the other package. i.e. When I only had git, I received the error go: missing Mercurial command.. Likewise, when I only had Hg, then I received the error go: missing Git command.

Installing EPEL

You will also need EPEL. To install, I followed these instructions.

[quinn@centos-dev ~]$ cd /tmp
[quinn@centos-dev tmp]$ sudo yum install wget
[quinn@centos-dev tmp]$ wget https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-2.noarch.rpm

Again, for brevity, I have not included the install output.

Sidenote: yum install method
I also tried sudo yum install epel-release-7-2.noarch.rpm, but received the following message: No package epel-release-7-2.noarch.rpm available.

Installing Revel

To install Revel we need to use go get. Good thing we installed git and hg, eh?

[quinn@centos-dev tmp]$ go get github.com/revel/cmd/revel

(If all goes smoothly, you should have no output.)

Now for the moment of truth:

[quinn@centos-dev tmp]$ revel run github.com/revel/revel/samples/chat
~
~ revel! http://revel.github.io
~
2014/12/03 21:10:19 revel.go:326: Loaded module static
2014/12/03 21:10:19 revel.go:326: Loaded module testrunner
2014/12/03 21:10:19 run.go:57: Running chat (github.com/revel/revel/samples/chat) in dev mode
2014/12/03 21:10:19 harness.go:165: Listening on :9000

SUCCESS.

Addenda

  • go get uses the same type of version control system as the package that you are “getting”.
  • As a new user to CentOS I am still not 100% clear what EPEL provides for the revel install – however without it you will be plagued with errors.

This is a copy of my work blog post.

New languages, new woes: tonight’s Golang roadblock — 18-September-2014

New languages, new woes: tonight’s Golang roadblock

Right now I’m working on learning Go by writing a small app that will, eventually, take a Markdown file and convert it to an HTML presentation. When I started working on my program today, my code wouldn’t compile. It was referring to missing packages/etc. I thought, well this can’t be good.

First step, check $GOPATH and $GOROOT. In my case, $GOROOT was null and $GOPATH was returning its old value. (Now that I’ve figured out what’s going on, I’m pretty sure that those more experienced than I already know where this is going…) I fixed $GOPATH to include the new path and $GOROOT to, IIRC, /usr/local/go. Then I checked my $PATH variable and thankfully that was still fine.

I tried running my program again, only to encounter this lovely gem*:

/usr/local/go/pkg/tool/darwin_amd64/6g: unknown flag -trimpath

I had NO idea what this error meant, so I googled for it. It took a little time for me to find something useful, but thankfully Stack Overflow came to my rescue (…again). I learned that I needed to reinstall Go after first making sure I removed the current version. Lovely.

I head over to the Go project page and check how to uninstall Go. Short and sweet, everything seemed fine. Then I download the current installer for Mac OS X, which as of this writing is for 1.3.1, and off I go.

I re-open terminal and try to run my little app. Unfortunately, I still have import problems (I wish I had saved those errors to paste in here, sorry guys). I try to reinstall blackfriday, which is a Markdown processor in Go:

$ go get github.com/russross/blackfriday
# github.com/russross/blackfriday
../../russross/blackfriday/sanitize.go:6: import /Users/ladyivangrey/Development/Go/pkg/darwin_amd64/code.google.com/p/go.net/html.a: object is [darwin amd64 go1.3 X:precisestack] expected [darwin amd64 go1.3.1 X:precisestack]

Great. I have NO idea what this means as it appears that the expected and fond objects are the same. So I “phone a friend”.

His first question? “Are you running more than one version of Go?”

So I tell him: No. Well, I hope not. Maybe. I’m not trying to. So I tell him the story: when I first downloaded Go I just wanted to put it somewhere, so I had it on my Desktop. Then I decided that was a bad idea. So I moved it to ~/Development which is where I have all my other code projects. Then I tried updating the various environmental variables and it all seemed fine. Until I reopened terminal. So I removed the old, I think, to install the new.

He had me check the version using the explicit path to the command. I then tried running it without the path, to see if the output differed:

$ go version
go version go1.3 darwin/amd64

$ /usr/local/go/bin/go version
go version go1.3.1 darwin/amd64

Yeah. Two versions of Go. To see where the other version of Go was installed, I ran “which go”:

$ which go
/usr/local/bin/go

Ah. See. There it is then. Great.

Before removing the “old” version of Go I updated my ~/.bash_profile to the current path I am using for Go: ~/Development/Go/. Then I closed and re-opened Terminal and everything was fine:

$ go run main.go -inputFile=~/Development/temp/myfile.md -log=info
2014-09-18 20:33:23.509 INFO Starting gopress
2014-09-18 20:33:23.511 WARNING Output directory unspecified or does not exist, creating new directory: /Users/ladyivangrey/Development/temp/myfile/
2014-09-18 20:33:23.514 INFO Successfully created new directory.
2014-09-18 20:33:23.517 INFO Successfully copied files.
2014-09-18 20:33:23.517 INFO Exited with no errors.

I even ran “go get” successfully, which after all this was a relief.

Then the magic happened, removing the old version:

$ rm /usr/local/bin/go

And everything was right again in my world. Good grief.

*I suppose I should use the term “gem” with caution since I may run into Ruby again. Don’t want to give it any ideas.
** Also posted this article on my employer’s blog.

Design a site like this with WordPress.com
Get started