github.com/argoproj/argo-cd/v2@v2.10.9/hack/generate-proto.sh (about)

     1  #! /usr/bin/env bash
     2  
     3  # This script auto-generates protobuf related files. It is intended to be run manually when either
     4  # API types are added/modified, or server gRPC calls are added. The generated files should then
     5  # be checked into source control.
     6  
     7  set -x
     8  set -o errexit
     9  set -o nounset
    10  set -o pipefail
    11  
    12  # shellcheck disable=SC2128
    13  PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE}")"/..; pwd)
    14  PATH="${PROJECT_ROOT}/dist:${PATH}"
    15  GOPATH=$(go env GOPATH)
    16  
    17  # output tool versions
    18  go version
    19  protoc --version
    20  swagger version
    21  jq --version
    22  
    23  export GO111MODULE=off
    24  
    25  # Generate pkg/apis/<group>/<apiversion>/(generated.proto,generated.pb.go)
    26  # NOTE: any dependencies of our types to the k8s.io apimachinery types should be added to the
    27  # --apimachinery-packages= option so that go-to-protobuf can locate the types, but prefixed with a
    28  # '-' so that go-to-protobuf will not generate .proto files for it.
    29  PACKAGES=(
    30      github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1
    31  )
    32  APIMACHINERY_PKGS=(
    33      +k8s.io/apimachinery/pkg/util/intstr
    34      +k8s.io/apimachinery/pkg/api/resource
    35      +k8s.io/apimachinery/pkg/runtime/schema
    36      +k8s.io/apimachinery/pkg/runtime
    37      k8s.io/apimachinery/pkg/apis/meta/v1
    38      k8s.io/api/core/v1
    39      k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1
    40  )
    41  
    42  export GO111MODULE=on
    43  [ -e ./v2 ] || ln -s . v2
    44  
    45  # protoc_include is the include directory containing the .proto files distributed with protoc binary
    46  if [ -d /dist/protoc-include ]; then
    47      # containerized codegen build
    48      protoc_include=/dist/protoc-include
    49  else
    50      # local codegen build
    51      protoc_include=${PROJECT_ROOT}/dist/protoc-include
    52  fi
    53  
    54  go-to-protobuf \
    55      --go-header-file="${PROJECT_ROOT}"/hack/custom-boilerplate.go.txt \
    56      --packages="$(IFS=, ; echo "${PACKAGES[*]}")" \
    57      --apimachinery-packages="$(IFS=, ; echo "${APIMACHINERY_PKGS[*]}")" \
    58      --proto-import=./vendor \
    59      --proto-import="${protoc_include}"
    60  
    61  # Either protoc-gen-go, protoc-gen-gofast, or protoc-gen-gogofast can be used to build
    62  # server/*/<service>.pb.go from .proto files. golang/protobuf and gogo/protobuf can be used
    63  # interchangeably. The difference in the options are:
    64  # 1. protoc-gen-go - official golang/protobuf
    65  #GOPROTOBINARY=go
    66  # 2. protoc-gen-gofast - fork of golang golang/protobuf. Faster code generation
    67  #GOPROTOBINARY=gofast
    68  # 3. protoc-gen-gogofast - faster code generation and gogo extensions and flexibility in controlling
    69  # the generated go code (e.g. customizing field names, nullable fields)
    70  GOPROTOBINARY=gogofast
    71  
    72  # Generate server/<service>/(<service>.pb.go|<service>.pb.gw.go)
    73  MOD_ROOT=${GOPATH}/pkg/mod
    74  grpc_gateway_version=$(go list -m github.com/grpc-ecosystem/grpc-gateway | awk '{print $NF}' | head -1)
    75  GOOGLE_PROTO_API_PATH=${MOD_ROOT}/github.com/grpc-ecosystem/grpc-gateway@${grpc_gateway_version}/third_party/googleapis
    76  GOGO_PROTOBUF_PATH=${PROJECT_ROOT}/vendor/github.com/gogo/protobuf
    77  PROTO_FILES=$(find "$PROJECT_ROOT" \( -name "*.proto" -and -path '*/server/*' -or -path '*/reposerver/*' -and -name "*.proto" -or -path '*/cmpserver/*' -and -name "*.proto" \) | sort)
    78  for i in ${PROTO_FILES}; do
    79      protoc \
    80          -I"${PROJECT_ROOT}" \
    81          -I"${protoc_include}" \
    82          -I./vendor \
    83          -I"$GOPATH"/src \
    84          -I"${GOOGLE_PROTO_API_PATH}" \
    85          -I"${GOGO_PROTOBUF_PATH}" \
    86          --${GOPROTOBINARY}_out=plugins=grpc:"$GOPATH"/src \
    87          --grpc-gateway_out=logtostderr=true:"$GOPATH"/src \
    88          --swagger_out=logtostderr=true:. \
    89          $i
    90  done
    91  [ -e ./v2 ] && rm -rf v2
    92  
    93  # collect_swagger gathers swagger files into a subdirectory
    94  collect_swagger() {
    95      SWAGGER_ROOT="$1"
    96      SWAGGER_OUT="${PROJECT_ROOT}/assets/swagger.json"
    97      PRIMARY_SWAGGER=$(mktemp)
    98      COMBINED_SWAGGER=$(mktemp)
    99  
   100      cat <<EOF > "${PRIMARY_SWAGGER}"
   101  {
   102    "swagger": "2.0",
   103    "info": {
   104      "title": "Consolidate Services",
   105      "description": "Description of all APIs",
   106      "version": "version not set"
   107    },
   108    "paths": {}
   109  }
   110  EOF
   111  
   112      rm -f "${SWAGGER_OUT}"
   113  
   114      find "${SWAGGER_ROOT}" -name '*.swagger.json' -exec swagger mixin --ignore-conflicts "${PRIMARY_SWAGGER}" '{}' \+ > "${COMBINED_SWAGGER}"
   115      jq -r 'del(.definitions[].properties[]? | select(."$ref"!=null and .description!=null).description) | del(.definitions[].properties[]? | select(."$ref"!=null and .title!=null).title) |
   116        # The "array" and "map" fields have custom unmarshaling. Modify the swagger to reflect this.
   117        .definitions.v1alpha1ApplicationSourcePluginParameter.properties.array = {"description":"Array is the value of an array type parameter.","type":"array","items":{"type":"string"}} |
   118        del(.definitions.v1alpha1OptionalArray) |
   119        .definitions.v1alpha1ApplicationSourcePluginParameter.properties.map = {"description":"Map is the value of a map type parameter.","type":"object","additionalProperties":{"type":"string"}} |
   120        del(.definitions.v1alpha1OptionalMap) |
   121        # Output for int64 is incorrect, because it is based on proto definitions, where int64 is a string. In our JSON API, we expect int64 to be an integer. https://github.com/grpc-ecosystem/grpc-gateway/issues/219
   122        (.definitions[]?.properties[]? | select(.type == "string" and .format == "int64")) |= (.type = "integer")
   123      ' "${COMBINED_SWAGGER}" | \
   124      jq '.definitions.v1Time.type = "string" | .definitions.v1Time.format = "date-time" | del(.definitions.v1Time.properties)' | \
   125      jq '.definitions.v1alpha1ResourceNode.allOf = [{"$ref": "#/definitions/v1alpha1ResourceRef"}] | del(.definitions.v1alpha1ResourceNode.properties.resourceRef) ' \
   126      > "${SWAGGER_OUT}"
   127  
   128      /bin/rm "${PRIMARY_SWAGGER}" "${COMBINED_SWAGGER}"
   129  }
   130  
   131  # clean up generated swagger files (should come after collect_swagger)
   132  clean_swagger() {
   133      SWAGGER_ROOT="$1"
   134      find "${SWAGGER_ROOT}" -name '*.swagger.json' -delete
   135  }
   136  
   137  collect_swagger server
   138  clean_swagger server
   139  clean_swagger reposerver
   140  clean_swagger controller
   141  clean_swagger cmpserver
   142