Skip to content

Commit

Permalink
Merge branch 'master' into Improve/gconv-dostruct
Browse files Browse the repository at this point in the history
  • Loading branch information
wln32 authored Apr 19, 2024
2 parents cc7245d + a39e6a2 commit 6c16b72
Show file tree
Hide file tree
Showing 32 changed files with 732 additions and 60 deletions.
225 changes: 225 additions & 0 deletions cmd/gf/internal/cmd/cmd_z_unit_gen_ctrl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,228 @@ func Test_Gen_Ctrl_Default(t *testing.T) {
}
})
}

// https://github.com/gogf/gf/issues/3460
func Test_Gen_Ctrl_UseMerge_Issue3460(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
ctrlPath = gfile.Temp(guid.S())
//ctrlPath = gtest.DataPath("issue", "3460", "controller")
apiFolder = gtest.DataPath("issue", "3460", "api")
in = genctrl.CGenCtrlInput{
SrcFolder: apiFolder,
DstFolder: ctrlPath,
WatchFile: "",
SdkPath: "",
SdkStdVersion: false,
SdkNoV1: false,
Clear: false,
Merge: true,
}
)

err := gfile.Mkdir(ctrlPath)
t.AssertNil(err)
defer gfile.Remove(ctrlPath)

_, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
t.AssertNil(err)

files, err := gfile.ScanDir(ctrlPath, "*.go", true)
t.AssertNil(err)
t.Assert(files, []string{
filepath.Join(ctrlPath, "/hello/hello.go"),
filepath.Join(ctrlPath, "/hello/hello_new.go"),
filepath.Join(ctrlPath, "/hello/hello_v1_req.go"),
filepath.Join(ctrlPath, "/hello/hello_v2_req.go"),
})

expectCtrlPath := gtest.DataPath("issue", "3460", "controller")
expectFiles := []string{
filepath.Join(expectCtrlPath, "/hello/hello.go"),
filepath.Join(expectCtrlPath, "/hello/hello_new.go"),
filepath.Join(expectCtrlPath, "/hello/hello_v1_req.go"),
filepath.Join(expectCtrlPath, "/hello/hello_v2_req.go"),
}

// Line Feed maybe \r\n or \n
for i, expectFile := range expectFiles {
val := gfile.GetContents(files[i])
expect := gfile.GetContents(expectFile)
t.Assert(val, expect)
}
})
}

// gf gen ctrl -m
// In the same module, different API files are added
func Test_Gen_Ctrl_UseMerge_AddNewFile(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
ctrlPath = gfile.Temp(guid.S())
//ctrlPath = gtest.DataPath("issue", "3460", "controller")
apiFolder = gtest.DataPath("genctrl-merge", "add_new_file", "api")
in = genctrl.CGenCtrlInput{
SrcFolder: apiFolder,
DstFolder: ctrlPath,
Merge: true,
}
)
const testNewApiFile = `
package v1
import "github.com/gogf/gf/v2/frame/g"
type DictTypeAddReq struct {
g.Meta
}
type DictTypeAddRes struct {
}
`

err := gfile.Mkdir(ctrlPath)
t.AssertNil(err)
defer gfile.Remove(ctrlPath)

_, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
t.AssertNil(err)

var (
genApi = filepath.Join(apiFolder, "/dict/dict.go")
genApiExpect = filepath.Join(apiFolder, "/dict/dict_expect.go")
)
defer gfile.Remove(genApi)
t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))

genCtrlFiles, err := gfile.ScanDir(ctrlPath, "*.go", true)
t.AssertNil(err)
t.Assert(genCtrlFiles, []string{
filepath.Join(ctrlPath, "/dict/dict.go"),
filepath.Join(ctrlPath, "/dict/dict_new.go"),
filepath.Join(ctrlPath, "/dict/dict_v1_dict_type.go"),
})

expectCtrlPath := gtest.DataPath("genctrl-merge", "add_new_file", "controller")
expectFiles := []string{
filepath.Join(expectCtrlPath, "/dict/dict.go"),
filepath.Join(expectCtrlPath, "/dict/dict_new.go"),
filepath.Join(expectCtrlPath, "/dict/dict_v1_dict_type.go"),
}

// Line Feed maybe \r\n or \n
expectFilesContent(t, genCtrlFiles, expectFiles)

// Add a new API file
newApiFilePath := filepath.Join(apiFolder, "/dict/v1/test_new.go")
err = gfile.PutContents(newApiFilePath, testNewApiFile)
t.AssertNil(err)
defer gfile.Remove(newApiFilePath)

