diff --git a/go.mod b/go.mod index 3466659..d2d8e91 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,6 @@ module apigo.cloud/git/apigo/ag go 1.18 -require github.com/ssgo/u v1.7.2 +require github.com/ssgo/u v1.7.3 -require ( - apigo.cloud/git/apigo/plugin v1.0.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) +require gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/main.go b/main.go index 42b7e16..c389ae5 100644 --- a/main.go +++ b/main.go @@ -56,8 +56,10 @@ var commands = []Command{ //{"new api", "+a", "[path] [method]", "create a new api for server project, will use restful api if specified http method", newServerAPI}, //{"new game", "+g", "[name]", "create a new game project, will create in the current directory if no name is specified", newServerProject}, //{"new webkit", "+w", "[name]", "create a new webkit project, will create in the current directory if no name is specified", newServerProject}, - {"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}, + //{"download", "dl", "[plugin name]", "will fetch plugin into project", downloadPlugin}, + {"run", "r", "", "will exec `go run .`", runProject}, + {"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}, //{"git login", "/lg", "", "login to apigo.cloud/git", }, //{"git new", "/+", "name", "create new public repository from apigo.cloud/git", }, @@ -74,7 +76,9 @@ var commands = []Command{ //{"build linux", "bl", "", "build", }, //{"build linuxarm", "bla", "", "build", }, //{"build all", "ba", "", "build", }, - //{"deploy", "d", "", "deploy", }, + //{"publish", "p", "", "publish project to target server", }, + // TODO 从 apigo.cloud/git 中读取信息增加命令,例如:server + // TODO 从 plugins 中读取信息增加命令,例如:dao } func findTool() (gowatchPath string, logvPath string) { @@ -170,21 +174,32 @@ func newServerAPI(args []string) { } func runProject(args []string) { - gowatchPath, logvPath := findTool() _ = runCommand("go", "mod", "tidy") - _ = runCommandPipe(logvPath, gowatchPath, "-pt", ".go,.yml,.js", "run", ".") - //_ = runCommandPipe(logvPath, gowatchPath, "-pt", ".go,.yml,.js", "-ig", "api", "run", ".") + _, logvPath := findTool() + _ = runCommandPipe(logvPath, "go", "run", ".") } func testProject(args []string) { - gowatchPath, logvPath := findTool() + cmdArgs := make([]string, 0) if u.FileExists("tests") { - _ = os.Chdir("tests") - _ = runCommand("go", "mod", "tidy") - _ = runCommandPipe(logvPath, gowatchPath, "-p", ".,..", "-pt", ".go,.yml,.js", "test", "-v", ".") + if u.FileExists(filepath.Join("tests", "go.mod")) { + _ = os.Chdir("tests") + cmdArgs = append(cmdArgs, "test", "-v", ".") + } else { + cmdArgs = append(cmdArgs, "test", "-v", "tests") + } } else { - _ = runCommandPipe(logvPath, gowatchPath, "-pt", ".go,.yml,.js", "test", "-v", ".") + cmdArgs = append(cmdArgs, "test", "-v", ".") } + _ = runCommand("go", "mod", "tidy") + _, logvPath := findTool() + _ = runCommandPipe(logvPath, "go", cmdArgs...) +} + +func devProject(args []string) { + gowatchPath, logvPath := findTool() + _ = runCommand("go", "mod", "tidy") + _ = runCommandPipe(logvPath, gowatchPath, "-p", ".,./main.js", "run", ".") } var pkgMatcher = regexp.MustCompile(`(?m)^\s*_\s+"([\w-_/.]+)"`) @@ -194,11 +209,11 @@ func makePluginCodeImports(from string, imports *[]string) { for _, f := range files { if f.IsDir() { if !strings.HasPrefix(f.Name(), ".") { - makePluginCodeImports(path.Join(from, f.Name()), imports) + 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(path.Join(from, f.Name())); err == nil { + 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]) @@ -224,13 +239,16 @@ 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._\-/]+)$`) func makePluginCode(args []string) { // 判断是否可执行项目(不创建指向项目本身的 import _) isMainProject := false + isEmptyProject := true if files, err := os.ReadDir("."); err == nil { for _, f := range files { if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") { + isEmptyProject = false code, _ := u.ReadFile(f.Name()) if strings.Contains(code, "package main") || strings.Contains(code, "func main(") { isMainProject = true @@ -244,14 +262,17 @@ func makePluginCode(args []string) { imports := make([]string, 0) makePluginCodeImports(".", &imports) + findGoModCode, _ := u.ReadFile("go.mod") goModCode := "module main\ngo 1.18\n" + currentModuleName := "current-project" if !isMainProject { - imports = append(imports, "current-project") - goModCode += "require current-project v0.0.0 // indirect\nreplace current-project v0.0.0 => ../\n" + if m := modNameMatcher.FindStringSubmatch(findGoModCode); m != nil { + currentModuleName = m[1] + } + goModCode += "require " + currentModuleName + " v0.0.0 // indirect\nreplace " + currentModuleName + " v0.0.0 => ../\n" } // 扫描 replace,处理路径后加入到 _makePluginCode/go.mod - findGoModCode, _ := u.ReadFile("go.mod") for _, m := range replaceMatcher.FindAllStringSubmatch(findGoModCode, 100) { replacePath := m[3] if absPath, err := filepath.Abs(m[3]); err == nil { @@ -260,19 +281,26 @@ func makePluginCode(args []string) { goModCode += fmt.Sprintln("replace", m[1], m[2], "=>", replacePath) } + if !isMainProject && !isEmptyProject { + imports = append(imports, currentModuleName) + } + _ = u.WriteFile("_makePluginCode/go.mod", goModCode) writeFile("_makePluginCode/main.go", makePluginCodeTPL, map[string]any{"imports": imports}) _ = os.Chdir("_makePluginCode") + defer func() { + _ = os.Chdir("..") + _ = os.RemoveAll("_makePluginCode") + }() _ = runCommand("go", "mod", "tidy") if err := runCommand("go", "run", "."); err != nil { fmt.Println(u.Red(err.Error())) } - _ = os.Chdir("..") - _ = os.RemoveAll("_makePluginCode") } func runCommand(name string, args ...string) error { cmd := exec.Command(name, args...) + cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() @@ -283,7 +311,13 @@ func runCommandPipe(pipeCommandName, commandName string, args ...string) error { cmd2 := exec.Command(pipeCommandName) r, w := io.Pipe() - defer w.Close() + wClosed := false + defer func() { + if !wClosed { + w.Close() + } + }() + cmd1.Stdin = os.Stdin cmd1.Stdout = w cmd1.Stderr = w cmd2.Stdin = r @@ -298,6 +332,8 @@ func runCommandPipe(pipeCommandName, commandName string, args ...string) error { if err := cmd1.Wait(); err != nil { return err } + w.Close() + wClosed = true // 等待第二个命令完成 if err := cmd2.Wait(); err != nil { return err diff --git a/templates/_gitignore b/templates/_gitignore index 8fece96..6a3de7c 100644 --- a/templates/_gitignore +++ b/templates/_gitignore @@ -1,3 +1,4 @@ .* !.gitignore -/go.sum +go.sum +/build diff --git a/templates/_gitignore_server b/templates/_gitignore_server index b4b8c24..996a1a1 100644 --- a/templates/_gitignore_server +++ b/templates/_gitignore_server @@ -1,7 +1,8 @@ .* !.gitignore -/go.sum +go.sum +env.yml +env.json /www /server -/env.yml -/env.json +/build diff --git a/templates/_main.go b/templates/_main.go index ccd8e4f..de7e6af 100644 --- a/templates/_main.go +++ b/templates/_main.go @@ -2,19 +2,8 @@ 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 - }, - }, - }) + gojs.RunFile("main.js", nil) } diff --git a/templates/_main.js b/templates/_main.js index 7abbd7e..314d2fb 100644 --- a/templates/_main.js +++ b/templates/_main.js @@ -1,9 +1,4 @@ -import console from '_/console' -import logger from '_/logger' -import file from '_/apigo.cloud/git/apigo/plguins/file' -// console.info(file.read('test.txt')) +import console from 'console' -setWorldName('gojs') -logger.info('Hello '+getWorldName()) - -// return 'OK' +let name = console.input("please enter your name: ") +console.log("hello "+name) diff --git a/templates/_main_test.go b/templates/_main_test.go index 24f58d9..94cadcc 100644 --- a/templates/_main_test.go +++ b/templates/_main_test.go @@ -7,7 +7,7 @@ import ( ) func TestPlusNumber(t *testing.T) { - r, err, _ := gojs.Run("return 1+2", nil) + r, err := gojs.Run("return 1+2", nil) if err != nil || u.Int(r) != 3 { t.Fatal("TestPlusNumber failed", r, err) } diff --git a/templates/_makePluginCode.go b/templates/_makePluginCode.go index b7a2495..13d848e 100644 --- a/templates/_makePluginCode.go +++ b/templates/_makePluginCode.go @@ -5,7 +5,6 @@ import ( "apigo.cloud/git/apigo/plugin" "fmt" "github.com/ssgo/u" - "path" "strings" {{- range.imports}} _ "{{.}}" @@ -29,12 +28,13 @@ const loggerModuleCode = `export default { func writeModule(id, name, code string, modules *[]string, imports *[]string) { idParts := strings.Split(id, "/") - filename := path.Join("node_modules", path.Join(idParts...)+u.StringIf(len(idParts) == 1, "/index.ts", ".ts")) + filename := filepath.Join("node_modules", filepath.Join(idParts...)+u.StringIf(len(idParts) == 1, "/index.ts", ".ts")) if err := u.WriteFile("../"+filename, code); err != nil { fmt.Println(u.Cyan(id), "-", name, u.BRed(err.Error())) } else { 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, fmt.Sprint("\"", idParts[0], "\": \"v0.0.0\"")) + (*modules) = u.AppendUniqueString(*modules, idParts[0]) (*imports) = u.AppendUniqueString(*imports, fmt.Sprint("import ", idParts[len(idParts)-1], " from '"+id+"'")) } } @@ -49,7 +49,27 @@ func main() { writeModule(plg.Id, plg.Name, code, &modules, &imports) } } - _ = u.WriteFile("../package.json", "{\n \"devDependencies\": {\n "+strings.Join(modules, ",\n ")+"\n }\n}") + packageJsonFile := filepath.Join("..", "package.json") + oldPackageJson, _ := u.ReadFile(packageJsonFile) + insertModulesPostfix := "" + if oldPackageJson == "" { + oldPackageJson = "{\n \"devDependencies\": {\n\n }\n}" + } else if !strings.Contains(oldPackageJson, "\"devDependencies\": {") { + oldPackageJson = strings.Replace(oldPackageJson, "{", "{\n \"devDependencies\": {\n\n },", 1) + } else { + insertModulesPostfix = "," + } + insertModules := make([]string, 0) + for _, mod := range modules { + if !strings.Contains(oldPackageJson, "\""+mod+"\":") { + insertModules = u.AppendUniqueString(insertModules, fmt.Sprint("\"", mod, "\": \"v0.0.0\"")) + } + } + if len(insertModules) > 0 { + newPackageJson := strings.Replace(oldPackageJson, "\"devDependencies\": {", "\"devDependencies\": {\n "+strings.Join(insertModules, ",\n ")+insertModulesPostfix, 1) + //_ = u.WriteFile("../package.json", "{\n \"devDependencies\": {\n "+strings.Join(modules, ",\n ")+"\n }\n}") + _ = u.WriteFile("../package.json", newPackageJson) + } fmt.Println() fmt.Println("Usage:") fmt.Println(" " + u.Magenta(strings.Join(imports, "\n "))) diff --git a/templates/_plugin_test.go b/templates/_plugin_test.go index 226eb62..ad5e857 100644 --- a/templates/_plugin_test.go +++ b/templates/_plugin_test.go @@ -15,7 +15,7 @@ func TestPlugin(t *testing.T) { 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) + r, err := gojs.RunFile(f.Name(), nil) if err != nil || r != true { t.Fatal("test "+testName+" failed", r, err) } else {