https://github.com/crowdstrike/perseus
The hero we all need to defeat the kraken that is Go module dependency graphs
Science Score: 26.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
○DOI references
-
○Academic publication links
-
○Committers with academic emails
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (10.8%) to scientific vocabulary
Keywords from Contributors
Repository
The hero we all need to defeat the kraken that is Go module dependency graphs
Basic Info
- Host: GitHub
- Owner: CrowdStrike
- License: mit
- Language: Go
- Default Branch: main
- Size: 1.42 MB
Statistics
- Stars: 41
- Watchers: 4
- Forks: 7
- Open Issues: 2
- Releases: 32
Metadata Files
README.md
Perseus
With the introduction of Go modules, our projects' dependency trees have exploded in complexity. Perseus is the hero we need to battle that Kraken.
Overview
At CrowdStrike, the move to Go Modules from our existing GOPATH-mode monorepo has brought with it some
pain points, especially around tracing descendant dependencies. In the GOPATH days, when our monorepo
lived under $GOPATH/src and all engineers always had a full copy of the entire codebase, it was a
straightforward grep command to find all imports of a given package to see what other packages depend on it.
Now that we've moved the majority of our development effort to modules, neither of those two conditions
are true. Engineers are no longer required to have the code under $GOPATH/src and almost no one has
the entire codebase locally anymore. We have dozens of functional teams working on hundreds of microservices,
so most developers have pared down their local workspace to only the things they're directly working
on on a day-to-day basis.
An unfortunate side effect of this paradigm shift has been that there is no longer a direct way to see
which other modules depend on your work. Existing tools like go mod graph and go list -m all will
show you what modules you depend on - with some rough edges - and the pkg.go.dev site has an Imported By
view that shows what other packages depend on your code. The go tool won't show which things depend
on you, though. The pkg.go.dev site can only show things that it knows about, so it won't help for
private modules, and it doesn't show you which versions of those other packages depend on your code.
See CHANGELOG.md for a detailed history of changes.
Existing Tooling
Unfortunately, the go CLI commands, the pkg.go.dev site, and OSS tools like goda
and godepgraph don't quite cover the ground we need, specifically
querying for downstream dependencies. The go CLI, goda and godepgraph all do an excellent job
of surfacing up which modules your code depends on in multiple ways. The pkg.go.dev site also provides
a nice Imported By view, but it shows which packages depend on your code, not which modules, and
doesn't include the version(s) of those dependents.
Perseus To The Rescue
The Database
For simplicity, Perseus uses a PostgreSQL database rather than an actual graph database like Neo4J, Cayley, and the like. After some initial investigation, we found that the relatively small number of entries (compared to other graph datasets) didn't warrant a specialized graph database. Additionally, our IT organization already has all of the necessary infrastructure in place to support PostgreSQL.
One potentially signficant caveat, however, is that Amazon RDS currently does not support the
pg-semver extension that we use for storing a module's semantic
version.
The Service
Service Architecture
The perseus service is built on Connect to provide an API that supports
binary gRPC and HTTP JSON/REST requests. Both RPC bindings are provided on a single port using
Vanguard, with the JSON/REST endpoints at a nested path of /api/v1/*.
Additionally, a basic web-based user interface is available at /ui.
In addition to the interactive endpoints, the service also exports an HTTP health check at /healthz
and basic Prometheus metrics at /metrics. For debugging and troubleshooting, the service supports
retrieving Go pprof data via HTTP at /debug/pprof*.
Running the Service
For simplicity, we publish a pre-built Docker image (based on a scratch base) to the GitHub Container
Registry when each release is tagged. The image runs perseus server and exposes port 31138, which
you can map to whatever is appropriate for your environment. You will need to provide the URL location
of the Perseus database, along with a valid username and password to connect, via environment variables.
The default database name is "perseus", but you can override that by also providing a DB_NAME
environment variable.
> docker run --rm -e DB_ADDR=... -e DB_USER=... -e DBPASS=... -p 31138:31138 ghcr.io/crowdstrike/perseus:latest
This example uses the latest tag but you should always reference a specific version for stability.
We also generate pre-built binaries for Windows, Linux, and Mac that can be downloaded from the releases page.
The perseus CLI
The perseus binary is both the server and a CLI tool for interacting with it. The update
and query commands are the workhorses as a client. The Perseus server address can be specified
by either setting the PERSEUS_SERVER_ADDR environment variable or passing it directly to the CLI
using the --server-addr flag.
perseus update analyzes a Go module, on disk or available via public Go module proxies, and adds it
to the Perseus graph. For a module on disk that is a Git repository, the CLI will try to infer the
version by looking at the Git tags on the current commit. If there is exactly 1 module version tag,
that version will be used. If there is no semver tag or there are multiple, you will need to specify
a version.
# process the current version of the perseus module on disk
> perseus update --path ~/code/github.com/CrowdStrike/perseus
# process a specific version of example/foo
> perseus update --path ~/code/github.com/example/foo --version v1.2.3
For public modules a version must always be specified.
> perseus update --module github.com/example/foo --version v1.2.3
Once you have data in your graph, perseus query is the way to retrieve it. There are 4 available
sub-commands: list-modules, list-module-versions, ancestors, and descendants.
The first two commands return modules and versions based on glob pattern matches:
# list all modules under the github.com/example organization along with the highest version
> perseus query list-modules 'github.com/example/*' --list
Module Version
github.com/example/foo v1.2.0
github.com/example/bar v1.1.0
github.com/example/baz v1.17.23
# list all versions of github.com/example/foo using an explicit format
> perseus query list-module-versions github.com/example/foo --format 'module {{.Path}} has version {{.Version}}.'
module github.com/example/foo has version v1.2.0
module github.com/example/foo has version v1.1.0
...
The ancestors and descendants commands walk the graph to return dependency trees, either what a
specified version of a module depends on or what modules depend on it.
# show the modules that v1.2.0 of github.com/example/foo depends on as a tabular list
> perseus query ancestors github.com/example/foo@v1.2.0 --list
Dependency Direct
github.com/pkg/errors@v0.9.1 true
golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c true
...
# show the modules that depend on v0.9.1 of github.com/pkg/errors as nested JSON, using jq to format it nicely
> perseus query descendants github.com/pkg/errors@v0.9.1 --json | jq .
{
"module": {
"Path": "github.com/pkg/errors",
"Version": "v0.9.1"
},
"deps": [
{
"module": {
"Path": "github.com/example/foo",
"Version": "v1.2.0"
},
...
}
]
}
In addition to text-based results using --json, --list or --format, the ancestor and descendant
commands also supports outputting DOT directed graphs using the --dot flag.
# generate an SVG image of the dependency graph for the highest version of github.com/example/foo
> perseus query ancestors github.com/example/foo --dot | dot -Tsvg -o ~/foo_deps.svg
The depth of the tree can be controlled by the --max-depth flag, with a default of 4 hops.
Disclaimer: perseus is an open source project, not a CrowdStrike product. As such, it carries no
formal support, expressed or implied. The project is licensed under the MIT open source license.
Owner
- Name: CrowdStrike
- Login: CrowdStrike
- Kind: organization
- Email: github@crowdstrike.com
- Location: United States of America
- Website: https://www.crowdstrike.com
- Repositories: 183
- Profile: https://github.com/CrowdStrike
GitHub Events
Total
- Watch event: 2
- Delete event: 32
- Issue comment event: 35
- Push event: 35
- Pull request review event: 18
- Pull request event: 71
- Fork event: 3
- Create event: 35
Last Year
- Watch event: 2
- Delete event: 32
- Issue comment event: 35
- Push event: 35
- Pull request review event: 18
- Pull request event: 71
- Fork event: 3
- Create event: 35
Committers
Last synced: about 1 year ago
Top Committers
| Name | Commits | |
|---|---|---|
| dependabot[bot] | 4****] | 163 |
| Dylan Bourque | d****e@c****m | 73 |
| Ben Woodward | b****d@c****m | 2 |
| jf-crwd | 1****d | 1 |
| bufdev | b****b@b****d | 1 |
| Anthony Lee | a****e@c****m | 1 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 10 months ago
All Time
- Total issues: 5
- Total pull requests: 296
- Average time to close issues: 2 months
- Average time to close pull requests: 7 days
- Total issue authors: 3
- Total pull request authors: 6
- Average comments per issue: 0.8
- Average comments per pull request: 0.55
- Merged pull requests: 220
- Bot issues: 1
- Bot pull requests: 267
Past Year
- Issues: 1
- Pull requests: 85
- Average time to close issues: 18 days
- Average time to close pull requests: 26 days
- Issue authors: 1
- Pull request authors: 2
- Average comments per issue: 1.0
- Average comments per pull request: 0.51
- Merged pull requests: 32
- Bot issues: 1
- Bot pull requests: 83
Top Authors
Issue Authors
- dylan-bourque (3)
- dependabot[bot] (1)
- bndw (1)
Pull Request Authors
- dependabot[bot] (267)
- dylan-bourque (23)
- jf-crwd (2)
- bufdev (2)
- bndw (1)
- alee792 (1)
Top Labels
Issue Labels
Pull Request Labels
Packages
- Total packages: 3
- Total downloads: unknown
-
Total dependent packages: 0
(may contain duplicates) -
Total dependent repositories: 0
(may contain duplicates) - Total versions: 99
proxy.golang.org: github.com/Crowdstrike/perseus
- Documentation: https://pkg.go.dev/github.com/Crowdstrike/perseus#section-documentation
- License: mit
-
Latest release: v0.23.0
published almost 2 years ago
Rankings
proxy.golang.org: github.com/CrowdStrike/perseus
- Homepage: https://github.com/CrowdStrike/perseus
- Documentation: https://pkg.go.dev/github.com/CrowdStrike/perseus#section-documentation
- License: MIT
-
Latest release: v0.23.0
published almost 2 years ago
Rankings
proxy.golang.org: github.com/crowdstrike/perseus
- Documentation: https://pkg.go.dev/github.com/crowdstrike/perseus#section-documentation
- License: mit
-
Latest release: v0.23.0
published almost 2 years ago
Rankings
Dependencies
- github.com/Masterminds/squirrel v1.5.3
- github.com/Microsoft/go-winio v0.4.16
- github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7
- github.com/acomagu/bufpipe v1.0.3
- github.com/emirpasic/gods v1.12.0
- github.com/fatih/color v1.13.0
- github.com/go-git/gcfg v1.5.0
- github.com/go-git/go-billy/v5 v5.3.1
- github.com/go-git/go-git/v5 v5.4.2
- github.com/golang/glog v1.0.0
- github.com/golang/protobuf v1.5.2
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3
- github.com/imdario/mergo v0.3.12
- github.com/inconshreveable/mousetrap v1.0.0
- github.com/jackc/chunkreader/v2 v2.0.1
- github.com/jackc/pgconn v1.13.0
- github.com/jackc/pgio v1.0.0
- github.com/jackc/pgpassfile v1.0.0
- github.com/jackc/pgproto3/v2 v2.3.1
- github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b
- github.com/jackc/pgtype v1.12.0
- github.com/jackc/pgx/v4 v4.17.2
- github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
- github.com/jmoiron/sqlx v1.3.5
- github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351
- github.com/lann/builder v0.0.0-20180802200727-47ae307949d0
- github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0
- github.com/mattn/go-colorable v0.1.12
- github.com/mattn/go-isatty v0.0.14
- github.com/mattn/go-runewidth v0.0.13
- github.com/mitchellh/go-homedir v1.1.0
- github.com/rivo/uniseg v0.2.0
- github.com/sergi/go-diff v1.1.0
- github.com/soheilhy/cmux v0.1.5
- github.com/spf13/cobra v1.5.0
- github.com/spf13/pflag v1.0.5
- github.com/theckman/yacspin v0.13.12
- github.com/xanzy/ssh-agent v0.3.0
- golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
- golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee
- golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e
- golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
- golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d
- golang.org/x/text v0.3.7
- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
- google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc
- google.golang.org/grpc v1.49.0
- google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0
- google.golang.org/protobuf v1.28.1
- gopkg.in/warnings.v0 v0.1.2
- gopkg.in/yaml.v3 v3.0.1
- 249 dependencies
- actions/checkout v3 composite
- actions/setup-go v3 composite
- goreleaser/goreleaser-action v4 composite
- actions/checkout v3 composite
- github/codeql-action/analyze v2 composite
- github/codeql-action/autobuild v2 composite
- github/codeql-action/init v2 composite
- actions/checkout v3 composite
- actions/setup-go v3 composite
- golangci/golangci-lint-action v3.4.0 composite
- actions/checkout v3 composite
- actions/setup-go v3 composite
- docker/login-action v2 composite
- goreleaser/goreleaser-action v4 composite