From 4cbc3b2156a3f13822f75270b660872eab8ca605 Mon Sep 17 00:00:00 2001
From: ko_oler <kooler89@gmail.com>
Date: Sun, 23 Feb 2025 23:19:32 +0300
Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?=
 =?UTF-8?q?=D0=BD=D1=8B=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D1=8B=20?=
 =?UTF-8?q?=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=D0=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Makefile      | 40 ++++++++++++++++++++++++++++++++++++----
 Taskfile.yaml | 39 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index c52dd2ad..6a1b9a8b 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,8 @@ ALLPROTO?=$(shell find -L $(PROTODIR) -name '*.proto' )
 # Убираем status.proto нужен только для front
 PROTOFILES=	$(filter-out $(PROTODIR)/status/status.proto, $(ALLPROTO))
 PROTOGOFILES=$(PROTOFILES:.proto=.pb.go)
+PROTOGOGWFILES=$(PROTOFILES:.proto=.gw.go)
+PROTOSWAGGERFILES=$(PROTOFILES:.proto=.swagger.json)
 PROTOGOGRPCFILES=$(PROTOFILES:.proto=_grpc.pb.go)
 
 ACCESSLOGGING=$(shell find -name "logging_middleware.go" -type f)
@@ -16,13 +18,43 @@ SERVICETELEMETRY=$(shell find -name "telemetry_middleware.go" -type f)
 SERVICEMIDDLEWARE=$(shell find -name "middleware.go" -type f)
 SERVICERECOVERING=$(shell find -name "recovering_middleware.go" -type f)
 
-# Генерация grpc-клиентов для go
-proto: protoc-check protoc-gen-go-check $(PROTOGOFILES)
-	@echo "Generate Go from proto files"
+GOOGLEAPIS_PATH := $(shell find ~/go/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@* -type d -name googleapis | head -n 1)
+
+# Генерация go grpc клиентов
+proto: $(PROTOGOFILES)
+	@echo "Generate Go gRPC from proto files"
 	@find $(PROTODIR) -name '*.proto'
 
 %.pb.go: %.proto
-	@protoc -I=$(PROTODIR) --experimental_allow_proto3_optional --go_out=$(DSTDIR) --go-grpc_out=$(DSTDIR) --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative "$<"
+	@protoc -I=$(PROTODIR) --experimental_allow_proto3_optional \
+		--proto_path=$(GOOGLEAPIS_PATH) \
+ 		--go_out=$(DSTDIR) \
+ 		--go-grpc_out=$(DSTDIR) \
+ 		--go_opt=paths=source_relative \
+ 		--go-grpc_opt=paths=source_relative "$<"
+
+# Генерация gateway
+gateway: $(PROTOGOGWFILES)
+	@echo "Generate gRPC-Gateway"
+	@find $(PROTODIR) -name '*.proto'
+
+%.gw.go: %.proto
+	@protoc -I=$(PROTODIR) --experimental_allow_proto3_optional \
+		--proto_path=$(GOOGLEAPIS_PATH) \
+		--grpc-gateway_out=$(DSTDIR) \
+		--grpc-gateway_opt=paths=source_relative \
+		--grpc-gateway_opt=standalone=true \
+		--grpc-gateway_opt=generate_unbound_methods=true "$<"
+
+# Генерация swagger/OpenAPI
+swagger:  $(PROTOSWAGGERFILES)
+	@echo "Generate OpenAPI/Swagger docs"
+	@find $(PROTODIR) -name '*.proto'
+
+%.swagger.json: %.proto
+	@protoc -I=$(PROTODIR) --experimental_allow_proto3_optional \
+		--proto_path=$(GOOGLEAPIS_PATH) \
+		--openapiv2_out=$(DSTDIR) "$<"
 
 proto-clean:
 	@rm -r $(DSTDIR)/*
diff --git a/Taskfile.yaml b/Taskfile.yaml
index 4a97ef91..7e215275 100644
--- a/Taskfile.yaml
+++ b/Taskfile.yaml
@@ -5,6 +5,8 @@ vars:
   PBDIR: proto
   DATE:
     sh: date -Idate
+  GOOGLEAPIS_PATH:
+    sh: find ~/go/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@* -type d -name googleapis | head -n 1
 
 tasks:
   tools:brew:
@@ -17,6 +19,8 @@ tasks:
       - brew install mockery
       - brew install protoc-gen-go
       - brew install protoc-gen-go-grpc
+      - brew install protoc-gen-grpc-gateway
+      - brew install protoc-gen-openapiv2
 
   # Тесты
 
@@ -136,8 +140,41 @@ tasks:
   gen:proto:file:
     desc: "Преобразует переданный .proto файл в код на языке Go для работы с сообщениями protobuf и сервисами gRPC."
     cmds:
-      - protoc -I={{ .PROTODIR }} --experimental_allow_proto3_optional --go_out={{ .PBDIR }} --go-grpc_out={{ .PBDIR }} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative {{ .FILE }}
+      - protoc -I={{ .PROTODIR }} --proto_path={{ .GOOGLEAPIS_PATH }} --experimental_allow_proto3_optional --go_out={{ .PBDIR }} --go-grpc_out={{ .PBDIR }} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative {{ .FILE }}
 
+  gen:gateway:
+    desc: "Генерирует gRPC-Gateway код для всех .proto файлов"
+    sources:
+      - "{{ .PROTODIR }}/**/*.proto"
+      - exclude: "{{ .PROTODIR }}/status/status.proto"
+    cmds:
+      - for: sources
+        task: gen:gateway:file
+        vars:
+          FILE: "{{ .ITEM }}"
+        silent: true
+
+  gen:gateway:file:
+    desc: "Генерирует gRPC-Gateway код для переданного .proto файла"
+    cmds:
+      - protoc -I={{ .PROTODIR }} --proto_path={{ .GOOGLEAPIS_PATH }} --experimental_allow_proto3_optional --grpc-gateway_out={{ .PBDIR }}  --grpc-gateway_opt=paths=source_relative --grpc-gateway_opt=standalone=true --grpc-gateway_opt=generate_unbound_methods=true {{ .FILE }}
+
+  gen:swagger:
+    desc: "Генерирует OpenAPI/Swagger документацию для всех .proto файлов"
+    sources:
+      - "{{ .PROTODIR }}/**/*.proto"
+      - exclude: "{{ .PROTODIR }}/status/status.proto"
+    cmds:
+      - for: sources
+        task: gen:swagger:file
+        vars:
+          FILE: "{{ .ITEM }}"
+        silent: true
+
+  gen:swagger:file:
+    desc: "Генерирует OpenAPI/Swagger JSON для переданного .proto файла"
+    cmds:
+      - protoc -I={{ .PROTODIR }} --proto_path={{ .GOOGLEAPIS_PATH }} --experimental_allow_proto3_optional --openapiv2_out={{ .PBDIR }} {{ .FILE }}
 
   gen:middleware:
     desc: "Генерирует middleware для всех пакетов"
-- 
GitLab