From b9254c1e6ff30851bcee80d8d7c3f00d7b42c56d Mon Sep 17 00:00:00 2001 From: Star <> Date: Mon, 27 May 2024 16:57:37 +0800 Subject: [PATCH] some updates --- go.mod | 2 +- main.go | 189 ++++++++++++++++++++++++++--------- templates/_makePluginCode.go | 39 ++++---- 3 files changed, 157 insertions(+), 73 deletions(-) diff --git a/go.mod b/go.mod index d2d8e91..07f7faa 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,6 @@ module apigo.cloud/git/apigo/ag go 1.18 -require github.com/ssgo/u v1.7.3 +require github.com/ssgo/u v1.7.5 require gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/main.go b/main.go index c389ae5..4de2df7 100644 --- a/main.go +++ b/main.go @@ -58,9 +58,11 @@ var commands = []Command{ //{"new webkit", "+w", "[name]", "create a new webkit project, will create in the current directory if no name is specified", newServerProject}, //{"download", "dl", "[plugin name]", "will fetch plugin into project", downloadPlugin}, {"run", "r", "", "will exec `go run .`", runProject}, + {"watch run", "rr", "[...]", "run project use gowatch, if project files changed will restart auto, ... args see gowatch help https://github.com/ssgo/tool", devProject}, {"test", "t", "", "will exec `go test -v .`, will exec into tests if exists tests dir", testProject}, - {"dev", "d", "[...more gowatch args]", "run project use gowatch, if project files changed will restart auto, gowatch args help see: https://github.com/ssgo/tool", devProject}, - {"export plugins", "ep", "", "export typescript code for used plugins into \"plugins/\"", makePluginCode}, + {"watch test", "tt", "[...]", "test project use gowatch, if project files changed will restart auto, ... args see gowatch help https://github.com/ssgo/tool", devTestProject}, + //{"export plugins", "ep", "", "export typescript code for used plugins into \"plugins/\"", makePluginCode}, + {"tidy", "td", "", "tidy project, find imported plugins from .js files add import code to jsImports.go, export typescript code for used plugins into \"plugins/\"", tidy}, //{"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", }, @@ -81,26 +83,26 @@ var commands = []Command{ // TODO 从 plugins 中读取信息增加命令,例如:dao } -func findTool() (gowatchPath string, logvPath string) { - gowatchPath = "gowatch" - logvPath = "logv" +func findTool() (goWatchPath string, logVPath string) { + goWatchPath = "gowatch" + logVPath = "logv" if binPath, err := exec.LookPath("gowatch"); err == nil && binPath != "" { - gowatchPath = binPath + goWatchPath = binPath } if binPath, err := exec.LookPath("logv"); err == nil && binPath != "" { - logvPath = binPath + logVPath = binPath } - return gowatchPath, logvPath + return goWatchPath, logVPath } func checkSSGOTool() { - gowatchPath, logvPath := findTool() - if gowatchPath == "gowatch" || logvPath == "logv" { + goWatchPath, logVPath := findTool() + if goWatchPath == "gowatch" || logVPath == "logv" { _ = runCommand("go", "get", "-u", "github.com/ssgo/tool") - if gowatchPath == "gowatch" { + if goWatchPath == "gowatch" { _ = runCommand("go", "install", "github.com/ssgo/tool/gowatch") } - if logvPath == "logv" { + if logVPath == "logv" { _ = runCommand("go", "install", "github.com/ssgo/tool/logv") } } @@ -173,50 +175,81 @@ func newServerProject(args []string) { func newServerAPI(args []string) { } -func runProject(args []string) { +func _runProject(args []string, isWatch bool) { _ = runCommand("go", "mod", "tidy") - _, logvPath := findTool() - _ = runCommandPipe(logvPath, "go", "run", ".") + goBinPath, logVPath := findTool() + if isWatch { + args = append(args, "-pt", ".go,.js,.yml", "run", ".") + } else { + goBinPath = "go" + args = append(args, "run", ".") + } + _ = runCommandPipe(logVPath, goBinPath, args...) } -func testProject(args []string) { - cmdArgs := make([]string, 0) - if u.FileExists("tests") { - if u.FileExists(filepath.Join("tests", "go.mod")) { - _ = os.Chdir("tests") - cmdArgs = append(cmdArgs, "test", "-v", ".") - } else { - cmdArgs = append(cmdArgs, "test", "-v", "tests") - } - } else { - cmdArgs = append(cmdArgs, "test", "-v", ".") - } - _ = runCommand("go", "mod", "tidy") - _, logvPath := findTool() - _ = runCommandPipe(logvPath, "go", cmdArgs...) +func runProject(args []string) { + _runProject(args, false) } func devProject(args []string) { - gowatchPath, logvPath := findTool() - _ = runCommand("go", "mod", "tidy") - _ = runCommandPipe(logvPath, gowatchPath, "-p", ".,./main.js", "run", ".") + _runProject(args, true) } -var pkgMatcher = regexp.MustCompile(`(?m)^\s*_\s+"([\w-_/.]+)"`) +func testProject(args []string) { + _testProject(args, false) +} -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(filepath.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(filepath.Join(from, f.Name())); err == nil { - for _, m := range pkgMatcher.FindAllStringSubmatch(code, 1024) { - if m[1] != "current-plugin" { - *imports = u.AppendUniqueString(*imports, m[1]) +func devTestProject(args []string) { + _testProject(args, true) +} + +func _testProject(args []string, isWatch bool) { + if u.FileExists("tests") { + if u.FileExists(filepath.Join("tests", "go.mod")) { + _ = os.Chdir("tests") + if isWatch { + args = append(args, "-p", "..") + } + args = append(args, "test", "-v", ".") + } else { + args = append(args, "test", "-v", "tests") + } + } else { + args = append(args, "test", "-v", ".") + } + _ = runCommand("go", "mod", "tidy") + goWatchPath, logVPath := findTool() + if isWatch { + args2 := append([]string{"-pt", ".go,.js,.yml"}, args...) + _ = runCommandPipe(logVPath, goWatchPath, args2...) + } else { + _ = runCommandPipe(logVPath, "go", args...) + } +} + +var pkgMatcher = regexp.MustCompile(`(?im)^\s*(import)?\s*_\s+"([\w-_/.]+)"`) +var importMatcher = regexp.MustCompile(`(?im)^\s*import\s+([\w{}, ]+)\s+from\s+['"]([\w./\\\- ]+)['"]`) + +func makeJsImports(path string, jsImports *[]string, pkgName string) { + if u.FileExists(filepath.Join(path, "go.mod")) { + if m := modNameMatcher.FindStringSubmatch(u.ReadFileN(filepath.Join(path, "go.mod"))); m != nil { + if pkgName != m[1] { + return + } + } + } + for _, f := range u.ReadDirN(path) { + filename := f.Name + fullName := filepath.Join(path, filename) + if !strings.HasPrefix(filename, ".") && !strings.HasPrefix(filename, "_") && filename != "_makePluginCode" && filename != "node_modules" && filename != "www" && filename != "src" { + if f.IsDir { + makeJsImports(fullName, jsImports, pkgName) + } else if strings.HasSuffix(filename, ".js") { + if code, err := u.ReadFile(fullName); err == nil { + for _, m := range importMatcher.FindAllStringSubmatch(code, 1024) { + if !strings.HasPrefix(m[2], ".") && !strings.HasPrefix(m[2], "_") && m[2] != "current-plugin" && m[2] != "console" && m[2] != "logger" { + if !u.FileExists(filepath.Join(path, m[2])) { + *jsImports = u.AppendUniqueString(*jsImports, m[2]) } } } @@ -226,6 +259,56 @@ func makePluginCodeImports(from string, imports *[]string) { } } +func makePluginCodeImports(from string, imports *[]string, parentModuleName string) { + jsImports := make([]string, 0) + currentParentModuleName := parentModuleName + if u.FileExists(filepath.Join(from, "go.mod")) { + pkgName := "" + if m := modNameMatcher.FindStringSubmatch(u.ReadFileN(filepath.Join(from, "go.mod"))); m != nil { + pkgName = m[1] + } + makeJsImports(from, &jsImports, pkgName) + parentModuleName = pkgName + } + + currentPkgName := "" + for _, f := range u.ReadDirN(from) { + if f.IsDir { + if !strings.HasPrefix(f.Name, ".") { + makePluginCodeImports(filepath.Join(from, f.Name), imports, parentModuleName) + } + } else { + if strings.HasSuffix(f.Name, ".go") && !strings.HasPrefix(f.Name, ".") && f.Name != "makePluginCode.go" { + if code, err := u.ReadFile(filepath.Join(from, f.Name)); err == nil { + if m := pkgNameMatcher.FindStringSubmatch(code); m != nil { + currentPkgName = m[1] + } + for _, m := range pkgMatcher.FindAllStringSubmatch(code, 1024) { + if m[2] != "current-plugin" && !strings.HasPrefix(f.Name, "jsImports") { + *imports = u.AppendUniqueString(*imports, m[2]) + } + } + } + } + } + } + + if currentPkgName != "" && u.FileExists(filepath.Join(from, "go.mod")) { + pkgList := make([]string, 0) + for _, plgPkg := range jsImports { + if plgPkg != currentParentModuleName && !u.StringIn(*imports, plgPkg) { + pkgList = append(pkgList, plgPkg) + *imports = u.AppendUniqueString(*imports, plgPkg) + } + } + if len(pkgList) > 0 { + _ = u.WriteFile(filepath.Join(from, u.StringIf(strings.HasSuffix(currentPkgName, "_test"), "jsImports_test.go", "jsImports.go")), `package `+currentPkgName+` +import _ "`+strings.Join(pkgList, "\"\nimport _ \"")+`" +`) + } + } +} + 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) @@ -240,8 +323,9 @@ func writeFile(filename string, fileContent string, data any) { var replaceMatcher = regexp.MustCompile(`([a-zA-Z0-9._\-/]+)\s+(v[0-9.]+)\s+=>\s+([a-zA-Z0-9._\-/\\]+)`) var modNameMatcher = regexp.MustCompile(`(?m)^module\s+([a-zA-Z0-9._\-/]+)$`) +var pkgNameMatcher = regexp.MustCompile(`(?m)^package\s+([a-zA-Z0-9._\-/]+)$`) -func makePluginCode(args []string) { +func tidy(args []string) { // 判断是否可执行项目(不创建指向项目本身的 import _) isMainProject := false isEmptyProject := true @@ -260,7 +344,7 @@ func makePluginCode(args []string) { // 扫描用到的插件(import _) imports := make([]string, 0) - makePluginCodeImports(".", &imports) + makePluginCodeImports(".", &imports, "") findGoModCode, _ := u.ReadFile("go.mod") goModCode := "module main\ngo 1.18\n" @@ -367,7 +451,12 @@ func main() { 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) + padStr := "" + padN := 30 - len(cmdInfo.Name) - len(cmdInfo.ShortName) - len(cmdInfo.Args) + if padN > 0 { + padStr = strings.Repeat(" ", padN) + } + fmt.Println(" ", u.Cyan(cmdInfo.Name), u.Dim("[")+u.Magenta(cmdInfo.ShortName)+u.Dim("]"), cmdInfo.Args, padStr, cmdInfo.Comment) } fmt.Println() fmt.Println("Examples:") diff --git a/templates/_makePluginCode.go b/templates/_makePluginCode.go index 13d848e..a39bbba 100644 --- a/templates/_makePluginCode.go +++ b/templates/_makePluginCode.go @@ -5,33 +5,30 @@ import ( "apigo.cloud/git/apigo/plugin" "fmt" "github.com/ssgo/u" + "path/filepath" "strings" {{- range.imports}} _ "{{.}}" {{- end}} ) -const consoleModuleCode = `export default { - "log": function (...args: any): void {return}, - "info": function (...args: any): void {return}, - "warn": function (...args: any): void {return}, - "error": function (...args: any): void {return}, - "input": function (): string {return}, -}` - -const loggerModuleCode = `export default { - "debug": function (message: string, ext?: Object): void {return}, - "info": function (message: string, ext?: Object): void {return}, - "warn": function (message: string, ext?: Object): void {return}, - "error": function (message: string, ext?: Object): void {return}, -}` - -func writeModule(id, name, code string, modules *[]string, imports *[]string) { +func writeModule(id, name, exportCode, interfaceCode string, modules *[]string, imports *[]string) { idParts := strings.Split(id, "/") - filename := filepath.Join("node_modules", filepath.Join(idParts...)+u.StringIf(len(idParts) == 1, "/index.ts", ".ts")) - if err := u.WriteFile("../"+filename, code); err != nil { + filename := filepath.Join("node_modules", filepath.Join(idParts...)) + interfaceFilename := filename + if len(idParts) == 1 { + filename = filepath.Join(filename, "index.ts") + interfaceFilename = filepath.Join(interfaceFilename+"Type", "index.ts") + }else{ + filename += ".ts" + interfaceFilename += "Type.ts" + } + if err := u.WriteFile(filepath.Join("..", filename), exportCode); err != nil { fmt.Println(u.Cyan(id), "-", name, u.BRed(err.Error())) } else { + if interfaceCode != "" { + _ = u.WriteFile(filepath.Join("..", interfaceFilename), interfaceCode) + } fmt.Println(u.Cyan(id), "-", name, u.BGreen("OK"), u.Dim(">> "+filename)) //(*modules) = u.AppendUniqueString(*modules, fmt.Sprint("\"", idParts[0], "\": \"v0.0.0\"")) (*modules) = u.AppendUniqueString(*modules, idParts[0]) @@ -42,11 +39,9 @@ func writeModule(id, name, code string, modules *[]string, imports *[]string) { func main() { modules := make([]string, 0) imports := make([]string, 0) - writeModule("console", "终端工具", consoleModuleCode, &modules, &imports) - writeModule("logger", "日志工具", loggerModuleCode, &modules, &imports) for _, plg := range plugin.List() { - if code := gojs.MakePluginCode(&plg); code != "" { - writeModule(plg.Id, plg.Name, code, &modules, &imports) + if exportCode, interfaceCode := gojs.MakePluginCode(&plg); exportCode != "" { + writeModule(plg.Id, plg.Name, exportCode, interfaceCode, &modules, &imports) } } packageJsonFile := filepath.Join("..", "package.json")