first
This commit is contained in:
parent
7371c6d4e0
commit
c6a2bcbb4c
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.*
|
||||||
|
!.gitignore
|
||||||
|
/go.sum
|
||||||
|
|
28
README.md
28
README.md
@ -1,2 +1,28 @@
|
|||||||
# gojs-cli
|
# ag - tools for apigo.cloud
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```shell
|
||||||
|
go install github.com/apigo/ag
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
tools for apigo.cloud
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
ag [command] [...]
|
||||||
|
ag [short command] [...]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
init [i] create a new project with "go mod init"、"go mod tidy" etc.
|
||||||
|
initPlugin [ip] name create a new plugin project with "go mod init"、"go mod tidy" etc.
|
||||||
|
initServer [is] name create a new server project with "go mod init"、"go mod tidy" etc.
|
||||||
|
pluginsCode [pc] export typescript code for used plugins into "plugins/"
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
ag i init a new simple project with Hello World
|
||||||
|
ag ip ali init a new plugin project named ali for use aliyun services
|
||||||
|
```
|
||||||
|
|
||||||
|
31
go.mod
Normal file
31
go.mod
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
module apigo.cloud/git/apigo/ag
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/ssgo/u v1.7.2
|
||||||
|
|
||||||
|
require (
|
||||||
|
apigo.cloud/git/apigo/plugin v1.0.1 // indirect
|
||||||
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
|
github.com/gomodule/redigo v1.8.8 // indirect
|
||||||
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||||
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||||
|
github.com/shirou/gopsutil/v3 v3.22.10 // indirect
|
||||||
|
github.com/ssgo/config v1.7.2 // indirect
|
||||||
|
github.com/ssgo/discover v1.7.2 // indirect
|
||||||
|
github.com/ssgo/httpclient v1.7.2 // indirect
|
||||||
|
github.com/ssgo/log v1.7.2 // indirect
|
||||||
|
github.com/ssgo/redis v1.7.2 // indirect
|
||||||
|
github.com/ssgo/s v1.7.2 // indirect
|
||||||
|
github.com/ssgo/standard v1.7.2 // indirect
|
||||||
|
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||||
|
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||||
|
golang.org/x/text v0.3.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace apigo.cloud/git/apigo/gojs v0.0.3 => ../gojs
|
295
main.go
Normal file
295
main.go
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"github.com/ssgo/u"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed templates/_makePluginCode.go
|
||||||
|
var makePluginCodeTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_main.go
|
||||||
|
var mainCodeTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_main_test.go
|
||||||
|
var mainTestCodeTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_main.js
|
||||||
|
var mainJSCodeTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_plugin.go
|
||||||
|
var pluginCodeTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_plugin_test.go
|
||||||
|
var pluginTestCodeTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_plugin_test.js
|
||||||
|
var pluginTestJSCodeTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_gitignore
|
||||||
|
var gitignoreTPL string
|
||||||
|
|
||||||
|
//go:embed templates/_gitignore_server
|
||||||
|
var gitignoreServerTPL string
|
||||||
|
|
||||||
|
type Command struct {
|
||||||
|
Name string
|
||||||
|
ShortName string
|
||||||
|
Args string
|
||||||
|
Comment string
|
||||||
|
Func func([]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO js 缓存 & 开发模式检测自动(gowatch 不再监听 js)
|
||||||
|
var commands = []Command{
|
||||||
|
{"new", "+", "[name]", "create a new project, will create in the current directory if no name is specified", newProject},
|
||||||
|
{"new plugin", "+p", "[name]", "create a new plugin project, will create in the current directory if no name is specified", newPluginProject},
|
||||||
|
//{"new server", "+s", "[name]", "create a new server project, will create in the current directory if no name is specified", newServerProject},
|
||||||
|
//{"new api", "+a", "[path] [method]", "create a new api for server project, will use restful api if specified http method", newServerAPI},
|
||||||
|
{"run", "r", "[...more gowatch args]", "run project use gowatch, if project files changed will restart auto, gowatch args help see: https://github.com/ssgo/tool", runProject},
|
||||||
|
{"test", "t", "[...more gowatch args]", "test project use gowatch, if project files changed will restart auto, gowatch args help see: https://github.com/ssgo/tool", testProject},
|
||||||
|
{"export plugins", "ep", "", "export typescript code for used plugins into \"plugins/\"", makePluginCode},
|
||||||
|
//{"git login", "/lg", "", "login to apigo.cloud/git", },
|
||||||
|
//{"git new", "/+", "name", "create new public repository from apigo.cloud/git", },
|
||||||
|
//{"git new pri", "/++", "name", "create new private repository from apigo.cloud/git", },
|
||||||
|
//{"git clone", "/cl", "name", "clone repository to current dir from apigo.cloud/git", },
|
||||||
|
//{"git list", "/l", "", "list current repository tags from apigo.cloud/git", },
|
||||||
|
//{"git commit", "/c", "comment", "commit current repository to apigo.cloud/git", },
|
||||||
|
//{"git tag", "/t", "tag", "create new tag for current repository and push to apigo.cloud/git", },
|
||||||
|
}
|
||||||
|
|
||||||
|
func findTool() (gowatchPath string, logvPath string) {
|
||||||
|
gowatchPath = "gowatch"
|
||||||
|
logvPath = "logv"
|
||||||
|
if binPath, err := exec.LookPath("gowatch"); err == nil && binPath != "" {
|
||||||
|
gowatchPath = binPath
|
||||||
|
}
|
||||||
|
if binPath, err := exec.LookPath("logv"); err == nil && binPath != "" {
|
||||||
|
logvPath = binPath
|
||||||
|
}
|
||||||
|
return gowatchPath, logvPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkSSGOTool() {
|
||||||
|
gowatchPath, logvPath := findTool()
|
||||||
|
if gowatchPath == "gowatch" || logvPath == "logv" {
|
||||||
|
_ = runCommand("go", "get", "-u", "github.com/ssgo/tool")
|
||||||
|
if gowatchPath == "gowatch" {
|
||||||
|
_ = runCommand("go", "install", "github.com/ssgo/tool/gowatch")
|
||||||
|
}
|
||||||
|
if logvPath == "logv" {
|
||||||
|
_ = runCommand("go", "install", "github.com/ssgo/tool/logv")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkProjectPath(args []string) string {
|
||||||
|
if len(args) > 0 {
|
||||||
|
if err := os.Mkdir(args[0], 0755); err != nil {
|
||||||
|
fmt.Println(u.BRed("mkdir error: " + err.Error()))
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if err := os.Chdir(args[0]); err != nil {
|
||||||
|
fmt.Println(u.BRed("chdir error: " + err.Error()))
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return args[0]
|
||||||
|
} else {
|
||||||
|
if pathname, err := os.Getwd(); err != nil {
|
||||||
|
fmt.Println(u.BRed("getwd error: " + err.Error()))
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
return path.Base(pathname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newProject(args []string) {
|
||||||
|
if name := checkProjectPath(args); name != "" {
|
||||||
|
_ = runCommand("go", "mod", "init", name)
|
||||||
|
_ = runCommand("go", "mod", "edit", "-go=1.18")
|
||||||
|
_ = runCommand("go", "get", "-u", "apigo.cloud/git/apigo/gojs")
|
||||||
|
_ = runCommand("go", "get", "-u", "apigo.cloud/git/apigo/plugins")
|
||||||
|
writeFile("main.go", mainCodeTPL, map[string]any{"name": name})
|
||||||
|
writeFile("main_test.go", mainTestCodeTPL, map[string]any{"name": name})
|
||||||
|
writeFile("main.js", mainJSCodeTPL, map[string]any{"name": name})
|
||||||
|
writeFile(".gitignore", gitignoreTPL, map[string]any{"name": name})
|
||||||
|
_ = runCommand("go", "mod", "tidy")
|
||||||
|
checkSSGOTool()
|
||||||
|
fmt.Println(u.BGreen("new project " + name + " created"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPluginProject(args []string) {
|
||||||
|
if name := checkProjectPath(args); name != "" {
|
||||||
|
_ = runCommand("go", "mod", "init", name)
|
||||||
|
_ = runCommand("go", "mod", "edit", "-go=1.18")
|
||||||
|
_ = runCommand("go", "get", "-u", "apigo.cloud/git/apigo/plugin")
|
||||||
|
writeFile("plugin.go", pluginCodeTPL, map[string]any{"name": name})
|
||||||
|
writeFile(".gitignore", gitignoreTPL, map[string]any{"name": name})
|
||||||
|
_ = runCommand("go", "mod", "tidy")
|
||||||
|
_ = os.Mkdir("tests", 0755)
|
||||||
|
_ = os.Chdir("tests")
|
||||||
|
_ = runCommand("go", "mod", "init", "tests")
|
||||||
|
_ = runCommand("go", "mod", "edit", "-go=1.18")
|
||||||
|
_ = runCommand("go", "mod", "edit", "-require=current-plugin@v0.0.0")
|
||||||
|
_ = runCommand("go", "mod", "edit", "-replace=current-plugin@v0.0.0=../")
|
||||||
|
_ = runCommand("go", "get", "-u", "apigo.cloud/git/apigo/plugin")
|
||||||
|
_ = runCommand("go", "get", "-u", "apigo.cloud/git/apigo/gojs")
|
||||||
|
writeFile("plugin_test.go", pluginTestCodeTPL, map[string]any{"name": name})
|
||||||
|
writeFile("plugin_test.js", pluginTestJSCodeTPL, map[string]any{"name": name})
|
||||||
|
_ = runCommand("go", "mod", "tidy")
|
||||||
|
checkSSGOTool()
|
||||||
|
fmt.Println(u.BGreen("new plugin " + name + " created"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServerProject(args []string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServerAPI(args []string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func runProject(args []string) {
|
||||||
|
gowatchPath, logvPath := findTool()
|
||||||
|
_ = runCommandPipe(logvPath, gowatchPath, "-pt", ".go,.json,.yml,.js,.ts", "run", ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testProject(args []string) {
|
||||||
|
gowatchPath, logvPath := findTool()
|
||||||
|
if u.FileExists("tests") {
|
||||||
|
_ = os.Chdir("tests")
|
||||||
|
fmt.Println(logvPath, gowatchPath)
|
||||||
|
_ = runCommandPipe(logvPath, gowatchPath, "-p", ".,..", "-pt", ".go,.yml,.js,.ts", "test", "-v", ".")
|
||||||
|
} else {
|
||||||
|
_ = runCommandPipe(logvPath, gowatchPath, "-pt", ".go,.yml,.js,.ts", "test", "-v", ".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkgMatcher = regexp.MustCompile(`(?m)^\s*_\s+"([\w-_/.]+)"`)
|
||||||
|
|
||||||
|
func makePluginCodeImports(from string, imports *[]string) {
|
||||||
|
if files, err := os.ReadDir(from); err == nil {
|
||||||
|
for _, f := range files {
|
||||||
|
if f.IsDir() {
|
||||||
|
if !strings.HasPrefix(f.Name(), ".") {
|
||||||
|
makePluginCodeImports(path.Join(from, f.Name()), imports)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if strings.HasSuffix(f.Name(), ".go") && !strings.HasPrefix(f.Name(), ".") && f.Name() != "makePluginCode.go" {
|
||||||
|
if code, err := u.ReadFile(path.Join(from, f.Name())); err == nil {
|
||||||
|
for _, m := range pkgMatcher.FindAllStringSubmatch(code, 1024) {
|
||||||
|
*imports = u.AppendUniqueString(*imports, m[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeFile(filename string, fileContent string, data any) {
|
||||||
|
if fp, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600); err == nil {
|
||||||
|
tpl, _ := template.New(filename).Parse(fileContent)
|
||||||
|
if err = tpl.Execute(fp, data); err != nil {
|
||||||
|
fmt.Println(u.Red(err.Error()))
|
||||||
|
}
|
||||||
|
_ = fp.Close()
|
||||||
|
} else {
|
||||||
|
fmt.Println(u.Red(err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makePluginCode(args []string) {
|
||||||
|
imports := make([]string, 0)
|
||||||
|
makePluginCodeImports(".", &imports)
|
||||||
|
if len(imports) > 0 {
|
||||||
|
writeFile("makePluginCode.go", makePluginCodeTPL, map[string]any{"imports": imports})
|
||||||
|
if err := runCommand("go", "run", "makePluginCode.go"); err != nil {
|
||||||
|
fmt.Println(u.Red(err.Error()))
|
||||||
|
}
|
||||||
|
_ = os.Remove("makePluginCode.go")
|
||||||
|
} else {
|
||||||
|
fmt.Println(u.Red("no plugin imported"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCommand(name string, args ...string) error {
|
||||||
|
cmd := exec.Command(name, args...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCommandPipe(pipeCommandName, commandName string, args ...string) error {
|
||||||
|
cmd1 := exec.Command(commandName, args...)
|
||||||
|
cmd2 := exec.Command(pipeCommandName)
|
||||||
|
|
||||||
|
r, w := io.Pipe()
|
||||||
|
defer w.Close()
|
||||||
|
cmd1.Stdout = w
|
||||||
|
cmd1.Stderr = w
|
||||||
|
cmd2.Stdin = r
|
||||||
|
cmd2.Stdout = os.Stdout
|
||||||
|
cmd2.Stderr = os.Stderr
|
||||||
|
if err := cmd2.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := cmd1.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := cmd1.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 等待第二个命令完成
|
||||||
|
if err := cmd2.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
cmd1 := os.Args[1]
|
||||||
|
cmd2 := cmd1
|
||||||
|
if len(os.Args) > 2 {
|
||||||
|
cmd2 += " " + os.Args[2]
|
||||||
|
}
|
||||||
|
for _, cmdInfo := range commands {
|
||||||
|
if cmd1 == cmdInfo.Name || cmd1 == cmdInfo.ShortName {
|
||||||
|
cmdInfo.Func(os.Args[2:])
|
||||||
|
return
|
||||||
|
} else if cmd2 == cmdInfo.Name {
|
||||||
|
cmdInfo.Func(os.Args[3:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("tools for apigo.cloud")
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Usage:")
|
||||||
|
fmt.Println(" ", u.Cyan("ag [command] [...]"))
|
||||||
|
fmt.Println(" ", u.Magenta("ag [short command] [...]"))
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Commands:")
|
||||||
|
for _, cmdInfo := range commands {
|
||||||
|
fmt.Println(" ", u.Cyan(cmdInfo.Name), u.Dim("[")+u.Magenta(cmdInfo.ShortName)+u.Dim("]"), cmdInfo.Args, strings.Repeat(" ", 30-len(cmdInfo.Name)-len(cmdInfo.ShortName)-len(cmdInfo.Args)), cmdInfo.Comment)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Examples:")
|
||||||
|
fmt.Println(" ", u.Magenta("ag +"), " create a new simple project with Hello World")
|
||||||
|
fmt.Println(" ", u.Magenta("ag +p ali"), " create a new plugin project named ali for use aliyun services")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println(findTool())
|
||||||
|
|
||||||
|
}
|
3
templates/_gitignore
Normal file
3
templates/_gitignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.*
|
||||||
|
!.gitignore
|
||||||
|
/go.sum
|
7
templates/_gitignore_server
Normal file
7
templates/_gitignore_server
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.*
|
||||||
|
!.gitignore
|
||||||
|
/go.sum
|
||||||
|
/www
|
||||||
|
/server
|
||||||
|
/env.yml
|
||||||
|
/env.json
|
20
templates/_main.go
Normal file
20
templates/_main.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"apigo.cloud/git/apigo/gojs"
|
||||||
|
//_ "apigo.cloud/git/apigo/plugins/file"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
worldName := ""
|
||||||
|
gojs.RunFile("main.js", &gojs.RuntimeOption{
|
||||||
|
Globals: map[string]interface{}{
|
||||||
|
"setWorldName": func(name string) {
|
||||||
|
worldName = name
|
||||||
|
},
|
||||||
|
"getWorldName": func() string {
|
||||||
|
return worldName
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
7
templates/_main.js
Normal file
7
templates/_main.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// import file from 'plugins/file';
|
||||||
|
// console.info(file.read('test.txt'))
|
||||||
|
|
||||||
|
setWorldName('gojs')
|
||||||
|
logger.info('Hello '+getWorldName())
|
||||||
|
|
||||||
|
// return 'OK'
|
14
templates/_main_test.go
Normal file
14
templates/_main_test.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package main_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"apigo.cloud/git/apigo/gojs"
|
||||||
|
"github.com/ssgo/u"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPlusNumber(t *testing.T) {
|
||||||
|
r, err, _ := gojs.Run("return 1+2", nil)
|
||||||
|
if err != nil || u.Int(r) != 3 {
|
||||||
|
t.Fatal("TestPlusNumber failed", r, err)
|
||||||
|
}
|
||||||
|
}
|
29
templates/_makePluginCode.go
Normal file
29
templates/_makePluginCode.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"apigo.cloud/git/apigo/gojs"
|
||||||
|
"apigo.cloud/git/apigo/plugin"
|
||||||
|
{{- range .imports}}
|
||||||
|
_ "{{.}}"
|
||||||
|
{{- end}}
|
||||||
|
"fmt"
|
||||||
|
"github.com/ssgo/u"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
for _, plg := range plugin.List() {
|
||||||
|
code := gojs.MakePluginCode(&plg)
|
||||||
|
errStr := "no code"
|
||||||
|
if code != "" {
|
||||||
|
err := u.WriteFile(path.Join("plugins", plg.Id+".ts"), code)
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println(u.Cyan(plg.Id), "-", plg.Name, u.BGreen("OK"), ">>", u.Magenta(path.Join("plugins", plg.Id+".ts")))
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
errStr = err.Error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(u.Cyan(plg.Id), "-", plg.Name, u.BGreen(errStr))
|
||||||
|
}
|
||||||
|
}
|
47
templates/_plugin.go
Normal file
47
templates/_plugin.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package {{.name}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
"apigo.cloud/git/apigo/plugin"
|
||||||
|
"errors"
|
||||||
|
"github.com/ssgo/log"
|
||||||
|
"github.com/ssgo/u"
|
||||||
|
)
|
||||||
|
|
||||||
|
var prefix = ""
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
plugin.Register(plugin.Plugin{
|
||||||
|
Id: "{{.name}}",
|
||||||
|
Name: "",
|
||||||
|
// set plugin contents
|
||||||
|
Objects: map[string]interface{}{
|
||||||
|
// *plugin.Context is optional if need to use, ignore it when invoke
|
||||||
|
"set": func(key string, value interface{}, ctx *plugin.Context) {
|
||||||
|
ctx.SetData(prefix+key, value)
|
||||||
|
},
|
||||||
|
// return error is optional if need to throw exception, ignore it when invoke
|
||||||
|
"get": func(key string, ctx *plugin.Context) (interface{}, error) {
|
||||||
|
value := ctx.GetData(prefix + key)
|
||||||
|
if value == nil {
|
||||||
|
return nil, errors.New("data " + key + " is null")
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
},
|
||||||
|
// you can get inject object from *plugin.Context, *log.Logger is default logger with a unique trance id
|
||||||
|
"remove": func(key string, ctx *plugin.Context) {
|
||||||
|
if logger, ok := ctx.GetInject("*log.Logger").(*log.Logger); ok {
|
||||||
|
logger.Warning("context data cannot be remove, will set to null")
|
||||||
|
}
|
||||||
|
ctx.SetData(prefix+key, nil)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// set config sample (recommend to use YAML format)
|
||||||
|
ConfigSample: `prefix: _`,
|
||||||
|
// init plugin config
|
||||||
|
Init: func(config map[string]interface{}) {
|
||||||
|
if config[prefix] != nil {
|
||||||
|
prefix = u.String(config[prefix])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
27
templates/_plugin_test.go
Normal file
27
templates/_plugin_test.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package {{.name}}_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"apigo.cloud/git/apigo/gojs"
|
||||||
|
_ "current-plugin"
|
||||||
|
"fmt"
|
||||||
|
"github.com/ssgo/u"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPlugin(t *testing.T) {
|
||||||
|
if files, err := os.ReadDir("."); err == nil {
|
||||||
|
for _, f := range files {
|
||||||
|
if !f.IsDir() && strings.HasSuffix(f.Name(), "_test.js") {
|
||||||
|
testName := f.Name()[0 : len(f.Name())-8]
|
||||||
|
r, err, _ := gojs.RunFile(f.Name(), nil)
|
||||||
|
if err != nil || r != true {
|
||||||
|
t.Fatal("test "+testName+" failed", r, err)
|
||||||
|
} else {
|
||||||
|
fmt.Println(u.Green("test "+testName), u.BGreen("OK"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
templates/_plugin_test.js
Normal file
18
templates/_plugin_test.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// run "ag export plugins" to make plugins code
|
||||||
|
import logger from 'plugins/logger';
|
||||||
|
import {{.name}} from 'plugins/{{.name}}';
|
||||||
|
|
||||||
|
{{.name}}.set('aaa', 111)
|
||||||
|
let aaa = {{.name}}.get('aaa')
|
||||||
|
if (aaa !== 111) return 'set value error'
|
||||||
|
|
||||||
|
try {
|
||||||
|
{{.name}}.get('bbb')
|
||||||
|
return 'no exception when getting non-existent key'
|
||||||
|
} catch (ex){
|
||||||
|
logger.error(ex.message, {stack:ex.stack})
|
||||||
|
}
|
||||||
|
logger.info('aaa')
|
||||||
|
{{.name}}.remove('bbb')
|
||||||
|
|
||||||
|
return true
|
Loading…
Reference in New Issue
Block a user