Add nfv2 to make generated Go artifacts available to native tooling

This commit is contained in:
Mustafa Gezen 2023-08-23 03:11:16 +02:00
parent 512b1f91f8
commit 00bbd487b5
Signed by: mustafa
GPG Key ID: DCDF010D946438C1
4 changed files with 166 additions and 1 deletions

20
devtools/nfv2/BUILD Normal file
View File

@ -0,0 +1,20 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "nfv2_lib",
srcs = ["main.go"],
importpath = "go.resf.org/peridot/devtools/nfv2",
visibility = ["//visibility:private"],
deps = [
"//base/go",
"//third_party/bazel/src/main/protobuf",
"//vendor/golang.org/x/mod/modfile",
"@org_golang_google_protobuf//proto",
],
)
go_binary(
name = "nfv2",
embed = [":nfv2_lib"],
visibility = ["//visibility:public"],
)

131
devtools/nfv2/main.go Normal file
View File

@ -0,0 +1,131 @@
// Package main implements nfv2 (nofussvendor 2) which is a tool to make sure the generated
// artifacts from Bazel can be used with native Go tooling. This is done by generating
// a go.mod file in bazel-bin to match the package name and then add a replace directive
// to the go.mod file in the root of the repo.
package main
import (
"bytes"
"fmt"
base "go.resf.org/peridot/base/go"
blaze_query "go.resf.org/peridot/third_party/bazel/src/main/protobuf"
"golang.org/x/mod/modfile"
"google.golang.org/protobuf/proto"
"os"
"os/exec"
"path/filepath"
"strings"
)
func callBazel(args ...string) []byte {
cmd := exec.Command(
"bazel",
args...,
)
var out bytes.Buffer
cmd.Stdout = &out
var errOut bytes.Buffer
cmd.Stderr = &errOut
err := cmd.Run()
if err != nil {
base.LogFatalf("error: %s", err)
}
return out.Bytes()
}
func main() {
// get bazel workspace
// exit if not invoked with bazel
searchDirectory := os.Getenv("BUILD_WORKSPACE_DIRECTORY")
if searchDirectory == "" {
base.LogFatalf("error: BUILD_WORKSPACE_DIRECTORY not found")
}
// change directory to bazel workspace
err := os.Chdir(searchDirectory)
if err != nil {
base.LogFatalf("could not change directory: %v", err)
}
queryProto := callBazel("query", "kind(go_proto_library, //... - //vendor/... - //third_party/... + //third_party/bazel/...)", "--output", "proto")
var query blaze_query.QueryResult
err = proto.Unmarshal(queryProto, &query)
if err != nil {
base.LogFatalf("could not unmarshal query result: %v", err)
}
replaceList := map[string]string{}
for _, rule := range query.Target {
if *rule.Rule.RuleClass != "go_proto_library" {
continue
}
fullTarget := *rule.Rule.Name
ruleName := strings.Split(fullTarget, ":")[1]
for _, nstring := range rule.Rule.Attribute {
if *nstring.Name == "importpath" {
origImportPath := *nstring.StringValue
importpath := origImportPath
buildLocation := strings.Replace(*rule.Rule.Location, searchDirectory+"/", "", 1)
buildLocation = filepath.Dir(strings.Split(buildLocation, ":")[0])
buildLocation = fmt.Sprintf("bazel-bin/%s/%s_", buildLocation, ruleName)
modDir := filepath.Join(buildLocation, importpath)
if err := os.MkdirAll(modDir, 0755); err != nil && !os.IsExist(err) {
base.LogFatalf("could not generate directory for importpath %s", importpath)
}
if strings.HasSuffix(importpath, "/v1") {
importpath = strings.TrimSuffix(importpath, "/v1")
modDir = filepath.Join(modDir, "..")
}
modContent := []byte(fmt.Sprintf("module %s", importpath))
if err := os.WriteFile(filepath.Join(modDir, "go.mod"), modContent, 0644); err != nil {
base.LogFatalf("could not write go.mod file: %v", err)
}
replaceList[importpath] = modDir
}
}
}
// parse go.mod file
modBts, err := os.ReadFile("go.mod")
if err != nil {
base.LogFatalf("could not read go.mod file: %v", err)
}
mod, err := modfile.Parse("go.mod", modBts, nil)
if err != nil {
base.LogFatalf("could not parse go.mod file: %v", err)
}
// add replace directives
for from, to := range replaceList {
err := mod.AddReplace(from, "", "./"+to, "")
if err != nil {
base.LogFatalf("could not add replace directive: %v", err)
}
}
// write go.mod file
bts, err := mod.Format()
if err != nil {
base.LogFatalf("could not format go.mod file: %v", err)
}
err = os.WriteFile("go.mod", bts, 0644)
if err != nil {
base.LogFatalf("could not write go.mod file: %v", err)
}
base.LogInfof("added %d replace directives pointing to generated modules", len(replaceList))
}

