Chainlets is a tool that allows you to look up the mod graph (mostly generated by go mod graph
) for dependency chains.
This can be useful in multiple scenarios:
- Discovering all the packages that has a certain dependency.
- Tracking dependencies that might have security vulnerabilities.
- Other scenarios we are not familiar; feel free to create a pull request to enhance this list.
go get github.com/saedx1/go-chainlets
A binary should be created in your $GOPATH/bin
First, you will need a file that contains the output of a go mod graph
; for example:
go mod graph > mod.graph
Then, you have a couple ways of using the tool:
This is the default mode. Use it if you want to display the full chains that link your own packages to a certain package you specify. This can be more output than you expect; you might end up with hunderds of chains to the same package.
Let's say you want to know the chains that end up with golang.org/x/[email protected]
, you would run the following command (assuming you stored the graph in mod.graph
):
go-chainlets mod.graph golang.org/x/[email protected]
This will output something like this:
1) github.com/saedx1/go-chainlets -> github.com/spf13/[email protected] -> github.com/spf13/[email protected] -> github.com/bketelsen/[email protected] -> golang.org/x/[email protected]
2) github.com/saedx1/go-chainlets -> github.com/spf13/[email protected] -> github.com/spf13/[email protected] -> github.com/bketelsen/[email protected] -> cloud.google.com/go/[email protected] -> cloud.google.com/[email protected] -> cloud.google.com/go/[email protected] -> google.golang.org/[email protected] -> golang.org/x/[email protected]
3) ...
If you don't care about knowing the full paths, and you want to know which packages you're directly require-ing in your go.mod
that lead to a certain dependency (you only care about the first package after yours in the chain). The output is a set of unique packages (no duplicates). You would run it with the --direct
flag (or -d
):
go-chainlets mod.graph golang.org/x/[email protected] --direct
The output for this would be:
1) github.com/saedx1/go-chainlets
which makes sense, because that's the root package in all chains. To get around that you need to use the exclude flag --exclude
(or -e
) and specify pkg (or part of its name). All the edges where the specified package is at the left (dependent) will be removed; so, usually you would only use this with the root package, otherwise, if you exclude a package in the middle, you will have a unexpected results due to a disconnected graph (2 or more individual graphs).
go-chainlets mod.graph golang.org/x/[email protected] --direct -e go-chainlets
and the output would be like this:
1) github.com/spf13/[email protected]
Which means that this version of cobra
is causing you to have golang.org/x/[email protected]
. In other words, removing cobra
from your dependencies will remove x/crypto@...
from the dependencies as well.