// Then execute the command
_, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
t.AssertNil(err)

genApi = filepath.Join(apiFolder, "/dict.go")
genApiExpect = filepath.Join(apiFolder, "/dict_add_new_ctrl_expect.gotest")

t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))

genCtrlFiles = append(genCtrlFiles, filepath.Join(ctrlPath, "/dict/dict_v1_test_new.go"))
// Use the gotest suffix, otherwise the IDE will delete the import
expectFiles = append(expectFiles, filepath.Join(expectCtrlPath, "/dict/dict_v1_test_new.gotest"))
// Line Feed maybe \r\n or \n
expectFilesContent(t, genCtrlFiles, expectFiles)

})

}

// gf gen ctrl -m
// In the same module, Add the same file to the API
func Test_Gen_Ctrl_UseMerge_AddNewCtrl(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
ctrlPath = gfile.Temp(guid.S())
//ctrlPath = gtest.DataPath("issue", "3460", "controller")
apiFolder = gtest.DataPath("genctrl-merge", "add_new_ctrl", "api")
in = genctrl.CGenCtrlInput{
SrcFolder: apiFolder,
DstFolder: ctrlPath,
Merge: true,
}
)

err := gfile.Mkdir(ctrlPath)
t.AssertNil(err)
defer gfile.Remove(ctrlPath)

_, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
t.AssertNil(err)

var (
genApi = filepath.Join(apiFolder, "/dict/dict.go")
genApiExpect = filepath.Join(apiFolder, "/dict/dict_expect.go")
)
defer gfile.Remove(genApi)
t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))

genCtrlFiles, err := gfile.ScanDir(ctrlPath, "*.go", true)
t.AssertNil(err)
t.Assert(genCtrlFiles, []string{
filepath.Join(ctrlPath, "/dict/dict.go"),
filepath.Join(ctrlPath, "/dict/dict_new.go"),
filepath.Join(ctrlPath, "/dict/dict_v1_dict_type.go"),
})

expectCtrlPath := gtest.DataPath("genctrl-merge", "add_new_ctrl", "controller")
expectFiles := []string{
filepath.Join(expectCtrlPath, "/dict/dict.go"),
filepath.Join(expectCtrlPath, "/dict/dict_new.go"),
filepath.Join(expectCtrlPath, "/dict/dict_v1_dict_type.go"),
}

// Line Feed maybe \r\n or \n
expectFilesContent(t, genCtrlFiles, expectFiles)

const testNewApiFile = `
type DictTypeAddReq struct {
g.Meta
}
type DictTypeAddRes struct {
}
`
dictModuleFileName := filepath.Join(apiFolder, "/dict/v1/dict_type.go")
// Save the contents of the file before the changes
apiFileContents := gfile.GetContents(dictModuleFileName)

// Add a new API file
err = gfile.PutContentsAppend(dictModuleFileName, testNewApiFile)
t.AssertNil(err)

//==================================
// Then execute the command
_, err = genctrl.CGenCtrl{}.Ctrl(ctx, in)
t.AssertNil(err)

genApi = filepath.Join(apiFolder, "/dict.go")
genApiExpect = filepath.Join(apiFolder, "/dict_add_new_ctrl_expect.gotest")
t.Assert(gfile.GetContents(genApi), gfile.GetContents(genApiExpect))

// Use the gotest suffix, otherwise the IDE will delete the import
expectFiles[2] = filepath.Join(expectCtrlPath, "/dict/dict_v1_test_new.gotest")
// Line Feed maybe \r\n or \n
expectFilesContent(t, genCtrlFiles, expectFiles)

// Restore the contents of the original API file
err = gfile.PutContents(dictModuleFileName, apiFileContents)
t.AssertNil(err)
})

}

