This commit is contained in:
孟帅
2023-11-25 18:36:11 +08:00
parent 40117c700d
commit 70e9f966c3
142 changed files with 5407 additions and 2058 deletions

View File

@@ -55,6 +55,7 @@ func (c cGF) Index(ctx context.Context, in cGFInput) (out *cGFOutput, err error)
_, err = Version.Index(ctx, cVersionInput{})
return
}
answer := "n"
// No argument or option, do installation checks.
if data, isInstalled := service.Install.IsInstalled(); !isInstalled {
@@ -71,6 +72,7 @@ func (c cGF) Index(ctx context.Context, in cGFInput) (out *cGFOutput, err error)
gcmd.Scan("press `Enter` to exit...")
return
}
// Print help content.
gcmd.CommandFromCtx(ctx).Print()
return

View File

@@ -159,7 +159,7 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
if gfile.Exists("main.go") {
file = "main.go"
} else {
mlog.Fatal("build file path cannot be empty")
mlog.Fatal("build file path is empty or main.go not found in current working directory")
}
}
if in.Name == "" {
@@ -254,17 +254,23 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
continue
}
if len(customSystems) == 0 && len(customArches) == 0 {
// Single binary building, output the binary to current working folder.
// For example:
// `gf build`
// `gf build -o main.exe`
if runtime.GOOS == "windows" {
ext = ".exe"
}
// Single binary building, output the binary to current working folder.
output := ""
var outputPath string
if len(in.Output) > 0 {
output = "-o " + in.Output + ext
outputPath = "-o " + in.Output
} else {
output = "-o " + in.Name + ext
outputPath = "-o " + in.Name + ext
}
cmd = fmt.Sprintf(`go build %s -ldflags "%s" %s %s`, output, ldFlags, in.Extra, file)
cmd = fmt.Sprintf(
`go build %s -ldflags "%s" %s %s`,
outputPath, ldFlags, in.Extra, file,
)
} else {
// Cross-building, output the compiled binary to specified path.
if system == "windows" {
@@ -272,11 +278,22 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
}
genv.MustSet("GOOS", system)
genv.MustSet("GOARCH", arch)
var outputPath string
if len(in.Output) > 0 {
outputPath = "-o " + in.Output
} else {
outputPath = fmt.Sprintf(
"-o %s/%s/%s%s",
in.Path, system+"_"+arch, in.Name, ext,
)
}
cmd = fmt.Sprintf(
`go build -o %s/%s/%s%s -ldflags "%s" %s%s`,
in.Path, system+"_"+arch, in.Name, ext, ldFlags, in.Extra, file,
`go build %s -ldflags "%s" %s%s`,
outputPath, ldFlags, in.Extra, file,
)
}
mlog.Debug(fmt.Sprintf("build for GOOS=%s GOARCH=%s", system, arch))
mlog.Debug(cmd)
// It's not necessary printing the complete command string.
cmdShow, _ := gregex.ReplaceString(`\s+(-ldflags ".+?")\s+`, " ", cmd)

View File

