Skip to content

Commit

Permalink
Merge pull request #2 from elza2/filter-config
Browse files Browse the repository at this point in the history
feat: add filter option feature.
  • Loading branch information
elza2 authored Dec 27, 2022
2 parents 4c6ca8d + 45cb006 commit 05d7cd1
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 22 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
```bash
go install github.com/elza2/go-cyclic@latest
# path 路径要设置为 go.mod 文件所在的路径.
go-cyclic gocyclic --dir .path
# filter 过滤匹配的文件, 多个条件使用逗号隔开(,)
go-cyclic gocyclic --dir .path [--filter *_test.go]
```

运行测试
===============
```bash
git clone https://github.com/elza2/go-cyclic.git
# path 路径要设置为 go.mod 文件所在的路径.
go run ./main.go gocyclic --dir .path
go run ./main.go gocyclic --dir .path [--filter *_test.go]
```

运行结果
Expand Down
34 changes: 32 additions & 2 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,52 @@ package cmd

import (
"log"
"strings"

"github.com/elza2/go-cyclic/errors"
"github.com/elza2/go-cyclic/tool"
"github.com/spf13/cobra"
)

"github.com/elza2/go-cyclic/tool"
const (
GoSuffix = ".go"
)

func RunCyclic(cmd *cobra.Command, args []string) {
dir, err := cmd.Flags().GetString("dir")
if err != nil {
log.Fatalf("get dir params failed: %v\n", err)
}
if err = tool.CheckCycleDepend(dir); err != nil {
filters := make([]string, 0)
filter, err := cmd.Flags().GetString("filter")
if filter != "" {
filters, err = HandleFilters(filter)
if err != nil {
log.Fatal(err.Error())
}
}
if err = tool.CheckCycleDepend(&tool.Params{
Dir: dir,
Filters: filters,
}); err != nil {
log.Fatalf("run failed. %v\n", err)
}
}

func HandleFilters(filter string) (filters []string, err error) {
if strings.Contains(filter, ",") {
return nil, errors.NotSupportCNComma()
}
filters = strings.Split(filter, ",")
for i, f := range filters {
if strings.Contains(f, GoSuffix) {
continue
}
filters[i] += GoSuffix
}
return filters, nil
}

func init() {
cmd := &cobra.Command{
Use: "gocyclic",
Expand Down
3 changes: 2 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ func Execute() {
}

func init() {
rootCmd.PersistentFlags().String("dir", os.Getenv("dir"), "dir. eg: full path of the go.mod file")
rootCmd.PersistentFlags().String("dir", os.Getenv("dir"), "dir. eg: directory address of the go.mod file")
rootCmd.PersistentFlags().String("filter", os.Getenv("filter"), "dir. eg: filters out files of the specified type. separate multiple types with commas (,)")
}
4 changes: 4 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ func GoModNotExist(filepath string) error {
func GoModParseFailed(filepath string) error {
return errors.New(fmt.Sprintf("path: %v/go.mod, go.mod file parse failed.", filepath))
}

func NotSupportCNComma() error {
return errors.New("not supported `,` symbol, please use `,` split")
}
5 changes: 4 additions & 1 deletion example_cyclic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ import (
)

func TestCyclic(t *testing.T) {
tool.CheckCycleDepend("/Users/yuanyou/go/src/daji")
tool.CheckCycleDepend(&tool.Params{
Dir: "../daji",
Filters: []string{},
})
}
17 changes: 15 additions & 2 deletions resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"go/parser"
"go/token"
"os"
"regexp"
"strings"

"golang.org/x/mod/modfile"
Expand Down Expand Up @@ -50,7 +51,7 @@ func ParseGoModule(dir string) (module string, err error) {
return modFile.Module.Mod.Path, nil
}

func ParseNodeSprite(root string, module string, dir string) (nodes []*sprite.NodeSprite, err error) {
func ParseNodeSprite(root string, module string, dir string, filters []string) (nodes []*sprite.NodeSprite, err error) {
nodeSprites := make([]*sprite.NodeSprite, 0)
files, err := os.ReadDir(dir)
if err != nil {
Expand All @@ -67,6 +68,9 @@ func ParseNodeSprite(root string, module string, dir string) (nodes []*sprite.No
nodeImports[key] = append(nodeImports[key], port.Path.Value[1:len(port.Path.Value)-1])
}
filePath, nodeName := GetNodeSpritePathName(key)
if HasFilterSprite(nodeName, filters) {
continue
}
nodeSprites = append(nodeSprites, &sprite.NodeSprite{
FilePath: filePath,
RootName: root,
Expand All @@ -79,7 +83,7 @@ func ParseNodeSprite(root string, module string, dir string) (nodes []*sprite.No
}
for _, file := range files {
if file.IsDir() {
sprites, err := ParseNodeSprite(root, module, fmt.Sprintf("%s/%s", dir, file.Name()))
sprites, err := ParseNodeSprite(root, module, fmt.Sprintf("%s/%s", dir, file.Name()), filters)
if err != nil {
return sprites, err
}
Expand All @@ -97,3 +101,12 @@ func GetNodeSpritePathName(content string) (filePath, nodeName string) {
index := strings.LastIndex(content, "/")
return content[:index], content[index+1:]
}

func HasFilterSprite(name string, filters []string) bool {
for _, p := range filters {
if regexp.MustCompile("^" + p + "$").MatchString(name) {
return true
}
}
return false
}
14 changes: 10 additions & 4 deletions tool/tool.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package tool

import (
"path/filepath"

"github.com/elza2/go-cyclic/resolver"
"github.com/elza2/go-cyclic/sprite"
"github.com/elza2/go-cyclic/topology"
"path/filepath"
)

func CheckCycleDepend(dir string) error {
abs, err := filepath.Abs(dir)
type Params struct {
Dir string
Filters []string
}

func CheckCycleDepend(params *Params) error {
abs, err := filepath.Abs(params.Dir)
if err != nil {
return err
}
Expand All @@ -23,7 +29,7 @@ func CheckCycleDepend(dir string) error {
return err
}
// parse sprite nodes by path.
sprites, err := resolver.ParseNodeSprite(root, module, abs)
sprites, err := resolver.ParseNodeSprite(root, module, abs, params.Filters)
if err != nil {
return err
}
Expand Down
27 changes: 17 additions & 10 deletions topology/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,32 @@ func ConstructorTopology(nodeSprites *sprite.NodeSprites) (topology *Topology) {
}
sprites := nodeSprites.GetNodeSprites()
for _, sp := range sprites {
if !strings.Contains(sp.PackageName, test) {
relation := topology.RelationTopology(nodeSprites, sp)
topology.Degrees[sp.GetAllPath()] = len(relation)
topology.Relations = append(topology.Relations, relation...)
}
relation := topology.RelationTopology(nodeSprites, sp)
topology.Degrees[sp.GetAllPath()] = len(relation)
topology.Relations = append(topology.Relations, relation...)
}
return topology
}

func (topology *Topology) RelationTopology(nodeSprites *sprite.NodeSprites, node *sprite.NodeSprite) [][]*sprite.NodeSprite {
depends := make([][]*sprite.NodeSprite, 0)
for _, in := range node.GetImportNames() {
pack := in[strings.LastIndex(in, "/")+1:]
sprites := nodeSprites.MatchImportNodeSprite(in)
packMap := map[string]int{}
for _, nodeSprite := range sprites {
if strings.Contains(nodeSprite.PackageName, test) {
continue
}
if node.GetAllPath() != nodeSprite.GetAllPath() {
depends = append(depends, []*sprite.NodeSprite{node, nodeSprite})
packMap[nodeSprite.PackageName] = 1
}
for _, nodeSprite := range sprites {
if len(packMap) == 1 {
if node.GetAllPath() != nodeSprite.GetAllPath() {
depends = append(depends, []*sprite.NodeSprite{node, nodeSprite})
}
} else {
if pack == nodeSprite.PackageName &&
node.GetAllPath() != nodeSprite.GetAllPath() {
depends = append(depends, []*sprite.NodeSprite{node, nodeSprite})
}
}
}
}
Expand Down

0 comments on commit 05d7cd1

Please sign in to comment.