func expectFilesContent(t *gtest.T, paths []string, expectPaths []string) {
for i, expectFile := range expectPaths {
val := gfile.GetContents(paths[i])
expect := gfile.GetContents(expectFile)
t.Assert(val, expect)
}
}
81 changes: 72 additions & 9 deletions cmd/gf/internal/cmd/genctrl/genctrl_generate_ctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package genctrl
import (
"fmt"
"path/filepath"
"strings"

"github.com/gogf/gf/cmd/gf/v2/internal/consts"
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
Expand Down Expand Up @@ -42,8 +43,16 @@ func (c *controllerGenerator) Generate(dstModuleFolderPath string, apiModuleApiI
); err != nil {
return
}

// use -merge
if merge {
err = c.doGenerateCtrlMergeItem(dstModuleFolderPath, subItems, doneApiItemSet)
continue
}

for _, subItem := range subItems {
if err = c.doGenerateCtrlItem(dstModuleFolderPath, subItem, merge); err != nil {
err = c.doGenerateCtrlItem(dstModuleFolderPath, subItem)
if err != nil {
return
}
doneApiItemSet.Add(subItem.String())
Expand Down Expand Up @@ -116,7 +125,7 @@ func (c *controllerGenerator) doGenerateCtrlNewByModuleAndVersion(
return
}

func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, item apiItem, merge bool) (err error) {
func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, item apiItem) (err error) {
var (
methodNameSnake = gstr.CaseSnake(item.MethodName)
ctrlName = fmt.Sprintf(`Controller%s`, gstr.UcFirst(item.Version))
Expand All @@ -126,13 +135,6 @@ func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, ite
)
var content string

if merge {
methodFilePath = gfile.Join(dstModuleFolderPath, fmt.Sprintf(
`%s_%s_%s.go`, item.Module, item.Version, item.FileName,
))

}

if gfile.Exists(methodFilePath) {
content = gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFuncMerge, g.MapStrStr{
"{Module}": item.Module,
Expand Down Expand Up @@ -162,3 +164,64 @@ func (c *controllerGenerator) doGenerateCtrlItem(dstModuleFolderPath string, ite
mlog.Printf(`generated: %s`, methodFilePath)
return
}

// use -merge
func (c *controllerGenerator) doGenerateCtrlMergeItem(dstModuleFolderPath string, apiItems []apiItem, doneApiSet *gset.StrSet) (err error) {

type controllerFileItem struct {
module string
version string
importPath string
// Each ctrlFileItem has multiple CTRLs
controllers strings.Builder
}
// It is possible that there are multiple files under one module
ctrlFileItemMap := make(map[string]*controllerFileItem)

for _, api := range apiItems {
ctrlFileItem, found := ctrlFileItemMap[api.FileName]
if !found {
ctrlFileItem = &controllerFileItem{
module: api.Module,
version: api.Version,
controllers: strings.Builder{},
importPath: api.Import,
}
ctrlFileItemMap[api.FileName] = ctrlFileItem
}

ctrl := gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlControllerMethodFuncMerge, g.MapStrStr{
"{Module}": api.Module,
"{CtrlName}": fmt.Sprintf(`Controller%s`, gstr.UcFirst(api.Version)),
"{Version}": api.Version,
"{MethodName}": api.MethodName,
}))
ctrlFileItem.controllers.WriteString(ctrl)
doneApiSet.Add(api.String())
}

for ctrlFileName, ctrlFileItem := range ctrlFileItemMap {
ctrlFilePath := gfile.Join(dstModuleFolderPath, fmt.Sprintf(
`%s_%s_%s.go`, ctrlFileItem.module, ctrlFileItem.version, ctrlFileName,
))

// This logic is only followed when a new ctrlFileItem is generated
// Most of the rest of the time, the following logic is followed
if !gfile.Exists(ctrlFilePath) {
ctrlFileHeader := gstr.TrimLeft(gstr.ReplaceByMap(consts.TemplateGenCtrlControllerHeader, g.MapStrStr{
"{Module}": ctrlFileItem.module,
"{ImportPath}": ctrlFileItem.importPath,
}))
err = gfile.PutContents(ctrlFilePath, ctrlFileHeader)
if err != nil {
return err
}
}

if err = gfile.PutContentsAppend(ctrlFilePath, ctrlFileItem.controllers.String()); err != nil {
return err
}
mlog.Printf(`generated: %s`, ctrlFilePath)
}
return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================

package dict

import (
"context"

"github.com/gogf/gf/cmd/gf/v2/internal/cmd/testdata/genctrl-merge/add_new_ctrl/api/dict/v1"
)

type IDictV1 interface {
DictTypeAddPage(ctx context.Context, req *v1.DictTypeAddPageReq) (res *v1.DictTypeAddPageRes, err error)
DictTypeAdd(ctx context.Context, req *v1.DictTypeAddReq) (res *v1.DictTypeAddRes, err error)
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 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 DictTypeAddPageReq struct {
g.Meta `path:"/dict/type/add" tags:"字典管理" method:"get" summary:"字典类型添加页面"`
}

type DictTypeAddPageRes struct {
g.Meta `mime:"text/html" type:"string" example:"<html/>"`
}
Loading

0 comments on commit 6c16b72

Please sign in to comment.