Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2022-05-02 10:10:03 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2022-05-06 11:44:31 +0300
commit3f30f8999301a6e60b1c39f6bea739b943a5402f (patch)
tree1fb3c9f3aab22efa3aa7ec7ba63dec23902c0935
parentbd0172ed0bdbb8779aa1d44bc1076f39d8c4e953 (diff)
protoc-gen-gitaly: Split up plugin by functionality
The `protoc-gen-gitaly` plugin provides two different functionalities: - It lints our Protobuf definitions to make sure they conform to our coding guidelines. - It generates a `protolist.go` file, which contains a list of all Protobuf files. This is conflating two otherwise unrelated concerns, and thus makes the divide between our `proto` and `lint-proto` Makefile targets a bit blurry. Furthermore, it is creating a cyclic dependency: the linting logic requires that the Protobuf files must have already been generated, but we can only generate them when we have plugin compiled. Prepare for a fix by splitting up functionality of this plugin into two separate plugins: `protoc-gen-gitaly-lint` is responsible for linting our definitions, while `protoc-gen-gitaly-protolist` will generate the list of Protobuf files.
-rw-r--r--Makefile38
-rw-r--r--proto/go/internal/cmd/protoc-gen-gitaly-lint/main.go108
-rw-r--r--proto/go/internal/cmd/protoc-gen-gitaly-protolist/main.go (renamed from proto/go/internal/cmd/protoc-gen-gitaly/main.go)93
3 files changed, 138 insertions, 101 deletions
diff --git a/Makefile b/Makefile
index 02bb4b397..890b4fb93 100644
--- a/Makefile
+++ b/Makefile
@@ -45,18 +45,19 @@ GIT_PREFIX ?= ${GIT_DEFAULT_PREFIX}
FIPS_MODE ?= 0
# Tools
-GIT := $(shell command -v git)
-GOIMPORTS := ${TOOLS_DIR}/goimports
-GOFUMPT := ${TOOLS_DIR}/gofumpt
-GOLANGCI_LINT := ${TOOLS_DIR}/golangci-lint
-PROTOLINT := ${TOOLS_DIR}/protolint
-GO_LICENSES := ${TOOLS_DIR}/go-licenses
-PROTOC := ${TOOLS_DIR}/protoc
-PROTOC_GEN_GO := ${TOOLS_DIR}/protoc-gen-go
-PROTOC_GEN_GO_GRPC:= ${TOOLS_DIR}/protoc-gen-go-grpc
-PROTOC_GEN_GITALY := ${TOOLS_DIR}/protoc-gen-gitaly
-GOTESTSUM := ${TOOLS_DIR}/gotestsum
-GOCOVER_COBERTURA := ${TOOLS_DIR}/gocover-cobertura
+GIT := $(shell command -v git)
+GOIMPORTS := ${TOOLS_DIR}/goimports
+GOFUMPT := ${TOOLS_DIR}/gofumpt
+GOLANGCI_LINT := ${TOOLS_DIR}/golangci-lint
+PROTOLINT := ${TOOLS_DIR}/protolint
+GO_LICENSES := ${TOOLS_DIR}/go-licenses
+PROTOC := ${TOOLS_DIR}/protoc
+PROTOC_GEN_GO := ${TOOLS_DIR}/protoc-gen-go
+PROTOC_GEN_GO_GRPC := ${TOOLS_DIR}/protoc-gen-go-grpc
+PROTOC_GEN_GITALY_LINT := ${TOOLS_DIR}/protoc-gen-gitaly-lint
+PROTOC_GEN_GITALY_PROTOLIST := ${TOOLS_DIR}/protoc-gen-gitaly-protolist
+GOTESTSUM := ${TOOLS_DIR}/gotestsum
+GOCOVER_COBERTURA := ${TOOLS_DIR}/gocover-cobertura
# Tool options
GOLANGCI_LINT_OPTIONS ?=
@@ -439,11 +440,11 @@ cover: prepare-tests libgit2 ${GOCOVER_COBERTURA}
.PHONY: proto
## Regenerate protobuf definitions.
-proto: SHARED_PROTOC_OPTS = --plugin=${PROTOC_GEN_GO} --plugin=${PROTOC_GEN_GO_GRPC} --plugin=${PROTOC_GEN_GITALY} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
-proto: ${PROTOC} ${PROTOC_GEN_GO} ${PROTOC_GEN_GO_GRPC} ${PROTOC_GEN_GITALY} ${SOURCE_DIR}/.ruby-bundle
+proto: SHARED_PROTOC_OPTS = --plugin=${PROTOC_GEN_GO} --plugin=${PROTOC_GEN_GO_GRPC} --plugin=${PROTOC_GEN_GITALY_LINT} --plugin=${PROTOC_GEN_GITALY_PROTOLIST} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
+proto: ${PROTOC} ${PROTOC_GEN_GO} ${PROTOC_GEN_GO_GRPC} ${PROTOC_GEN_GITALY_LINT} ${PROTOC_GEN_GITALY_PROTOLIST} ${SOURCE_DIR}/.ruby-bundle
${Q}mkdir -p ${SOURCE_DIR}/proto/go/gitalypb
${Q}rm -f ${SOURCE_DIR}/proto/go/gitalypb/*.pb.go
- ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/proto -I ${PROTOC_INSTALL_DIR}/include --go_out=${SOURCE_DIR}/proto/go/gitalypb --gitaly_out=proto_dir=${SOURCE_DIR}/proto,gitalypb_dir=${SOURCE_DIR}/proto/go/gitalypb:${SOURCE_DIR} --go-grpc_out=${SOURCE_DIR}/proto/go/gitalypb ${SOURCE_DIR}/proto/*.proto
+ ${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/proto -I ${PROTOC_INSTALL_DIR}/include --go_out=${SOURCE_DIR}/proto/go/gitalypb --gitaly-protolist_out=proto_dir=${SOURCE_DIR}/proto,gitalypb_dir=${SOURCE_DIR}/proto/go/gitalypb:${SOURCE_DIR} --gitaly-lint_out=${SOURCE_DIR} --go-grpc_out=${SOURCE_DIR}/proto/go/gitalypb ${SOURCE_DIR}/proto/*.proto
${SOURCE_DIR}/_support/generate-proto-ruby
@ # this part is related to the generation of sources from testing proto files
${PROTOC} ${SHARED_PROTOC_OPTS} -I ${SOURCE_DIR}/internal --go_out=${SOURCE_DIR}/internal --go-grpc_out=${SOURCE_DIR}/internal ${SOURCE_DIR}/internal/praefect/grpc-proxy/testdata/test.proto
@@ -605,8 +606,11 @@ ${TOOLS_DIR}/%: GOBIN = ${TOOLS_DIR}
${TOOLS_DIR}/%: ${TOOLS_DIR}/%.version
${Q}go install ${TOOL_PACKAGE}@${TOOL_VERSION}
-${PROTOC_GEN_GITALY}: proto | ${TOOLS_DIR}
- ${Q}go build -o $@ ${SOURCE_DIR}/proto/go/internal/cmd/protoc-gen-gitaly
+${PROTOC_GEN_GITALY_LINT}: proto | ${TOOLS_DIR}
+ ${Q}go build -o $@ ${SOURCE_DIR}/proto/go/internal/cmd/protoc-gen-gitaly-lint
+
+${PROTOC_GEN_GITALY_PROTOLIST}: | ${TOOLS_DIR}
+ ${Q}go build -o $@ ${SOURCE_DIR}/proto/go/internal/cmd/protoc-gen-gitaly-protolist
# External tools
${GOCOVER_COBERTURA}: TOOL_PACKAGE = github.com/t-yuki/gocover-cobertura
diff --git a/proto/go/internal/cmd/protoc-gen-gitaly-lint/main.go b/proto/go/internal/cmd/protoc-gen-gitaly-lint/main.go
new file mode 100644
index 000000000..e0756ceca
--- /dev/null
+++ b/proto/go/internal/cmd/protoc-gen-gitaly-lint/main.go
@@ -0,0 +1,108 @@
+// Command protoc-gen-gitaly-lint is designed to be used as a protobuf compiler
+// plugin to verify Gitaly processes are being followed when writing RPC's.
+//
+// Usage
+//
+// The protoc-gen-gitaly linter can be chained into any protoc workflow that
+// requires verification that Gitaly RPC guidelines are followed. Typically
+// this can be done by adding the following argument to an existing protoc
+// command:
+//
+// --gitaly_lint_out=.
+//
+// For example, you may add the linter as an argument to the command responsible
+// for generating Go code:
+//
+// protoc --go_out=. --gitaly_lint_out=. *.proto
+//
+// Or, you can run the Gitaly linter by itself. To try out, run the following
+// command while in the project root:
+//
+// protoc --gitaly_lint_out=. ./go/internal/linter/testdata/incomplete.proto
+//
+// You should see some errors printed to screen for improperly written
+// RPC's in the incomplete.proto file.
+//
+// Prerequisites
+//
+// The protobuf compiler (protoc) can be obtained from the GitHub page:
+// https://github.com/protocolbuffers/protobuf/releases
+//
+// Background
+//
+// The protobuf compiler accepts plugins to analyze protobuf files and generate
+// language specific code.
+//
+// These plugins require the following executable naming convention:
+//
+// protoc-gen-$NAME
+//
+// Where $NAME is the plugin name of the compiler desired. The protobuf compiler
+// will search the PATH until an executable with that name is found for a
+// desired plugin. For example, the following protoc command:
+//
+// protoc --gitaly_lint_out=. *.proto
+//
+// The above will search the PATH for an executable named protoc-gen-gitaly-lint
+//
+// The plugin accepts a protobuf message in STDIN that describes the parsed
+// protobuf files. A response is sent back on STDOUT that contains any errors.
+package main
+
+import (
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strings"
+
+ "gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/pluginpb"
+)
+
+func main() {
+ data, err := io.ReadAll(os.Stdin)
+ if err != nil {
+ log.Fatalf("reading input: %s", err)
+ }
+
+ req := &pluginpb.CodeGeneratorRequest{}
+
+ if err := proto.Unmarshal(data, req); err != nil {
+ log.Fatalf("parsing input proto: %s", err)
+ }
+
+ if err := lintProtos(req); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func lintProtos(req *pluginpb.CodeGeneratorRequest) error {
+ var errMsgs []string
+ for _, pf := range req.GetProtoFile() {
+ errs := linter.LintFile(pf, req)
+ for _, err := range errs {
+ errMsgs = append(errMsgs, err.Error())
+ }
+ }
+
+ resp := &pluginpb.CodeGeneratorResponse{}
+
+ if len(errMsgs) > 0 {
+ errMsg := strings.Join(errMsgs, "\n\t")
+ resp.Error = &errMsg
+ }
+
+ // Send back the results.
+ data, err := proto.Marshal(resp)
+ if err != nil {
+ return fmt.Errorf("failed to marshal output proto: %s", err)
+ }
+
+ _, err = os.Stdout.Write(data)
+ if err != nil {
+ return fmt.Errorf("failed to write output proto: %s", err)
+ }
+ return nil
+}
diff --git a/proto/go/internal/cmd/protoc-gen-gitaly/main.go b/proto/go/internal/cmd/protoc-gen-gitaly-protolist/main.go
index efe8a312e..7e775360e 100644
--- a/proto/go/internal/cmd/protoc-gen-gitaly/main.go
+++ b/proto/go/internal/cmd/protoc-gen-gitaly-protolist/main.go
@@ -1,53 +1,12 @@
-/*Command protoc-gen-gitaly is designed to be used as a protobuf compiler
-plugin to verify Gitaly processes are being followed when writing RPC's.
-
-Usage
-
-The protoc-gen-gitaly linter can be chained into any protoc workflow that
-requires verification that Gitaly RPC guidelines are followed. Typically
-this can be done by adding the following argument to an existing protoc
-command:
-
- --gitaly_out=.
-
-For example, you may add the linter as an argument to the command responsible
-for generating Go code:
-
- protoc --go_out=. --gitaly_out=. *.proto
-
-Or, you can run the Gitaly linter by itself. To try out, run the following
-command while in the project root:
-
- protoc --gitaly_out=. ./go/internal/linter/testdata/incomplete.proto
-
-You should see some errors printed to screen for improperly written
-RPC's in the incomplete.proto file.
-
-Prerequisites
-
-The protobuf compiler (protoc) can be obtained from the GitHub page:
-https://github.com/protocolbuffers/protobuf/releases
-
-Background
-
-The protobuf compiler accepts plugins to analyze protobuf files and generate
-language specific code.
-
-These plugins require the following executable naming convention:
-
- protoc-gen-$NAME
-
-Where $NAME is the plugin name of the compiler desired. The protobuf compiler
-will search the PATH until an executable with that name is found for a
-desired plugin. For example, the following protoc command:
-
- protoc --gitaly_out=. *.proto
-
-The above will search the PATH for an executable named protoc-gen-gitaly
-
-The plugin accepts a protobuf message in STDIN that describes the parsed
-protobuf files. A response is sent back on STDOUT that contains any errors.
-*/
+// Command protoc-gen-gitaly-protolist is designed to be used as a protobuf compiler to generate a
+// list of protobuf files via a publicly accessible variable.
+//
+// This plugin can be accessed by invoking the protoc compiler with the following arguments:
+//
+// protoc --plugin=protoc-gen-gitaly-protolist --gitaly_protolist_out=.
+//
+// The plugin accepts a protobuf message in STDIN that describes the parsed protobuf files. A
+// response is sent back on STDOUT that contains any errors.
package main
import (
@@ -61,7 +20,6 @@ import (
"strings"
"text/template"
- "gitlab.com/gitlab-org/gitaly/v14/proto/go/internal/linter"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/pluginpb"
)
@@ -83,10 +41,6 @@ func main() {
log.Fatalf("parsing input proto: %s", err)
}
- if err := lintProtos(req); err != nil {
- log.Fatal(err)
- }
-
if err := generateProtolistGo(req); err != nil {
log.Fatal(err)
}
@@ -109,35 +63,6 @@ func parseArgs(argString string) (gitalyProtoDir string, gitalypbDir string) {
return gitalyProtoDir, gitalypbDir
}
-func lintProtos(req *pluginpb.CodeGeneratorRequest) error {
- var errMsgs []string
- for _, pf := range req.GetProtoFile() {
- errs := linter.LintFile(pf, req)
- for _, err := range errs {
- errMsgs = append(errMsgs, err.Error())
- }
- }
-
- resp := &pluginpb.CodeGeneratorResponse{}
-
- if len(errMsgs) > 0 {
- errMsg := strings.Join(errMsgs, "\n\t")
- resp.Error = &errMsg
- }
-
- // Send back the results.
- data, err := proto.Marshal(resp)
- if err != nil {
- return fmt.Errorf("failed to marshal output proto: %s", err)
- }
-
- _, err = os.Stdout.Write(data)
- if err != nil {
- return fmt.Errorf("failed to write output proto: %s", err)
- }
- return nil
-}
-
func generateProtolistGo(req *pluginpb.CodeGeneratorRequest) error {
var err error
gitalyProtoDir, gitalypbDir := parseArgs(req.GetParameter())