From f4f95e0e2af66e61bfebfb07f5ec2c6dfbaf2a7d Mon Sep 17 00:00:00 2001 From: Eugene Palchukovsky Date: Mon, 4 Nov 2019 00:43:03 +0200 Subject: [PATCH] Support gRPC Web plugin install --- README.md | 5 +- main.go | 117 ++++++++++++++++++++++++++++++-------------- platform_unix.go | 7 ++- platform_windows.go | 7 ++- 4 files changed, 93 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index e683981..15544c9 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,10 @@ Downloads and unpacks Protocol Buffers compiler protoc. ## To run ### Arguments -* -ver: Protocol Buffers compiler version +* -type: "cli" for protoc or "grpc-web" for gRPC Web protoc plugin +* -ver: version to install * -out: output directory ### Example ```shell - protoc-install -ver 3.10.1 -out bin + protoc-install -type cli -ver 3.10.1 -out bin ``` \ No newline at end of file diff --git a/main.go b/main.go index b427434..df22d63 100644 --- a/main.go +++ b/main.go @@ -12,7 +12,9 @@ import ( ) var ( - version = flag.String("ver", "", "protoc version, for ex. 3.10.1") + protocType = flag.String("type", "protoc", + `type, "cli" for protoc or "grpc-web" for gRPC Web protoc plugin`) + version = flag.String("ver", "", "version to install, for ex. 3.10.1") outDir = flag.String("out", "", "output directory") ) @@ -22,48 +24,72 @@ func main() { log.Fatal("Version is not set.\n") } if len(*outDir) == 0 { - log.Fatal("Destination is not set.\n") + log.Fatal("Out is not set.\n") } - - binFilePath := filepath.Join(*outDir, binFile) - if _, err := os.Stat(binFilePath); !os.IsNotExist(err) { - log.Printf("protoc is already existing (\"%s\").\n", binFilePath) + if *protocType == "cli" { + installProtoc() return } + if *protocType == "grpc-web" { + installGRPCWebPlugin() + return + } + log.Fatal("Unknown type.\n") +} - archFile := fmt.Sprintf("protoc-%s-%s.zip", *version, platform) - archFilePath := filepath.Join(*outDir, archFile) - if _, err := os.Stat(binFilePath); os.IsNotExist(err) { +func download(source, file string) string { + path := filepath.Join(*outDir, file) + if _, err := os.Stat(path); !os.IsNotExist(err) { + return path + } - url := fmt.Sprintf("https://github.com/protocolbuffers/protobuf/releases/download/v%s/%s", *version, archFile) - log.Printf("Downloading protoc archive from \"%s\"...\n", url) + log.Printf("Downloading from \"%s\"...\n", source) - if err = os.MkdirAll(filepath.Dir(archFilePath), os.ModePerm); err != nil { - panic(err) - } + err := os.MkdirAll(filepath.Dir(path), os.ModePerm) + if err != nil { + panic(err) + } - resp, err := http.Get(url) - if err != nil { - panic(err) - } - defer resp.Body.Close() + response, err := http.Get(source) + if err != nil { + panic(err) + } + defer response.Body.Close() - out, err := os.Create(archFilePath) - if err != nil { - panic(err) - } - defer func() { - out.Close() - if err := os.Remove(archFilePath); err != nil { - log.Printf("Failed to remove archive file: \"%s\".", err) - } - }() - - _, err = io.Copy(out, resp.Body) - if err != nil { - panic(err) - } + out, err := os.Create(path) + if err != nil { + panic(err) } + defer out.Close() + + _, err = io.Copy(out, response.Body) + if err != nil { + panic(err) + } + + return path +} + +func remove(path string) { + if err := os.Remove(path); err != nil { + log.Printf("Failed to remove \"%s\": \"%s\".", path, err) + } +} + +func installProtoc() { + + binFilePath := filepath.Join(*outDir, protocFile) + if _, err := os.Stat(binFilePath); !os.IsNotExist(err) { + log.Printf("protoc is already existing (\"%s\").\n", binFilePath) + return + } + + archFile := fmt.Sprintf("protoc-%s-%s.zip", *version, protocPlatform) + url := fmt.Sprintf( + "https://github.com/protocolbuffers/protobuf/releases/download/v%s/%s", + *version, archFile) + archFilePath := download(url, archFile) + defer remove(archFilePath) log.Printf("Unpacking into \"%s\"...\n", binFilePath) arch, err := zip.OpenReader(archFilePath) @@ -72,7 +98,7 @@ func main() { } defer arch.Close() - binInsideArchPath := "bin/" + binFile + binInsideArchPath := "bin/" + protocFile for _, file := range arch.File { if file.Name != binInsideArchPath { continue @@ -81,7 +107,6 @@ func main() { if err != nil { panic(err) } - defer bin.Close() r, err := file.Open() if err != nil { panic(err) @@ -91,9 +116,27 @@ func main() { if err != nil { panic(err) } - log.Println("Successfully installed.") + bin.Close() + err = os.Chmod(binFilePath, 0777) + if err != nil { + panic(err) + } + log.Println("protoc successfully installed.") return } log.Fatalf("Archive \"%s\" does not have protoc.\n", archFilePath) } + +func installGRPCWebPlugin() { + fileName := "protoc-gen-grpc-web" + url := fmt.Sprintf( + "https://github.com/grpc/grpc-web/releases/download/%s/%s-%s-%s%s", + *version, fileName, *version, grpcWebPlatform, grpcWebFileExt) + binFilePath := download(url, fileName+grpcWebFileExt) + err := os.Chmod(binFilePath, 0777) + if err != nil { + panic(err) + } + log.Println("gRPC Web protoc plugin installed.") +} diff --git a/platform_unix.go b/platform_unix.go index 04a4322..32e139d 100644 --- a/platform_unix.go +++ b/platform_unix.go @@ -3,6 +3,9 @@ package main const ( - platform = "linux-x86_64" - binFile = "protoc" + protocPlatform = "linux-x86_64" + protocFile = "protoc" + + grpcWebPlatform = "linux-x86_64" + grpcWebFileExt = "" ) diff --git a/platform_windows.go b/platform_windows.go index d1306ee..144acf0 100644 --- a/platform_windows.go +++ b/platform_windows.go @@ -3,6 +3,9 @@ package main const ( - platform = "win64" - binFile = "protoc.exe" + protocPlatform = "win64" + protocFile = "protoc.exe" + + grpcWebPlatform = "windows-x86_64" + grpcWebFileExt = ".exe" )