By polite I mean not interfering in any other projects (even Golang ones), not polluting or forcing your global workspace (no matter how it is organized), and being reproducible on any other machine. For reasons out of the scope of this document, that's not an easy task to accomplish when working with Golang.
These are my notes, not a generic solution. They are not meant to work anywhere outside my machines.
asdf lives in https://github.com/asdf-vm/asdf
Follow its installation instructions, which at the moment of writing were:
cd
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.4.3
# For Ubuntu or other linux distros
echo '. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo '. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrcOn a new terminal, install Golang plugin:
asdf plugin-add golang https://github.com/kennyp/asdf-golangThen install Golang:
asdf install golang 1.10.1Set some Golang verion as global. You will need it to setup your environment afterwards:
asdf global golang 1.10.1These are a couple of functions that are handy to manage golang workspace. Add them to your .bashrc, then put the ingopath call in the prompt as well:
######## golang stuff
# This goes up from current folder looking for a folder
# that looks like a golang workspace root (has a 'src' subfolder, by now).
# Then echoes its path and returns 0.
# Returns -1 if does not find such a folder.
function detect_go_workspace_root {
path="$PWD"
while [[ $path != / ]];
do
src="$path/src"
if [ -d "$src" ]; then
echo "$path" && return 0
fi
path="$(realpath -s "$path"/..)" # ignoring symlinks
done
return -1
}
# This will setup the Go workspace to the detected root path.
# It will complain if not detected.
# Then it will cd into folder pointed by $GOPATH/.letsgo_srcpath
function letsgo {
root=$(detect_go_workspace_root)
if [ $? -ne 0 ]; then
echo "Could not find Go Workspace Root for $PWD" && return -1
fi
export GOPATH=$root
export GOBIN=$root/bin
export PATH=$GOBIN:$PATH
export GOROOT=$(go env GOROOT)
srcpath="$root/.letsgo_srcpath"
[ -L "$srcpath" ] && cd "$(readlink $srcpath)"
}
# This will echo some funny symbol if we are inside current GOPATH.
function ingopath {
[[ $PWD == "$(go env GOPATH)"* ]] && echo "(๐)"
}
## then in the prompt
export PS1='bla bla \[\033[00;36m\]$(ingopath)\[\033[00m\] bla bla $ '
Create a folder for your workspace, then put a src folder inside it, and cd into it. Then run letsgo.
~ $ mkdir -p my_project/src
~ $ cd my_project/
~/my_project $ letsgo
~/my_project(๐) $ # <------ see the eyes, we're inside the GOPATHAt this point you have a pristine golang workspace to follow mainstream conventions (See https://golang.org/doc/code.html).
-
Not existing repo
If this is a new project you should create a folder for your source code, creating folders after your repo's URL path:
mkdir -p src/github.com/rubencaro/my_project cd src/github.com/rubencaro/my_projectThat's the folder that gets into version control. You should setup
gitnow. From inside that folder, something like:git initecho "# My Project" > README.mdgit add .git commit -m'First commit'git remote add <blabblablab>git push -u origin master
-
Already existing repo
If your project already exists on some repo, you can do:
go get -d github.com/rubencaro/my_project cd src/github.com/rubencaro/my_projectThat will create the folders for you.
If you happen to be using SSH to authenticate with github (I recommend that), then you may want to add this to your .gitconfig:
[url "[email protected]:"]
insteadOf = https://github.com/This will prevent go get from using https login when accessing github.
Fix your golang version running asdf local golang 1.8.3 on your source code folder. That will create a .tool-versions file that should be included into version control. That file sets the golang (among others) version to be run when inside this folder.
Then you link that file to the root of your workspace, so everyone in the workspace uses the same golang version you configure on your repo:
ln -s $PWD/.tool-versions $GOPATH/If the version you just fixed was different from the current one (see go version), then you should continue from a new terminal and run letsgo again to ensure your go version is the one you chose. You can run go env if you are in doubt of anything misconfigured.
cd into your source code folder and run this:
ln -s "$PWD" "$GOPATH/.letsgo_srcpath"This makes a link in your $GOPATH that will make letsgo get you into this folder after setting all Go environment. This is useful to avoid repeated cd src/github.com/blahblah/blahblah every time.
From your source code folder run:
go get -u github.com/golang/dep/cmd/depRemember this installs dep only on this workspace. Not on global.
-
A new project, first
deprun:- You should run
dep initto create theGopkg.tomlandGopkg.lockfiles. See https://github.com/golang/dep for further info. - Ignore the
vendorfolder from your version controlecho "vendor" >> .gitignore. You only need to keep track of both theGopkg.*files. - Now you can commit your changes to
.gitignore,Gopkg.tomlandGopkg.lockfiles.
- You should run
-
An existing project: Simply run
dep ensureto install on the workspace everything specified in theGopkg.lockfile. There should be no change on yourgit status.
The first thing to do is always to run letsgo from anywhere inside your workspace folder. That will point your GOPATH to the detected workspace root path, and add $GOPATH/bin to the PATH. Then you can open your favourite editor and compile, do your thing. Everything done from there will work with the project dependencies, golang version, etc. You can see the little eyes (or whatever funny symbol you return from the ingopath function) indicating you are somewhere inside your GOPATH.
If you fail to do that, just forgetting, or opening a new terminal and not running letsgo, then you will be working with the global GOPATH, meaning that you will Go to Hell (pun intended). You will mix up everything from your different golang projects. You may be mixing binaries compiled from different golang versions, or mixing different versions of the same libraries, and so on.
Remember to always run letsgo before start working on your project.
Any new version of golang may come out, you simply install it using asdf install golang <newversion>. Then to try it on your project, go to the source folder and run asdf local golang <newversion>. That will change your .tool-versions file, and thus change the golang version used everywhere inside your workspace. Remember to recompile everything using the new golang to see if it all checks out.
See https://github.com/golang/dep for details. Taken from there:
importthe package in your*.gosource code file(s).- Run the following command to update your
Gopkg.lockand populatevendor/with the new dependency.
dep ensure
How can I upgrade golang version in asdf?