@@ -7,14 +7,19 @@
package cmd
import (
"bytes"
"context"
"fmt"
"runtime"
"strings"
"time"
"github.com/gogf/gf/v2"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gbuild"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
@@ -25,6 +30,10 @@ var (
Version = cVersion{}
)
const (
defaultIndent = "{{indent}}"
)
type cVersion struct {
g.Meta `name:"version" brief:"show version information of current binary"`
}
@@ -36,34 +45,90 @@ type cVersionInput struct {
type cVersionOutput struct{}
func (c cVersion) Index(ctx context.Context, in cVersionInput) (*cVersionOutput, error) {
info := gbuild.Info()
if info.Git == "" {
info.Git = "none"
}
mlog.Printf(`GoFrame CLI Tool %s, https://goframe.org`, gf.VERSION)
gfVersion, err := c.getGFVersionOfCurrentProject()
if err != nil {
gfVersion = err.Error()
detailBuffer := &detailBuffer{}
detailBuffer.WriteString(fmt.Sprintf("%s", gf.VERSION))
detailBuffer.appendLine(0, "Welcome to GoFrame!")
detailBuffer.appendLine(0, "Env Detail:")
goVersion, ok := getGoVersion()
if ok {
detailBuffer.appendLine(1, fmt.Sprintf("Go Version: %s", goVersion))
detailBuffer.appendLine(1, fmt.Sprintf("GF Version(go.mod): %s", getGoFrameVersion(2)))
} else {
gfVersion = gfVersion + " in current go.mod"
}
mlog.Printf(`GoFrame Version: %s`, gfVersion)
mlog.Printf(`CLI Installed At: %s`, gfile.SelfPath())
if info.GoFrame == "" {
mlog.Print(`Current is a custom installed version, no installation information.`)
return nil, nil
v, err := c.getGFVersionOfCurrentProject()
if err == nil {
detailBuffer.appendLine(1, fmt.Sprintf("GF Version(go.mod): %s", v))
} else {
detailBuffer.appendLine(1, fmt.Sprintf("GF Version(go.mod): %s", err.Error()))
}
}
mlog.Print(gstr.Trim(fmt.Sprintf(`
CLI Built Detail:
Go Version: %s
GF Version: %s
Git Commit: %s
Build Time: %s
`, info.Golang, info.GoFrame, info.Git, info.Time)))
detailBuffer.appendLine(0, "CLI Detail:")
detailBuffer.appendLine(1, fmt.Sprintf("Installed At: %s", gfile.SelfPath()))
info := gbuild.Info()
if info.GoFrame == "" {
detailBuffer.appendLine(1, fmt.Sprintf("Built Go Version: %s", runtime.Version()))
detailBuffer.appendLine(1, fmt.Sprintf("Built GF Version: %s", gf.VERSION))
} else {
if info.Git == "" {
info.Git = "none"
}
detailBuffer.appendLine(1, fmt.Sprintf("Built Go Version: %s", info.Golang))
detailBuffer.appendLine(1, fmt.Sprintf("Built GF Version: %s", info.GoFrame))
detailBuffer.appendLine(1, fmt.Sprintf("Git Commit: %s", info.Git))
detailBuffer.appendLine(1, fmt.Sprintf("Built Time: %s", info.Time))
}
detailBuffer.appendLine(0, "Others Detail:")
detailBuffer.appendLine(1, "Docs: https://goframe.org")
detailBuffer.appendLine(1, fmt.Sprintf("Now : %s", time.Now().Format(time.RFC3339)))
mlog.Print(detailBuffer.replaceAllIndent(" "))
return nil, nil
}
// detailBuffer is a buffer for detail information.
type detailBuffer struct {
bytes.Buffer
}
// appendLine appends a line to the buffer with given indent level.
func (d *detailBuffer) appendLine(indentLevel int, line string) {
d.WriteString(fmt.Sprintf("\n%s%s", strings.Repeat(defaultIndent, indentLevel), line))
}
// replaceAllIndent replaces the tab with given indent string and prints the buffer content.
func (d *detailBuffer) replaceAllIndent(indentStr string) string {
return strings.ReplaceAll(d.String(), defaultIndent, indentStr)
}
// getGoFrameVersion returns the goframe version of current project using.
func getGoFrameVersion(indentLevel int) (gfVersion string) {
pkgInfo, err := gproc.ShellExec(context.Background(), `go list -f "{{if (not .Main)}}{{.Path}}@{{.Version}}{{end}}" -m all`)
if err != nil {
return "cannot find go.mod"
}
pkgList := gstr.Split(pkgInfo, "\n")
for _, v := range pkgList {
if strings.HasPrefix(v, "github.com/gogf/gf") {
gfVersion += fmt.Sprintf("\n%s%s", strings.Repeat(defaultIndent, indentLevel), v)
}
}
return
}
// getGoVersion returns the go version
func getGoVersion() (goVersion string, ok bool) {
goVersion, err := gproc.ShellExec(context.Background(), "go version")
if err != nil {
return "", false
}
goVersion = gstr.TrimLeftStr(goVersion, "go version ")
goVersion = gstr.TrimRightStr(goVersion, "\n")
return goVersion, true
}
// getGFVersionOfCurrentProject checks and returns the GoFrame version current project using.
func (c cVersion) getGFVersionOfCurrentProject() (string, error) {
goModPath := gfile.Join(gfile.Pwd(), "go.mod")

View File

@@ -0,0 +1,11 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import "context"
var ctx = context.Background()

View File

@@ -0,0 +1,85 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/guid"
"github.com/gogf/gf/v2/util/gutil"
"hotgo/internal/library/hggen/internal/cmd/genctrl"
"path/filepath"
"testing"
)
func Test_Gen_Ctrl_Default(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
path = gfile.Temp(guid.S())
apiFolder = gtest.DataPath("genctrl", "api")
in = genctrl.CGenCtrlInput{
SrcFolder: apiFolder,
DstFolder: path,
WatchFile: "",
SdkPath: "",
SdkStdVersion: false,
SdkNoV1: false,
Clear: false,
Merge: false,
}
)
err := gutil.FillStructWithDefault(&in)
t.AssertNil(err)
err = gfile.Mkdir(path)
t.AssertNil(err)
defer gfile.Remove(path)
_, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
if err != nil {
panic(err)
}
// apiInterface file
var (
genApi = apiFolder + filepath.FromSlash("/article/article.go")
genApiExpect = apiFolder + filepath.FromSlash("/article/article_expect.go")
)
defer gfile.Remove(genApi)
t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))
// files
files, err := gfile.ScanDir(path, "*.go", true)
t.AssertNil(err)
t.Assert(files, []string{
path + filepath.FromSlash("/article/article.go"),
path + filepath.FromSlash("/article/article_new.go"),
path + filepath.FromSlash("/article/article_v1_create.go"),
path + filepath.FromSlash("/article/article_v1_get_list.go"),
path + filepath.FromSlash("/article/article_v1_get_one.go"),
path + filepath.FromSlash("/article/article_v1_update.go"),
path + filepath.FromSlash("/article/article_v2_create.go"),
path + filepath.FromSlash("/article/article_v2_update.go"),
})
// content
testPath := gtest.DataPath("genctrl", "controller")
expectFiles := []string{
testPath + filepath.FromSlash("/article/article.go"),
testPath + filepath.FromSlash("/article/article_new.go"),
testPath + filepath.FromSlash("/article/article_v1_create.go"),
testPath + filepath.FromSlash("/article/article_v1_get_list.go"),
testPath + filepath.FromSlash("/article/article_v1_get_one.go"),
testPath + filepath.FromSlash("/article/article_v1_update.go"),
testPath + filepath.FromSlash("/article/article_v2_create.go"),
testPath + filepath.FromSlash("/article/article_v2_update.go"),
}
for i := range files {
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
}
})
}

