Put Go Wherever You Like

posted 6 years ago

I really enjoy writing Go programs. Well everything except:

Go code must be kept inside a workspace. A workspace is a directory hierarchy with three directories at its root:

  • src contains Go source files organized into packages (one package per directory),
  • pkg contains package objects, and
  • bin contains executable commands.

The go tool builds source packages and installs the resulting binaries to the pkg and bin directories.

-- The Docs

Oh! Golang! Why so many rules?

On unix based file systems, you can create symbolic links which are basically pointers to a file or folder somewhere else in the file system. For example:

# create a file
touch a.txt

# create a symbolic link to a.txt
ln -s a.txt b.txt

# manipulate b.txt
echo 'hello' > b.txt

# the change is reflected in a.txt
cat a.txt
#> hello

As you can see, the symlink acts like the file itself. Here are a few more properties just for fun, and then a solution to the oppressive structure rules.

# removing the symlink doesn't remove the file
rm b.txt
ls
#> a.txt

# removing the file doesn't remove the symlink
ln -s a.txt b.txt
rm a.txt
echo 'come back' > b.txt
cat a.txt
#> come back

# you can point to pointers too
ln -s a.txt b.txt
ln -s b.txt c.txt
echo 'peace' > c.txt
cat a.txt
#> peace

It's also possible to symlink folders. For example:

mkdir a
ln -s a b
touch b/file.txt
ls a
#> file.txt

Important: do not try to symlink to an empty directory. The link will be added to the directory instead of overwriting the empty directory.

mkdir c
ln -s a c
tree c
#> c
#> └── a -> a

Go Structure

Suppose I want to keep Go server code near my javascript client code, for example:

/projects
  /project
    /web
      index.js
    /server
      main.go

However Go wants my code in the Go workspace.

/src
  /github.com
    /company
      /project-server
        main.go

Symbolic link the Go workspace folder into the project folder, and we're good.

cd $GOPATH
mkdir ~/projects/project
mkdir src/github.com/company/project-server
ln -s src/github.com/company/project-server ~/projects/project/server
cd ~/projects/project/server

You can use git, the go command, everything. It should just work, but tweet @aj0strow if something breaks.