goctl add plugin support (#243)

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* add plugin support

* remove no need

* add plugin support

* rename

* rename

* add plugin support

* refactor

* update plugin

* refactor

* refactor

* refactor

* update plugin

* newline

Co-authored-by: anqiansong <anqiansong@xiaoheiban.cn>
master
kingxt 4 years ago committed by GitHub
parent 7cd0463953
commit cecd4b1b75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -20,6 +20,7 @@ import (
"github.com/tal-tech/go-zero/tools/goctl/docker" "github.com/tal-tech/go-zero/tools/goctl/docker"
"github.com/tal-tech/go-zero/tools/goctl/kube" "github.com/tal-tech/go-zero/tools/goctl/kube"
model "github.com/tal-tech/go-zero/tools/goctl/model/sql/command" model "github.com/tal-tech/go-zero/tools/goctl/model/sql/command"
"github.com/tal-tech/go-zero/tools/goctl/plugin"
rpc "github.com/tal-tech/go-zero/tools/goctl/rpc/cli" rpc "github.com/tal-tech/go-zero/tools/goctl/rpc/cli"
"github.com/tal-tech/go-zero/tools/goctl/tpl" "github.com/tal-tech/go-zero/tools/goctl/tpl"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -186,6 +187,30 @@ var (
}, },
Action: ktgen.KtCommand, Action: ktgen.KtCommand,
}, },
{
Name: "plugin",
Usage: "custom file generator",
Flags: []cli.Flag{
cli.StringFlag{
Name: "plugin",
Usage: "the plugin file",
},
cli.StringFlag{
Name: "dir",
Usage: "the target directory",
},
cli.StringFlag{
Name: "api",
Usage: "the api file",
},
cli.StringFlag{
Name: "style",
Required: false,
Usage: "the file naming format, see [https://github.com/tal-tech/go-zero/tree/master/tools/goctl/config/readme.md]",
},
},
Action: plugin.PluginCommand,
},
}, },
}, },
{ {

@ -0,0 +1,20 @@
package main
import (
"fmt"
"github.com/tal-tech/go-zero/tools/goctl/plugin"
)
func main() {
plugin, err := plugin.NewPlugin()
if err != nil {
panic(err)
}
if plugin.Api != nil {
fmt.Printf("api: %+v \n", plugin.Api)
}
fmt.Printf("dir: %s \n", plugin.Dir)
fmt.Println("Enjoy anything you want.")
}

@ -0,0 +1,166 @@
package plugin
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/tal-tech/go-zero/tools/goctl/api/parser"
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
"github.com/tal-tech/go-zero/tools/goctl/rpc/execx"
"github.com/tal-tech/go-zero/tools/goctl/util"
"github.com/urfave/cli"
)
const (
pluginArg = "_plugin"
)
type Plugin struct {
Api *spec.ApiSpec
Style string
Dir string
}
func PluginCommand(c *cli.Context) error {
ex, err := os.Executable()
if err != nil {
panic(err)
}
var plugin = c.String("plugin")
if len(plugin) == 0 {
return errors.New("missing plugin")
}
transferData, err := prepareArgs(c)
if err != nil {
return err
}
bin, download, err := getCommand(plugin)
if err != nil {
return err
}
if download {
defer func() {
_ = os.Remove(bin)
}()
}
content, err := execx.Run(bin, filepath.Dir(ex), bytes.NewBuffer(transferData))
if err != nil {
return err
}
fmt.Println(content)
return nil
}
func prepareArgs(c *cli.Context) ([]byte, error) {
apiPath := c.String("api")
var transferData Plugin
if len(apiPath) > 0 && util.FileExists(apiPath) {
p, err := parser.NewParser(apiPath)
if err != nil {
return nil, err
}
api, err := p.Parse()
if err != nil {
return nil, err
}
transferData.Api = api
}
dirAbs, err := filepath.Abs(c.String("dir"))
if err != nil {
return nil, err
}
transferData.Dir = dirAbs
transferData.Style = c.String("style")
data, err := json.Marshal(transferData)
if err != nil {
return nil, err
}
return data, nil
}
func getCommand(arg string) (string, bool, error) {
p, err := exec.LookPath(arg)
if err == nil {
abs, err := filepath.Abs(p)
if err != nil {
return "", false, err
}
return abs, false, nil
}
var defaultErr = errors.New("invalid plugin value " + arg)
if strings.HasPrefix(arg, "http") {
items := strings.Split(arg, "/")
if len(items) == 0 {
return "", false, defaultErr
}
filename, err := filepath.Abs(pluginArg + items[len(items)-1])
if err != nil {
return "", false, err
}
err = downloadFile(filename, arg)
if err != nil {
return "", false, err
}
os.Chmod(filename, os.ModePerm)
return filename, true, nil
}
return arg, false, nil
}
func downloadFile(filepath string, url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer func() {
_ = resp.Body.Close()
}()
out, err := os.Create(filepath)
if err != nil {
return err
}
defer func() {
_ = out.Close()
}()
_, err = io.Copy(out, resp.Body)
return err
}
func NewPlugin() (*Plugin, error) {
var plugin Plugin
content, err := ioutil.ReadAll(os.Stdin)
if err != nil {
return nil, err
}
err = json.Unmarshal(content, &plugin)
if err != nil {
return nil, err
}
return &plugin, nil
}

@ -12,7 +12,7 @@ import (
"github.com/tal-tech/go-zero/tools/goctl/vars" "github.com/tal-tech/go-zero/tools/goctl/vars"
) )
func Run(arg string, dir string) (string, error) { func Run(arg string, dir string, in ...*bytes.Buffer) (string, error) {
goos := runtime.GOOS goos := runtime.GOOS
var cmd *exec.Cmd var cmd *exec.Cmd
switch goos { switch goos {
@ -28,6 +28,9 @@ func Run(arg string, dir string) (string, error) {
} }
stdout := new(bytes.Buffer) stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer) stderr := new(bytes.Buffer)
if len(in) > 0 {
cmd.Stdin = in[0]
}
cmd.Stdout = stdout cmd.Stdout = stdout
cmd.Stderr = stderr cmd.Stderr = stderr
err := cmd.Run() err := cmd.Run()

@ -17,3 +17,12 @@ func Untitle(s string) string {
return strings.ToLower(s[:1]) + s[1:] return strings.ToLower(s[:1]) + s[1:]
} }
func Index(slice []string, item string) int {
for i, _ := range slice {
if slice[i] == item {
return i
}
}
return -1
}

Loading…
Cancel
Save