From 6d80ce514e3b2ec096d713ab6e448caa25c22dbf Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Thu, 11 Jul 2013 21:27:58 -0400 Subject: go+ --- README.md | 1 + goplus.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ res/go+ | 27 +++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 goplus.md create mode 100755 res/go+ diff --git a/README.md b/README.md index e11fbfe..decf5fb 100644 --- a/README.md +++ b/README.md @@ -3,5 +3,6 @@ This is my here blog. It's not much at the moment (one post? booyah!), but maybe Maybe not * [Erlang, tcp sockets, and active true](erlang-tcp-socket-pull-pattern.md) (originally posted March 9, 2013) +* [go+](goplus.md) (originally posted July 11, 2013) That's all folks! diff --git a/goplus.md b/goplus.md new file mode 100644 index 0000000..c9b0191 --- /dev/null +++ b/goplus.md @@ -0,0 +1,59 @@ +# Go and project root + +Compared to other languages go has some strange behavior regarding its project root settings. If you +import a library called `somelib`, go will look for a `src/somelib` folder in all of the folders in +the `$GOPATH` environment variable. This works nicely for globally installed packages, but it makes +encapsulating a project with a specific version, or modified version, rather tedious. Whenever you go +to work on this project you'll have to add its path to your `$GOPATH`, or add the path permanently, +which could break other projects which may use a different version of `somelib`. + +My solution is in the form of a simple script I'm calling go+. go+ will search in currrent directory +and all of its parents for a file called `GOPROJROOT`. If it finds that file in a directory, it +prepends that directory's absolute path to your `$GOPATH` and stops the search. Regardless of whether +or not `GOPROJROOT` was found go+ will passthrough all arguments to the actual go call. The +modification to `$GOPATH` will only last the duration of the call. + +As an example, consider the following: +``` +/tmp + /hello + GOPROJROOT + /src + /somelib/somelib.go + /hello.go +``` + +If `hello.go` depends on `somelib`, as long as you run go+ from `/tmp/hello` or one of its children +your project will still compile + +Here is the source code for go+: + +```bash +#!/bin/sh + +SEARCHING_FOR=GOPROJROOT +ORIG_DIR=$(pwd) + +STOPSEARCH=0 +SEARCH_DIR=$ORIG_DIR +while [ $STOPSEARCH = 0 ]; do + + RES=$( find $SEARCH_DIR -maxdepth 1 -type f -name $SEARCHING_FOR | \ + grep -P "$SEARCHING_FOR$" | \ + head -n1 ) + + if [ "$RES" = "" ]; then + if [ "$SEARCH_DIR" = "/" ]; then + STOPSEARCH=1 + fi + cd .. + SEARCH_DIR=$(pwd) + else + export GOPATH=$SEARCH_DIR:$GOPATH + STOPSEARCH=1 + fi +done + +cd "$ORIG_DIR" +exec go $@ +``` diff --git a/res/go+ b/res/go+ new file mode 100755 index 0000000..835a72d --- /dev/null +++ b/res/go+ @@ -0,0 +1,27 @@ +#!/bin/sh + +SEARCHING_FOR=GOPROJROOT +ORIG_DIR=$(pwd) + +STOPSEARCH=0 +SEARCH_DIR=$ORIG_DIR +while [ $STOPSEARCH = 0 ]; do + + RES=$( find $SEARCH_DIR -maxdepth 1 -type f -name $SEARCHING_FOR | \ + grep -P "$SEARCHING_FOR$" | \ + head -n1 ) + + if [ "$RES" = "" ]; then + if [ "$SEARCH_DIR" = "/" ]; then + STOPSEARCH=1 + fi + cd .. + SEARCH_DIR=$(pwd) + else + export GOPATH=$SEARCH_DIR:$GOPATH + STOPSEARCH=1 + fi +done + +cd "$ORIG_DIR" +exec go $@ -- cgit v1.2.3