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