View File

@@ -7,8 +7,8 @@
package cmd
import (
"context"
"fmt"
"path/filepath"
"testing"
"github.com/gogf/gf/v2/database/gdb"
@@ -20,8 +20,6 @@ import (
"hotgo/internal/library/hggen/internal/cmd/gendao"
)
var ctx = context.Background()
func dropTableWithDb(db gdb.DB, table string) {
dropTableStmt := fmt.Sprintf("DROP TABLE IF EXISTS `%s`", table)
if _, err := db.Exec(ctx, dropTableStmt); err != nil {
@@ -105,18 +103,18 @@ func Test_Gen_Dao_Default(t *testing.T) {
files, err := gfile.ScanDir(path, "*.go", true)
t.AssertNil(err)
t.Assert(files, []string{
path + "/dao/internal/table_user.go",
path + "/dao/table_user.go",
path + "/model/do/table_user.go",
path + "/model/entity/table_user.go",
filepath.FromSlash(path + "/dao/internal/table_user.go"),
filepath.FromSlash(path + "/dao/table_user.go"),
filepath.FromSlash(path + "/model/do/table_user.go"),
filepath.FromSlash(path + "/model/entity/table_user.go"),
})
// content
testPath := gtest.DataPath("gendao", "generated_user")
expectFiles := []string{
testPath + "/dao/internal/table_user.go",
testPath + "/dao/table_user.go",
testPath + "/model/do/table_user.go",
testPath + "/model/entity/table_user.go",
filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
filepath.FromSlash(testPath + "/dao/table_user.go"),
filepath.FromSlash(testPath + "/model/do/table_user.go"),
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
}
for i, _ := range files {
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
@@ -209,18 +207,18 @@ func Test_Gen_Dao_TypeMapping(t *testing.T) {
files, err := gfile.ScanDir(path, "*.go", true)
t.AssertNil(err)
t.Assert(files, []string{
path + "/dao/internal/table_user.go",
path + "/dao/table_user.go",
path + "/model/do/table_user.go",
path + "/model/entity/table_user.go",
filepath.FromSlash(path + "/dao/internal/table_user.go"),
filepath.FromSlash(path + "/dao/table_user.go"),
filepath.FromSlash(path + "/model/do/table_user.go"),
filepath.FromSlash(path + "/model/entity/table_user.go"),
})
// content
testPath := gtest.DataPath("gendao", "generated_user_type_mapping")
expectFiles := []string{
testPath + "/dao/internal/table_user.go",
testPath + "/dao/table_user.go",
testPath + "/model/do/table_user.go",
testPath + "/model/entity/table_user.go",
filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
filepath.FromSlash(testPath + "/dao/table_user.go"),
filepath.FromSlash(testPath + "/model/do/table_user.go"),
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
}
for i, _ := range files {
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))

View File

@@ -0,0 +1,72 @@
// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package cmd
import (
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/guid"
"github.com/gogf/gf/v2/util/gutil"
"hotgo/internal/library/hggen/internal/cmd/genservice"
"path/filepath"
"testing"
)
func Test_Gen_Service_Default(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
path = gfile.Temp(guid.S())
dstFolder = path + filepath.FromSlash("/service")
apiFolder = gtest.DataPath("genservice", "logic")
in = genservice.CGenServiceInput{
SrcFolder: apiFolder,
DstFolder: dstFolder,
DstFileNameCase: "Snake",
WatchFile: "",
StPattern: "",
Packages: nil,
ImportPrefix: "",
Clear: false,
}
)
err := gutil.FillStructWithDefault(&in)
t.AssertNil(err)
err = gfile.Mkdir(path)
t.AssertNil(err)
defer gfile.Remove(path)
_, err = genservice.CGenService{}.Service(ctx, in)
if err != nil {
panic(err)
}
// logic file
var (
genApi = apiFolder + filepath.FromSlash("/logic.go")
genApiExpect = apiFolder + filepath.FromSlash("/logic_expect.go")
)
defer gfile.Remove(genApi)
t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))
// files
files, err := gfile.ScanDir(dstFolder, "*.go", true)
t.AssertNil(err)
t.Assert(files, []string{
dstFolder + filepath.FromSlash("/article.go"),
})
// contents
testPath := gtest.DataPath("genservice", "service")
expectFiles := []string{
testPath + filepath.FromSlash("/article.go"),
}
for i := range files {
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
}
})
}

