188 lines
5.2 KiB
Go
188 lines
5.2 KiB
Go
/*
|
|
* Copyright 2022 CloudWeGo Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"golib.gaore.com/GaoreGo/gr_hz/meta"
|
|
"golib.gaore.com/GaoreGo/gr_hz/util"
|
|
"golib.gaore.com/GaoreGo/gr_hz/util/logs"
|
|
)
|
|
|
|
func lookupTool(idlType string) (string, error) {
|
|
tool := meta.TpCompilerThrift
|
|
if idlType == meta.IdlProto {
|
|
tool = meta.TpCompilerProto
|
|
}
|
|
|
|
path, err := exec.LookPath(tool)
|
|
logs.Debugf("[DEBUG]path:%v", path)
|
|
if err != nil {
|
|
goPath, err := util.GetGOPATH()
|
|
if err != nil {
|
|
return "", fmt.Errorf("get 'GOPATH' failed for find %s : %v", tool, path)
|
|
}
|
|
path = filepath.Join(goPath, "bin", tool)
|
|
}
|
|
|
|
isExist, err := util.PathExist(path)
|
|
if err != nil {
|
|
return "", fmt.Errorf("check '%s' path error: %v", path, err)
|
|
}
|
|
|
|
if !isExist {
|
|
if tool == meta.TpCompilerThrift {
|
|
// If thriftgo does not exist, the latest version will be installed automatically.
|
|
err := util.InstallAndCheckThriftgo()
|
|
if err != nil {
|
|
return "", fmt.Errorf("can't install '%s' automatically, please install it manually for https://github.com/cloudwego/thriftgo, err : %v", tool, err)
|
|
}
|
|
} else {
|
|
// todo: protoc automatic installation
|
|
return "", fmt.Errorf("%s is not installed, please install it first", tool)
|
|
}
|
|
}
|
|
|
|
if tool == meta.TpCompilerThrift {
|
|
// If thriftgo exists, the version is detected; if the version is lower than v0.2.0 then the latest version of thriftgo is automatically installed.
|
|
err := util.CheckAndUpdateThriftgo()
|
|
if err != nil {
|
|
return "", fmt.Errorf("update thriftgo version failed, please install it manually for https://github.com/cloudwego/thriftgo, err: %v", err)
|
|
}
|
|
}
|
|
|
|
return path, nil
|
|
}
|
|
|
|
// link removes the previous symbol link and rebuilds a new one.
|
|
func link(src, dst string) error {
|
|
err := syscall.Unlink(dst)
|
|
if err != nil && !os.IsNotExist(err) {
|
|
return fmt.Errorf("unlink %q: %s", dst, err)
|
|
}
|
|
err = os.Symlink(src, dst)
|
|
if err != nil {
|
|
return fmt.Errorf("symlink %q: %s", dst, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func BuildPluginCmd(args *Argument) (*exec.Cmd, error) {
|
|
exe, err := os.Executable()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to detect current executable, err: %v", err)
|
|
}
|
|
|
|
argPacks, err := args.Pack()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
kas := strings.Join(argPacks, ",")
|
|
|
|
path, err := lookupTool(args.IdlType)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cmd := &exec.Cmd{
|
|
Path: path,
|
|
}
|
|
|
|
if args.IdlType == meta.IdlThrift {
|
|
// thriftgo
|
|
os.Setenv(meta.EnvPluginMode, meta.ThriftPluginName)
|
|
cmd.Args = append(cmd.Args, meta.TpCompilerThrift)
|
|
for _, inc := range args.Includes {
|
|
cmd.Args = append(cmd.Args, "-i", inc)
|
|
}
|
|
|
|
if args.Verbose {
|
|
cmd.Args = append(cmd.Args, "-v")
|
|
}
|
|
thriftOpt, err := args.GetThriftgoOptions()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cmd.Args = append(cmd.Args,
|
|
"-o", args.ModelOutDir(),
|
|
"-g", thriftOpt,
|
|
"-p", "hertz="+exe+":"+kas,
|
|
)
|
|
for _, p := range args.ThriftPlugins {
|
|
cmd.Args = append(cmd.Args, "-p", p)
|
|
}
|
|
if !args.NoRecurse {
|
|
cmd.Args = append(cmd.Args, "-r")
|
|
}
|
|
} else {
|
|
// protoc
|
|
os.Setenv(meta.EnvPluginMode, meta.ProtocPluginName)
|
|
cmd.Args = append(cmd.Args, meta.TpCompilerProto)
|
|
for _, inc := range args.Includes {
|
|
cmd.Args = append(cmd.Args, "-I", inc)
|
|
}
|
|
for _, inc := range args.IdlPaths {
|
|
cmd.Args = append(cmd.Args, "-I", filepath.Dir(inc))
|
|
}
|
|
cmd.Args = append(cmd.Args,
|
|
"--plugin=protoc-gen-hertz="+exe,
|
|
"--hertz_out="+args.OutDir,
|
|
"--hertz_opt="+kas,
|
|
)
|
|
for _, p := range args.ProtobufPlugins {
|
|
pluginParams := strings.Split(p, ":")
|
|
if len(pluginParams) != 3 {
|
|
logs.Warnf("Failed to get the correct protoc plugin parameters for %. "+
|
|
"Please specify the protoc plugin in the form of \"plugin_name:options:out_dir\"", p)
|
|
os.Exit(1)
|
|
}
|
|
// pluginParams[0] -> plugin name, pluginParams[1] -> plugin options, pluginParams[2] -> out_dir
|
|
cmd.Args = append(cmd.Args,
|
|
fmt.Sprintf("--%s_out=%s", pluginParams[0], pluginParams[2]),
|
|
fmt.Sprintf("--%s_opt=%s", pluginParams[0], pluginParams[1]),
|
|
)
|
|
}
|
|
for _, kv := range args.ProtocOptions {
|
|
cmd.Args = append(cmd.Args, "--"+kv)
|
|
}
|
|
}
|
|
|
|
cmd.Args = append(cmd.Args, args.IdlPaths...)
|
|
logs.Infof(strings.Join(cmd.Args, " "))
|
|
logs.Flush()
|
|
return cmd, nil
|
|
}
|
|
|
|
func (arg *Argument) GetThriftgoOptions() (string, error) {
|
|
defaultOpt := "reserve_comments,gen_json_tag=false,"
|
|
prefix, err := arg.ModelPackagePrefix()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
arg.ThriftOptions = append(arg.ThriftOptions, "package_prefix="+prefix)
|
|
if arg.JSONEnumStr {
|
|
arg.ThriftOptions = append(arg.ThriftOptions, "json_enum_as_text")
|
|
}
|
|
gas := "go:" + defaultOpt + strings.Join(arg.ThriftOptions, ",")
|
|
return gas, nil
|
|
}
|