dependency management in go
DESCRIPTION
Golang Taipei Gathering #2TRANSCRIPT
Dependency Management in Go
Poga
A KickStarter
Haunts
• Open Source• https://github.com/runningwild/haunts
• Written in Go• https://github.com/go-gl/gl
• Screwed by dependency hell
import "github.com/go-gl/gl"
go get "github.com/go-gl/gl"
• $GOPATH/
• src/
• github.com/
• go-gl/
• gl/
• ...
• pkg/
• bin/
import "github.com/go-gl/gl"
import path
• 3 in 1
• remote repo url
• local package install path
• package name
go get
go get "github.com/go-gl/gl"
go get
git clone
go install
+=
go get "github.com/go-gl/gl"
go get (the git clone part)
• can’t specify version
• looks for tag/branch name matching your go version
• if no such exist, it goes for the most recent version/master branch
• won’t update cloned repo by default
• use -u
go get (the go install part)
• build/install to $GOPATH
• first path in $GOPATH if it contains multiple paths
• weird behavior when package names conflict
go 對你的 package 有所期待
expectation of go
• green master policy
• always backward compatible
• remote repo url = local install path = package name
BUT• People make mistakes
• repos may change their name/location, or removed
• same package, different import paths
• Dependency Hell
• what if your project depends on version A and a dependency needs version B?
• different versions, same import paths
Haunts
• dependency renamed
• dependency becomes backward incompatible
• developer lost local installed version
• developer make local changes and didn’t push upstream
Solutions
• Manage Dependencies by yourself
• ... or with some tools
• centralized package management
DIY• $GOPATH/
• src/
• github.com/
• USER/
• PROJECT/
• ...
• vender/
• github.com/
• go-gl/• gl
• $GOPATH/
• src/
• github.com/
• USER/
• PROJECT/
• ...
• go-gl/
• gl/
• ...
import "github.com/USER/PROJECT/vendor/github.com/go-gl/gl"
http://camlistore.org/ use this solutionrewrite import path with a python script
DIY Update
• git submodule
• http://git-scm.com/book/en/Git-Tools-Submodules
• git subtree merge
• http://git-scm.com/book/en/Git-Tools-Subtree-Merging
Tools
• Goven
• https://github.com/kr/goven
• copy local packages into project path
• and remove .git/
• rewrite import paths
Tools
• Gopin
• https://github.com/laher/gopin
• download specified version
Tools
• Rx
• https://github.com/kylelemons/rx
• track repos and their tags
• update to a specified tag
• automatically run tests for dependents
• rollback if something is broken
• save current versioning setup as a config
• share this config with your team
Centralized Package Management
• Go Nuts
• gonuts.io
• import “gonuts.io/vendor/nut”
• import “gonuts.io/vendor/nut/version”
• currently host 11 package only
My Conclusion
• No perfect way (now)
• use Camlistore way
• vender 3rd-party dependencies
• rewrite import path with makefile/scripts/goven
• go/parser will be helpful
Thank you
Q&A?