From 8fb4636cb48218687bf46bd527e1511808db9dff Mon Sep 17 00:00:00 2001 From: John Guo Date: Thu, 6 Jul 2023 20:36:33 +0800 Subject: [PATCH] improve command gen service for import alias and comments handling (#2745) --- cmd/gf/internal/cmd/genservice/genservice.go | 74 ++++++++++++++----- .../cmd/genservice/genservice_generate.go | 7 ++ 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/cmd/gf/internal/cmd/genservice/genservice.go b/cmd/gf/internal/cmd/genservice/genservice.go index 554c9fe7e..8211db629 100644 --- a/cmd/gf/internal/cmd/genservice/genservice.go +++ b/cmd/gf/internal/cmd/genservice/genservice.go @@ -173,13 +173,13 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe // Parse single logic package folder. var ( // StructName => FunctionDefinitions - srcPkgInterfaceMap = make(map[string]*garray.StrArray) - srcImportedPackages = garray.NewSortedStrArray().SetUnique(true) - importPackageItemAliasMap = gmap.NewStrStrMap() // for conflict imports check. alias => path - srcPackageName = gfile.Basename(srcFolderPath) - aliasIndex = 0 - ok bool - dstFilePath = gfile.Join(in.DstFolder, + srcPkgInterfaceMap = make(map[string]*garray.StrArray) + srcImportedPackages = garray.NewSortedStrArray().SetUnique(true) + importAliasToPathMap = gmap.NewStrStrMap() // for conflict imports check. alias => import path(with `"`) + importPathToAliasMap = gmap.NewStrStrMap() // for conflict imports check. import path(with `"`) => alias + srcPackageName = gfile.Basename(srcFolderPath) + ok bool + dstFilePath = gfile.Join(in.DstFolder, c.getDstFileNameCase(srcPackageName, in.DstFileNameCase)+".go", ) srcCodeCommentedMap = make(map[string]string) @@ -189,15 +189,16 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe var packageItems []packageItem fileContent = gfile.GetContents(file) // Calculate code comments in source Go files. - err := c.calculateCodeCommented(in, fileContent, srcCodeCommentedMap) + err = c.calculateCodeCommented(in, fileContent, srcCodeCommentedMap) if err != nil { return nil, err } // remove all comments. - fileContent, err = gregex.ReplaceString(`/[/|\*](.+)`, "", fileContent) + fileContent, err = gregex.ReplaceString(`/[/|\*](.*)`, "", fileContent) if err != nil { return nil, err } + // Calculate imported packages of source go files. packageItems, err = c.calculateImportedPackages(fileContent) if err != nil { @@ -205,21 +206,59 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe } // try finding the conflicts imports between files. for _, item := range packageItems { - alias := item.Alias + var alias = item.Alias if alias == "" { alias = gfile.Basename(gstr.Trim(item.Path, `"`)) } - importPath := importPackageItemAliasMap.Get(alias) + + // ignore unused import paths, which do not exist in function definitions. + if !gregex.IsMatchString(fmt.Sprintf(`func .+?([^\w])%s(\.\w+).+?{`, alias), fileContent) { + mlog.Debugf(`ignore unused package: %s`, item.RawImport) + continue + } + + // find the exist alias with the same import path. + var existAlias = importPathToAliasMap.Get(item.Path) + if existAlias != "" { + fileContent, err = gregex.ReplaceStringFuncMatch( + fmt.Sprintf(`([^\w])%s(\.\w+)`, alias), fileContent, + func(match []string) string { + return match[1] + existAlias + match[2] + }, + ) + if err != nil { + return nil, err + } + continue + } + + // resolve alias conflicts. + var importPath = importAliasToPathMap.Get(alias) if importPath == "" { - importPackageItemAliasMap.Set(alias, item.Path) + importAliasToPathMap.Set(alias, item.Path) + importPathToAliasMap.Set(item.Path, alias) srcImportedPackages.Add(item.RawImport) continue } if importPath != item.Path { - // update the conflicted alias with suffix. - item.Alias = fmt.Sprintf(`%s%d`, alias, aliasIndex) - aliasIndex++ - importPackageItemAliasMap.Set(item.Alias, item.Path) + // update the conflicted alias for import path with suffix. + // eg: + // v1 -> v10 + // v11 -> v110 + for aliasIndex := 0; ; aliasIndex++ { + item.Alias = fmt.Sprintf(`%s%d`, alias, aliasIndex) + var existPathForAlias = importAliasToPathMap.Get(item.Alias) + if existPathForAlias != "" { + if existPathForAlias == item.Path { + break + } + continue + } + break + } + importPathToAliasMap.Set(item.Path, item.Alias) + importAliasToPathMap.Set(item.Alias, item.Path) + // reformat the import path with alias. item.RawImport = fmt.Sprintf(`%s %s`, item.Alias, item.Path) // update the file content with new alias import. @@ -232,16 +271,15 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe if err != nil { return nil, err } - srcImportedPackages.Add(item.RawImport) } } + // Calculate functions and interfaces for service generating. err = c.calculateInterfaceFunctions(in, fileContent, srcPkgInterfaceMap) if err != nil { return nil, err } - } initImportSrcPackages = append( diff --git a/cmd/gf/internal/cmd/genservice/genservice_generate.go b/cmd/gf/internal/cmd/genservice/genservice_generate.go index 9c169e5d4..bc80e1a17 100644 --- a/cmd/gf/internal/cmd/genservice/genservice_generate.go +++ b/cmd/gf/internal/cmd/genservice/genservice_generate.go @@ -128,6 +128,7 @@ func (c CGenService) generateServiceFile(in generateServiceFilesInput) (ok bool, // isToGenerateServiceGoFile checks and returns whether the service content dirty. func (c CGenService) isToGenerateServiceGoFile(dstPackageName, filePath string, funcArray *garray.StrArray) bool { var ( + err error fileContent = gfile.GetContents(filePath) generatedFuncArray = garray.NewSortedStrArrayFrom(funcArray.Slice()) contentFuncArray = garray.NewSortedStrArray() @@ -135,6 +136,12 @@ func (c CGenService) isToGenerateServiceGoFile(dstPackageName, filePath string, if fileContent == "" { return true } + // remove all comments. + fileContent, err = gregex.ReplaceString(`/[/|\*](.*)`, "", fileContent) + if err != nil { + panic(err) + return false + } matches, _ := gregex.MatchAllString(`\s+interface\s+{([\s\S]+?)}`, fileContent) for _, match := range matches { contentFuncArray.Append(gstr.SplitAndTrim(match[1], "\n")...)