This is a creation in Article, where the information may have evolved or changed.
During my day job I ' ve been working on re-factoring some the internals of Juju to reverse the trend of a growing number of Dependencies in our core packages.
In this post I'll show how I used to help me in the this go list
task.
The basics
Let's start with the basics of go list
. The default invocation of go list
returns the name of the the import path that represents the directory is currently in, or The package path is provide.
% CD $GOPATH/src/code.google.com/p/go.crypto/ssh% go listcode.google.com/p/go.crypto/ssh% go list github.com /juju/jujuGithub.com/juju/juju
By itself this doesn ' t appear to being particularly notable, however this simple example belies the power ofgo list.
The secret of the -f
flag
Tucked away at the top of the documentation for are this short go help list
piece
-f
the flag specifies an alternate format for the list, using the syntax of the package template. The default output is equivalent to -f '{{.ImportPath}}'
.
Put simply, -f
allows you to execute a Go template which have access to the internal data structures go
of the tool, Same structures that is used when build
ing, test
ing or get
ting code.
This example, using was equivalent to the -f '{{ .ImportPath }}',
previous invocation and gives us a glimpse into the power ofgo list
% Go list-f ' {{. Importpath}} ' Github.com/juju/juju github.com/juju/juju
Going a step further with Go list
cmd/go
the Godoc for lists the structures available -f
to, so I won ' t repeat them verbatim. Instead I ' ll highlight some uses of go list
.
Listing the test files that would be built
% Go list-f ' {{. Testgofiles}} ' Archive/tar[reader_test.go tar_test.go Writer_test.go]
Or the external test files of that
% Go list-f ' {{. Xtestgofiles}} ' Archive/tar[Example_test.go]
Or a summary for a set of packages
% Go list-f ' {{. Name}}: {{. DOC}} ' code.google.com/p/go.net/ipv{4,6}ipv4:package IPv4 implements Ip-level socket options for the Internet Protoc OL version 4.ipv6:package IPv6 implements ip-level socket options for the Internet Protocol version 6.
Conditional builds and build tags
A important part of writing Go programs are dealing with portability issues across various operating systems or processors. I ' ve written about conditional builds before, so I'll just show an example listing the files that would be compiled on Var IOUs platforms
% env Goos=darwin Go list-f ' {{. Gofiles}} ' Github.com/pkg/term[term.go term_bsd.go]% env goos=linux Go list-f ' {{. Gofiles}} ' Github.com/pkg/term[term.go Term_linux.go]
Who depends on?
go list
Can show both the packages that your package directly depends, or it complete set of transitive dependencies.
% Go list-f ' {{. Imports} ' github.com/davecheney/profile[io/ioutil log os os/signal path/filepath runtime runtime/pprof]% go List-f ' {. Deps}} ' github.com/davecheney/profile[bufio bytes errors fmt io io/ioutil log math os os/signal path/filepath reflect Runtime runtime/pprof sort StrConv strings sync sync/atomic syscall text/tabwriter time Unicode Unicode/utf8 unsafe]
The first command lists only the packages, which github.com/davecheney/profile
depends on directly. The unique set import
of statements in all Go files, adjusted for build constraints. The second command returns the set of direct and transitive dependency of github.com/davecheney/profile
.
Fancy Templating
The set of data structures available go list
to the template are quite specialised, but don ' t forget we have the whole power The of the Go template package at our disposal.
The previous examples dealing with slices of values, the default output format follows the package fmt
. However it is probably more convenient for scripting applications to has one entry per line, which we can do easily as th E go list
template contains a function called join
which delegates tostrings.Join.
% Go list-f ' {{join. Imports "\ n"}} ' Github.com/davecheney/profileio/ioutillogosos/signalpath/filepathruntimeruntime/pprof
Putting It together
With the task of trying to unpick the forest of dependencies in We core packages, I can use to go list
define a helper like
Deps () { go list-f ' {{join. Deps "\ n"}} '. | grep JuJu}
The usage is as simple as navigating-a particular package in my and checking to see it complete $GOPATH
dependency list
% Depsgithub.com/juju/cmdgithub.com/juju/errgogithub.com/juju/errorsgithub.com/juju/gojsonpointergithub.com /juju/gojsonreferencegithub.com/juju/gojsonschemagithub.com/juju/juju/api/agent...//many more lines elided
Conclusion
This short post has barely scratched the surface of the flexibility that go list
provides.
If your development, build, or CI tooling is using hand rolled scripts, grep, awk, etc, to introspect Go packages and Thei R interdependencies, consider switching to go list
.
Related Posts:
- Introducing profile, Super simple profiling for Go programs
- simple profiling package moved, updated /li>
- go and Juju at Canonical slides posted
- Five suggestions for setting up a Go project