8
go.mod
View File

@ -16,11 +16,12 @@ require (
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2
github.com/prometheus/client_golang v1.16.0
github.com/sirupsen/logrus v1.9.3
github.com/temporalio/temporalite v0.3.0
github.com/urfave/cli/v2 v2.25.7
github.com/wk8/go-ordered-map/v2 v2.1.8
go.ciq.dev/pika v0.0.0-20230819201750-737c3e8f413d
go.resf.org/peridot/third_party/bazel/src/main/protobuf v0.0.0-00010101000000-000000000000
go.resf.org/peridot/tools/mothership/pb v0.0.0-00010101000000-000000000000
go.starlark.net v0.0.0-20230814145427-12f4cb8177e4
golang.org/x/mod v0.10.0
google.golang.org/grpc v1.57.0
@ -155,6 +156,7 @@ require (
github.com/russellhaering/goxmldsig v1.4.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smarty/assertions v1.15.1 // indirect
github.com/smartystreets/assertions v1.15.1 // indirect
github.com/spf13/cast v1.4.1 // indirect
@ -237,3 +239,7 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
replace go.resf.org/peridot/tools/mothership/pb => ./bazel-bin/tools/mothership/proto/v1/mothershippb_go_proto_/go.resf.org/peridot/tools/mothership/pb
replace go.resf.org/peridot/third_party/bazel/src/main/protobuf => ./bazel-bin/third_party/bazel/src/main/protobuf/blaze_query_go_proto_/go.resf.org/peridot/third_party/bazel/src/main/protobuf

8
vendor/modules.txt vendored
View File

@ -948,6 +948,12 @@ go.opentelemetry.io/proto/otlp/common/v1
go.opentelemetry.io/proto/otlp/metrics/v1
go.opentelemetry.io/proto/otlp/resource/v1
go.opentelemetry.io/proto/otlp/trace/v1
# go.resf.org/peridot/third_party/bazel/src/main/protobuf v0.0.0-00010101000000-000000000000 => ./bazel-bin/third_party/bazel/src/main/protobuf/blaze_query_go_proto_/go.resf.org/peridot/third_party/bazel/src/main/protobuf
## explicit
go.resf.org/peridot/third_party/bazel/src/main/protobuf
# go.resf.org/peridot/tools/mothership/pb v0.0.0-00010101000000-000000000000 => ./bazel-bin/tools/mothership/proto/v1/mothershippb_go_proto_/go.resf.org/peridot/tools/mothership/pb
## explicit
go.resf.org/peridot/tools/mothership/pb
# go.starlark.net v0.0.0-20230814145427-12f4cb8177e4
## explicit; go 1.16
go.starlark.net/internal/compile
@ -1582,3 +1588,5 @@ sigs.k8s.io/structured-merge-diff/v4/value
sigs.k8s.io/yaml
# github.com/coreos/bbolt v1.3.7 => go.etcd.io/bbolt v1.3.7
# github.com/smartystreets/assertions v1.15.1 => github.com/smarty/assertions v1.15.1
# go.resf.org/peridot/tools/mothership/pb => ./bazel-bin/tools/mothership/proto/v1/mothershippb_go_proto_/go.resf.org/peridot/tools/mothership/pb
# go.resf.org/peridot/third_party/bazel/src/main/protobuf => ./bazel-bin/third_party/bazel/src/main/protobuf/blaze_query_go_proto_/go.resf.org/peridot/third_party/bazel/src/main/protobuf