GenVer is a tool that improves accessibility to your Go project's dependency information. GenVer comes in two flavours -- a CLI that generates code and an importable package used to retrieve version information during runtime.
This idea came about when a project I was working on required the precise version of each dependency be logged for auditing purposes. Following Go 1.18, this information because available at runtime using the runtime/debug or runtime/buildinfo library. However, the data returned is not easily queryable and not performant to interact with.
This can be useful:
- If you need to know external dependency versions at runtime for auditing or logging purposes.
- If you need to build tooling that requires precise dependency information at runtime.
genver CLI:
go install github.com/gregfurman/genver/cmd/genver@latestgenver package:
go get github.com/gregfurman/genverThe genver binary takes, as an argument, the full content of your Go modules in JSON form. This can easily be retrieved with cmd/go with the go list -m -json all command. See Flags for more options and CLI flags. See CLI implementation example for a potential approach.
genver [options] required_json_module_dependencies
options:
-out string
location of generated dependency information. (default "versions.gen.go")
-package string
package of generated dependency information. (default "genver")
-validate
if enabled, uses the Go AST parser to check if the generated file has valid syntax (default true)
All are optional and have reasonable defaults:
--out: directs the location of the generated code. (default"versions.gen.go")--package: names the package of the generated code. (default"genver")--validate: validate the generated file against the Go AST parser (defaulttrue)
go list -m -json all | genverThe generated code file will contain information of each package, defined as two const values per module imported, one for module's Version and Path, respectively. The generic naming of each constant provides information in the form <PATH>_<DOMAIN>_<TYPE>. See this repo'sversion.gen.go or the CLI example.
Example #1 cloud.google.com/go/[email protected]:
// Currently using cloud.google.com/go/analytics v0.12.0
const (
GoAnalytics_Google_Version = "v0.12.0"
GoAnalytics_Google_Path = "cloud.google.com/go/analytics"
)Example #2 [email protected]:
// Currently using go.opencensus.io v0.24.0
const (
Opencensus_Version = "v0.24.0"
Opencensus_Path = "go.opencensus.io"
)Example #3 sigs.k8s.io/[email protected]:
// Currently using sigs.k8s.io/yaml v1.3.0
const (
Yaml_K8s_Version = "v1.3.0"
Yaml_K8s_Path = "sigs.k8s.io/yaml"
)The package exposes a NewDependencyVersionStore function that returns a *DependencyStore. This will pull in dependencies from runtime and populate each module name and version into a trie. This exposes the following methods:
FindVersionFromPath(path string) any: Pass in an arbitrary pathname and get its version as output (ornilif not found)FindVersionFromData(data any) any: Pass in an arbitrary data type and the version of the module that imported it in get the module (ornilif not found)
import (
"github.com/gregfurman/genver"
"google.golang.org/grpc/codes" // v1.59.0
"google.golang.org/protobuf/proto" // v1.31.0
)
func main() {
versionStore := genver.NewDependencyVersionStore()
// Find the dependency version from a pathname
grpcVersion := versionStore.FindVersionFromPath("google.golang.org/grpc/codes")
fmt.Println("Using grpc@%s", grpcVersion)
// Find the module version from a dependency's attribute
// where proto.String is a signature to an exported function
pbVersion := versionStore.FindVersionFromData(proto.String)
fmt.Println("Using protobuf@%s", pbVersion)
}Using [email protected]
Using [email protected]- Provide more code examples
- Potentially fix installation guide
- Give more rationale behind using a trie
- Explain more on rationale behind creation
- Add makefile and github actions
- Add more tests and documentation -- perhaps consolidate all code into single
internalpackage - Look into using cobra and improve CLI docs
- Perhaps add args to generated files