View File

@@ -38,7 +38,7 @@ gf gen ctrl
)
const (
PatternApiDefinition = `type\s+(\w+)Req\s+struct\s+{([\s\S]+?)}`
PatternApiDefinition = `type[\s\(]+(\w+)Req\s+struct\s+{([\s\S]+?)}`
PatternCtrlDefinition = `func\s+\(.+?\)\s+\w+\(.+?\*(\w+)\.(\w+)Req\)\s+\(.+?\*(\w+)\.(\w+)Res,\s+\w+\s+error\)\s+{`
)

View File

@@ -8,6 +8,7 @@ package genctrl
import (
"fmt"
"path/filepath"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/frame/g"
@@ -64,8 +65,8 @@ func (c *controllerGenerator) doGenerateCtrlNewByModuleAndVersion(
dstModuleFolderPath, module, version, importPath string,
) (err error) {
var (
moduleFilePath = gfile.Join(dstModuleFolderPath, module+".go")
moduleFilePathNew = gfile.Join(dstModuleFolderPath, module+"_new.go")
moduleFilePath = filepath.FromSlash(gfile.Join(dstModuleFolderPath, module+".go"))
moduleFilePathNew = filepath.FromSlash(gfile.Join(dstModuleFolderPath, module+"_new.go"))
ctrlName = fmt.Sprintf(`Controller%s`, gstr.UcFirst(version))
interfaceName = fmt.Sprintf(`%s.I%s%s`, module, gstr.CaseCamel(module), gstr.UcFirst(version))
newFuncName = fmt.Sprintf(`New%s`, gstr.UcFirst(version))
@@ -107,7 +108,7 @@ func (c *controllerGenerator) doGenerateCtrlNewByModuleAndVersion(
"{NewFuncName}": newFuncName,
"{InterfaceName}": interfaceName,
})
err = gfile.PutContentsAppend(moduleFilePathNew, gstr.TrimLeft(content))
err = gfile.PutContentsAppend(moduleFilePathNew, content)
if err != nil {
return err
}
@@ -119,9 +120,9 @@ func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, ite
var (
methodNameSnake = gstr.CaseSnake(item.MethodName)
ctrlName = fmt.Sprintf(`Controller%s`, gstr.UcFirst(item.Version))
methodFilePath = gfile.Join(dstModuleFolderPath, fmt.Sprintf(
methodFilePath = filepath.FromSlash(gfile.Join(dstModuleFolderPath, fmt.Sprintf(
`%s_%s_%s.go`, item.Module, item.Version, methodNameSnake,
))
)))
)
var content string

View File

@@ -8,6 +8,7 @@ package genctrl
import (
"fmt"
"path/filepath"
"github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/container/gset"
@@ -39,18 +40,17 @@ func (c *apiInterfaceGenerator) Generate(apiModuleFolderPath string, apiModuleAp
func (c *apiInterfaceGenerator) doGenerate(apiModuleFolderPath string, module string, items []apiItem) (err error) {
var (
moduleFilePath = gfile.Join(apiModuleFolderPath, fmt.Sprintf(`%s.go`, module))
moduleFilePath = filepath.FromSlash(gfile.Join(apiModuleFolderPath, fmt.Sprintf(`%s.go`, module)))
importPathMap = gmap.NewListMap()
importPaths []string
)
// if there's already exist file that with the same but not auto generated go file,
// it uses another file name.
if !utils.IsFileDoNotEdit(moduleFilePath) {
moduleFilePath = gfile.Join(apiModuleFolderPath, fmt.Sprintf(`%s.if.go`, module))
moduleFilePath = filepath.FromSlash(gfile.Join(apiModuleFolderPath, fmt.Sprintf(`%s.if.go`, module)))
}
// all import paths.
importPathMap.Set("\t"+`"context"`, 1)
importPathMap.Set("\t"+``, 1)
importPathMap.Set("\t"+`"context"`+"\n", 1)
for _, item := range items {
importPathMap.Set(fmt.Sprintf("\t"+`"%s"`, item.Import), 1)
}
@@ -91,7 +91,7 @@ func (c *apiInterfaceGenerator) doGenerate(apiModuleFolderPath string, module st
interfaceDefinition += "\n\n"
}
interfaceContent = gstr.TrimLeft(gstr.ReplaceByMap(interfaceContent, g.MapStrStr{
"{Interfaces}": interfaceDefinition,
"{Interfaces}": gstr.TrimRightStr(interfaceDefinition, "\n", 2),
}))
err = gfile.PutContents(moduleFilePath, interfaceContent)
mlog.Printf(`generated: %s`, moduleFilePath)

View File

@@ -8,6 +8,7 @@ package genctrl
import (
"fmt"
"path/filepath"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/frame/g"
@@ -54,7 +55,7 @@ func (c *apiSdkGenerator) Generate(apiModuleApiItems []apiItem, sdkFolderPath st
func (c *apiSdkGenerator) doGenerateSdkPkgFile(sdkFolderPath string) (err error) {
var (
pkgName = gfile.Basename(sdkFolderPath)
pkgFilePath = gfile.Join(sdkFolderPath, fmt.Sprintf(`%s.go`, pkgName))
pkgFilePath = filepath.FromSlash(gfile.Join(sdkFolderPath, fmt.Sprintf(`%s.go`, pkgName)))
fileContent string
)
if gfile.Exists(pkgFilePath) {
@@ -79,7 +80,7 @@ func (c *apiSdkGenerator) doGenerateSdkIClient(
funcName = gstr.CaseCamel(module) + gstr.UcFirst(version)
interfaceName = fmt.Sprintf(`I%s`, funcName)
moduleImportPath = gstr.Replace(fmt.Sprintf(`"%s"`, gfile.Dir(versionImportPath)), "\\", "/", -1)
iClientFilePath = gfile.Join(sdkFolderPath, fmt.Sprintf(`%s.iclient.go`, pkgName))
iClientFilePath = filepath.FromSlash(gfile.Join(sdkFolderPath, fmt.Sprintf(`%s.iclient.go`, pkgName)))
interfaceFuncDefinition = fmt.Sprintf(
`%s() %s.%s`,
gstr.CaseCamel(module)+gstr.UcFirst(version), module, interfaceName,
@@ -145,9 +146,9 @@ func (c *apiSdkGenerator) doGenerateSdkImplementer(
moduleImportPath = gstr.Replace(gfile.Dir(versionImportPath), "\\", "/", -1)
versionPrefix = ""
implementerName = moduleNameCamel + gstr.UcFirst(version)
implementerFilePath = gfile.Join(sdkFolderPath, fmt.Sprintf(
implementerFilePath = filepath.FromSlash(gfile.Join(sdkFolderPath, fmt.Sprintf(
`%s_%s_%s.go`, pkgName, moduleNameSnake, version,
))
)))
)
if sdkNoV1 && version == "v1" {
implementerName = moduleNameCamel

View File

@@ -9,9 +9,10 @@ package gendao
import (
"context"
"fmt"
"golang.org/x/mod/modfile"
"strings"
"golang.org/x/mod/modfile"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"

View File

@@ -10,6 +10,7 @@ import (
"bytes"
"context"
"fmt"
"path/filepath"
"strings"
"github.com/olekukonko/tablewriter"
@@ -106,7 +107,7 @@ type generateDaoIndexInput struct {
}
func generateDaoIndex(in generateDaoIndexInput) {
path := gfile.Join(in.DirPathDao, in.FileName+".go")
path := filepath.FromSlash(gfile.Join(in.DirPathDao, in.FileName+".go"))
if in.OverwriteDao || !gfile.Exists(path) {
indexContent := gstr.ReplaceByMap(
getTemplateFromPathOrDefault(in.TplDaoIndexPath, consts.TemplateGenDaoIndexContent),
@@ -136,7 +137,7 @@ type generateDaoInternalInput struct {
}
func generateDaoInternal(in generateDaoInternalInput) {
path := gfile.Join(in.DirPathDaoInternal, in.FileName+".go")
path := filepath.FromSlash(gfile.Join(in.DirPathDaoInternal, in.FileName+".go"))
modelContent := gstr.ReplaceByMap(
getTemplateFromPathOrDefault(in.TplDaoInternalPath, consts.TemplateGenDaoInternalContent),
g.MapStrStr{

View File

@@ -9,6 +9,7 @@ package gendao
import (
"context"
"fmt"
"path/filepath"
"strings"
"github.com/gogf/gf/v2/frame/g"
@@ -22,7 +23,7 @@ import (
)
func generateDo(ctx context.Context, in CGenDaoInternalInput) {
var dirPathDo = gfile.Join(in.Path, in.DoPath)
var dirPathDo = filepath.FromSlash(gfile.Join(in.Path, in.DoPath))
if in.Clear {
doClear(ctx, dirPathDo, false)
}

View File

@@ -8,6 +8,7 @@ package gendao
import (
"context"
"path/filepath"
"strings"
"github.com/gogf/gf/v2/frame/g"
@@ -33,7 +34,7 @@ func generateEntity(ctx context.Context, in CGenDaoInternalInput) {
var (
newTableName = in.NewTableNames[i]
entityFilePath = gfile.Join(dirPathEntity, gstr.CaseSnake(newTableName)+".go")
entityFilePath = filepath.FromSlash(gfile.Join(dirPathEntity, gstr.CaseSnake(newTableName)+".go"))
structDefinition, appendImports = generateStructDefinition(ctx, generateStructDefinitionInput{
CGenDaoInternalInput: in,
TableName: tableName,

View File

@@ -10,9 +10,10 @@ import (
"bytes"
"context"
"fmt"
"github.com/olekukonko/tablewriter"
"strings"
"github.com/olekukonko/tablewriter"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gregex"
@@ -70,7 +71,7 @@ func generateStructFieldDefinition(
err error
localTypeName gdb.LocalType
localTypeNameStr string
jsonTag = getJsonTagFromCase(field.Name, in.JsonCase)
jsonTag = gstr.CaseConvert(field.Name, gstr.CaseTypeMatch(in.JsonCase))
)
if in.TypeMapping != nil && len(in.TypeMapping) > 0 {
@@ -158,30 +159,3 @@ func formatComment(comment string) string {
comment = gstr.Trim(comment)
return comment
}
// getJsonTagFromCase call gstr.Case* function to convert the s to specified case.
func getJsonTagFromCase(str, caseStr string) string {
switch gstr.ToLower(caseStr) {
case gstr.ToLower("Camel"):
return gstr.CaseCamel(str)
case gstr.ToLower("CamelLower"):
return gstr.CaseCamelLower(str)
case gstr.ToLower("Kebab"):
return gstr.CaseKebab(str)
case gstr.ToLower("KebabScreaming"):
return gstr.CaseKebabScreaming(str)
case gstr.ToLower("Snake"):
return gstr.CaseSnake(str)
case gstr.ToLower("SnakeFirstUpper"):
return gstr.CaseSnakeFirstUpper(str)
case gstr.ToLower("SnakeScreaming"):
return gstr.CaseSnakeScreaming(str)
}
return str
}

View File

@@ -19,9 +19,10 @@ import (
const pkgLoadMode = 0xffffff
type EnumsParser struct {
enums []EnumItem
parsedPkg map[string]struct{}
prefixes []string
enums []EnumItem
parsedPkg map[string]struct{}
prefixes []string
standardPackages map[string]struct{}
}
type EnumItem struct {
@@ -31,23 +32,12 @@ type EnumItem struct {
Type string // Pkg.ID + TypeName
}
var standardPackages = make(map[string]struct{})
//func init() {
// stdPackages, err := packages.Load(nil, "std")
// if err != nil {
// panic(err)
// }
// for _, p := range stdPackages {
// standardPackages[p.ID] = struct{}{}
// }
//}
func NewEnumsParser(prefixes []string) *EnumsParser {
return &EnumsParser{
enums: make([]EnumItem, 0),
parsedPkg: make(map[string]struct{}),
prefixes: prefixes,
enums: make([]EnumItem, 0),
parsedPkg: make(map[string]struct{}),
prefixes: prefixes,
standardPackages: getStandardPackages(),
}
}
@@ -59,7 +49,7 @@ func (p *EnumsParser) ParsePackages(pkgs []*packages.Package) {
func (p *EnumsParser) ParsePackage(pkg *packages.Package) {
// Ignore std packages.
if _, ok := standardPackages[pkg.ID]; ok {
if _, ok := p.standardPackages[pkg.ID]; ok {
return
}
// Ignore pared packages.
@@ -144,3 +134,15 @@ func (p *EnumsParser) Export() string {
}
return gjson.MustEncodeString(typeEnumMap)
}
func getStandardPackages() map[string]struct{} {
standardPackages := make(map[string]struct{})
stdPackages, err := packages.Load(nil, "std")
if err != nil {
panic(err)
}
for _, p := range stdPackages {
standardPackages[p.ID] = struct{}{}
}
return standardPackages
}

View File

@@ -10,6 +10,7 @@ import (
"bytes"
"context"
"fmt"
"path/filepath"
"strings"
"github.com/olekukonko/tablewriter"
@@ -197,7 +198,7 @@ func doGenPbEntityForArray(ctx context.Context, index int, in CGenPbEntityInput)
if len(match) == 3 {
gdb.AddConfigNode(tempGroup, gdb.ConfigNode{
Type: gstr.Trim(match[1]),
Link: gstr.Trim(match[2]),
Link: in.Link,
})
db, _ = gdb.Instance(tempGroup)
}
@@ -246,7 +247,7 @@ func generatePbEntityContentFile(ctx context.Context, in CGenPbEntityInternalInp
tableNameSnakeCase = gstr.CaseSnake(newTableName)
entityMessageDefine = generateEntityMessageDefinition(tableNameCamelCase, fieldMap, in)
fileName = gstr.Trim(tableNameSnakeCase, "-_.")
path = gfile.Join(in.Path, fileName+".proto")
path = filepath.FromSlash(gfile.Join(in.Path, fileName+".proto"))
)
if gstr.Contains(entityMessageDefine, "google.protobuf.Timestamp") {
imports = `import "google/protobuf/timestamp.proto";`

View File

@@ -9,6 +9,7 @@ package genservice
import (
"context"
"fmt"
"path/filepath"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/container/gmap"
@@ -93,10 +94,10 @@ const (
)
func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGenServiceOutput, err error) {
in.SrcFolder = gstr.TrimRight(in.SrcFolder, `\/`)
in.SrcFolder = gstr.Replace(in.SrcFolder, "\\", "/")
in.WatchFile = gstr.TrimRight(in.WatchFile, `\/`)
in.WatchFile = gstr.Replace(in.WatchFile, "\\", "/")
in.SrcFolder = filepath.ToSlash(in.SrcFolder)
in.SrcFolder = gstr.TrimRight(in.SrcFolder, `/`)
in.WatchFile = filepath.ToSlash(in.WatchFile)
in.WatchFile = gstr.TrimRight(in.WatchFile, `/`)
// Watch file handling.
if in.WatchFile != "" {

View File

@@ -194,28 +194,9 @@ func (c CGenService) generateInitializationFile(in CGenServiceInput, importSrcPa
}
// getDstFileNameCase call gstr.Case* function to convert the s to specified case.
func (c CGenService) getDstFileNameCase(str, caseStr string) string {
switch gstr.ToLower(caseStr) {
case gstr.ToLower("Lower"):
return gstr.ToLower(str)
case gstr.ToLower("Camel"):
return gstr.CaseCamel(str)
case gstr.ToLower("CamelLower"):
return gstr.CaseCamelLower(str)
case gstr.ToLower("Kebab"):
return gstr.CaseKebab(str)
case gstr.ToLower("KebabScreaming"):
return gstr.CaseKebabScreaming(str)
case gstr.ToLower("SnakeFirstUpper"):
return gstr.CaseSnakeFirstUpper(str)
case gstr.ToLower("SnakeScreaming"):
return gstr.CaseSnakeScreaming(str)
func (c CGenService) getDstFileNameCase(str, caseStr string) (newStr string) {
if newStr := gstr.CaseConvert(str, gstr.CaseTypeMatch(caseStr)); newStr != str {
return newStr
}
return gstr.CaseSnake(str)
}

View File

@@ -0,0 +1,24 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package article
import (
"context"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v1"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v2"
)
type IArticleV1 interface {
Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error)
Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error)
GetList(ctx context.Context, req *v1.GetListReq) (res *v1.GetListRes, err error)
GetOne(ctx context.Context, req *v1.GetOneReq) (res *v1.GetOneRes, err error)
}
type IArticleV2 interface {
Create(ctx context.Context, req *v2.CreateReq) (res *v2.CreateRes, err error)
Update(ctx context.Context, req *v2.UpdateReq) (res *v2.UpdateRes, err error)
}

View File

@@ -0,0 +1,27 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package v1
import "github.com/gogf/gf/v2/frame/g"
type (
CreateReq struct {
g.Meta `path:"/article/create" method:"post" tags:"ArticleService"`
Title string `v:"required"`
}
CreateRes struct{}
)
type (
UpdateReq struct {
g.Meta `path:"/article/update" method:"post" tags:"ArticleService"`
Title string `v:"required"`
}
UpdateRes struct{}
)

View File

@@ -0,0 +1,25 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package v1
import "github.com/gogf/gf/v2/frame/g"
type GetListReq struct {
g.Meta `path:"/article/list" method:"get" tags:"ArticleService"`
}
type GetListRes struct {
list []struct{}
}
type GetOneReq struct {
g.Meta `path:"/article/one" method:"get" tags:"ArticleService"`
}
type GetOneRes struct {
one struct{}
}

View File

@@ -0,0 +1,23 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package v2
import "github.com/gogf/gf/v2/frame/g"
type CreateReq struct {
g.Meta `path:"/article/create" method:"post" tags:"ArticleService"`
Title string `v:"required"`
}
type CreateRes struct{}
type UpdateReq struct {
g.Meta `path:"/article/update" method:"post" tags:"ArticleService"`
Title string `v:"required"`
}
type UpdateRes struct{}

View File

@@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package article

View File

@@ -0,0 +1,21 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package article
import (
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article"
)
type ControllerV1 struct{}
func NewV1() article.IArticleV1 {
return &ControllerV1{}
}
type ControllerV2 struct{}
func NewV2() article.IArticleV2 {
return &ControllerV2{}
}

View File

@@ -0,0 +1,14 @@
package article
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v1"
)
func (c *ControllerV1) Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

View File

@@ -0,0 +1,14 @@
package article
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v1"
)
func (c *ControllerV1) GetList(ctx context.Context, req *v1.GetListReq) (res *v1.GetListRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

View File

@@ -0,0 +1,14 @@
package article
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v1"
)
func (c *ControllerV1) GetOne(ctx context.Context, req *v1.GetOneReq) (res *v1.GetOneRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

View File

@@ -0,0 +1,14 @@
package article
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v1"
)
func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

View File

@@ -0,0 +1,14 @@
package article
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v2"
)
func (c *ControllerV2) Create(ctx context.Context, req *v2.CreateReq) (res *v2.CreateRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

View File

@@ -0,0 +1,14 @@
package article
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"hotgo/internal/library/hggen/internal/cmd/testdata/genctrl/api/article/v2"
)
func (c *ControllerV2) Update(ctx context.Context, req *v2.UpdateReq) (res *v2.UpdateRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

View File

@@ -0,0 +1,33 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package article
import (
"context"
"hotgo/internal/library/hggen/internal/cmd/testdata/genservice/service"
)
type sArticle struct {
}
func init() {
service.RegisterArticle(&sArticle{})
}
// Get article details
func (s *sArticle) Get(ctx context.Context, id uint) (info struct{}, err error) {
return struct{}{}, err
}
// Create
/**
* create an article.
* @author oldme
*/
func (s *sArticle) Create(ctx context.Context, info struct{}) (id uint, err error) {
return id, err
}

View File

@@ -0,0 +1,9 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "hotgo/internal/library/hggen/internal/cmd/testdata/genservice/logic/article"
)

View File

@@ -0,0 +1,38 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
)
type (
IArticle interface {
// Get article details
Get(ctx context.Context, id uint) (info struct{}, err error)
// Create
/**
* create an article.
* @author oldme
*/
Create(ctx context.Context, info struct{}) (id uint, err error)
}
)
var (
localArticle IArticle
)
func Article() IArticle {
if localArticle == nil {
panic("implement not found for interface IArticle, forgot register?")
}
return localArticle
}
func RegisterArticle(i IArticle) {
localArticle = i
}

View File

@@ -12,12 +12,11 @@ const TemplateGenCtrlControllerEmpty = `
// =================================================================================
package {Module}
`
const TemplateGenCtrlControllerNewEmpty = `
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package {Module}
@@ -25,7 +24,6 @@ package {Module}
import (
{ImportPath}
)
`
const TemplateGenCtrlControllerNewFunc = `
@@ -34,7 +32,6 @@ type {CtrlName} struct{}
func {NewFuncName}() {InterfaceName} {
return &{CtrlName}{}
}
`
const TemplateGenCtrlControllerMethodFunc = `
@@ -63,7 +60,7 @@ func (c *{CtrlName}) {MethodName}(ctx context.Context, req *{Version}.{MethodNam
const TemplateGenCtrlApiInterface = `
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package {Module}

View File

@@ -118,7 +118,7 @@ func GetImportPath(filePath string) string {
func GetModPath() string {
var (
oldDir = gfile.Pwd()
newDir = gfile.Dir(oldDir)
newDir = oldDir
goModName = "go.mod"
goModPath string
)
@@ -127,11 +127,11 @@ func GetModPath() string {
if gfile.Exists(goModPath) {
return goModPath
}
oldDir = newDir
newDir = gfile.Dir(oldDir)
if newDir == oldDir {
break
}
oldDir = newDir
}
return ""
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/consts"
"hotgo/internal/model/input/sysin"
"strings"
)
// 默认表单组件映射 Ts -> 表单组件
@@ -119,7 +118,7 @@ func setDefault(field *sysin.GenCodesColumnListModel) {
field.Required = true
}
if strings.Contains(field.Index, consts.GenCodesIndexUNI) {
if IsIndexUNI(field.Index) {
field.Unique = true
}
@@ -136,7 +135,7 @@ func setDefault(field *sysin.GenCodesColumnListModel) {
func setDefaultEdit(field *sysin.GenCodesColumnListModel) {
field.IsEdit = true
if field.Index == consts.GenCodesIndexPK {
if IsIndexPK(field.Index) {
field.IsEdit = false
return
}
@@ -258,7 +257,7 @@ func setDefaultExport(field *sysin.GenCodesColumnListModel) {
func setDefaultQuery(field *sysin.GenCodesColumnListModel) {
field.IsQuery = false
if field.Index == consts.GenCodesIndexPK {
if IsIndexPK(field.Index) {
field.IsQuery = true
return
}

View File

@@ -11,7 +11,6 @@ import (
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/consts"
)
func (l *gCurd) webEditTplData(ctx context.Context, in *CurdPreviewInput) (data g.Map, err error) {
@@ -28,7 +27,7 @@ func (l *gCurd) generateWebEditFormItem(ctx context.Context, in *CurdPreviewInpu
continue
}
if field.Index == consts.GenCodesIndexPK {
if IsIndexPK(field.Index) {
continue
}

View File

@@ -34,7 +34,7 @@ func (l *gCurd) getPkField(in *CurdPreviewInput) *sysin.GenCodesColumnListModel
panic("getPkField masterFields uninitialized.")
}
for _, field := range in.masterFields {
if field.Index == consts.GenCodesIndexPK {
if IsIndexPK(field.Index) {
return field
}
}
@@ -165,3 +165,13 @@ func GetModName(ctx context.Context) (modName string, err error) {
}
return
}
// IsIndexPK 是否是主键
func IsIndexPK(index string) bool {
return gstr.ToUpper(index) == gstr.ToUpper(consts.GenCodesIndexPK)
}
// IsIndexUNI 是否是唯一索引
func IsIndexUNI(index string) bool {
return gstr.ToUpper(index) == gstr.ToUpper(consts.GenCodesIndexUNI)
}