Skip to content

Commit

Permalink
Merge pull request #37 from kcmvp/pattern
Browse files Browse the repository at this point in the history
#36: include sub folders for wildchar pattern
  • Loading branch information
kcmvp authored Jun 18, 2024
2 parents 8b8235a + 53e9b01 commit 693f106
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 126 deletions.
26 changes: 0 additions & 26 deletions internal/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"go/types"
"log"
"os/exec"
"regexp"
"strings"
"sync"

Expand Down Expand Up @@ -88,31 +87,6 @@ func Arch() *Artifact {
})
return arch
}

func PkgPattern(path string) (*regexp.Regexp, error) {
p := `^(?:[a-zA-Z]+(?:\.[a-zA-Z]+)*|\.\.\.)$`
re := regexp.MustCompile(p)
for _, seg := range strings.Split(path, "/") {
if len(seg) > 0 && !re.MatchString(seg) {
return nil, fmt.Errorf("invalid package paths: %s", path)
}
}
path = strings.TrimSuffix(path, "/")
path = strings.TrimPrefix(path, "/")
path = strings.ReplaceAll(path, "...", ".*")
return regexp.MustCompile(fmt.Sprintf("%s$", path)), nil
}

func PkgPatters(paths ...string) []*regexp.Regexp {
return lo.Map(paths, func(path string, _ int) *regexp.Regexp {
reg, err := PkgPattern(path)
if err != nil {
log.Fatal(err)
}
return reg
})
}

func parse(pkg *packages.Package, mode ParseMode) *Package {
archPkg := &Package{raw: pkg}
typPkg := pkg.Types
Expand Down
61 changes: 2 additions & 59 deletions internal/artifact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,6 @@ import (
"testing"
)

func Test_pattern(t *testing.T) {
tests := []struct {
name string
path string
wantErr bool
}{
{
name: "valid one dot",
path: "github.com/kcmvp/archunit",
wantErr: false,
},
{
name: "invalid one dot",
path: "github.com/./kcmvp/archunit",
wantErr: true,
},
{
name: "valid-two-dots",
path: "git.hub.com/kcmvp/archunit",
wantErr: false,
},
{
name: "invalid with two dots",
path: "github.com/../kcmvp/archunit",
wantErr: true,
},
{
name: "invalid-two-dots",
path: "github..com/kcmvp/archunit",
wantErr: true,
},
{
name: "invalid-two-dots",
path: "githubcom/../kcmvp/archunit",
wantErr: true,
},
{
name: "valid three dots",
path: "githubcom/.../kcmvp/archunit",
wantErr: false,
},
{
name: "invalid three more dots",
path: "githubcom/..../kcmvp/archunit",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := PkgPattern(tt.path)
assert.Equal(t, tt.wantErr, err != nil)
})
}
}

func TestAllConstants(t *testing.T) {
tests := []struct {
pkg string
Expand Down Expand Up @@ -103,8 +48,6 @@ func TestPackage_Functions(t *testing.T) {
pkg: "github.com/kcmvp/archunit/internal",
funcs: []string{
"Arch",
"PkgPattern",
"PkgPatters",
"parse",
},
imports: []string{
Expand All @@ -113,7 +56,6 @@ func TestPackage_Functions(t *testing.T) {
"golang.org/x/tools/go/packages",
"log",
"go/types",
"regexp",
"github.com/samber/lo",
"strings",
"sync",
Expand All @@ -139,6 +81,7 @@ func TestPackage_Functions(t *testing.T) {
"TypesWith",
"Packages",
"AllPackages",
"ScopePattern",
},
imports: []string{
"fmt",
Expand Down Expand Up @@ -199,7 +142,7 @@ func TestPackage_Functions(t *testing.T) {
}

func TestAllSource(t *testing.T) {
assert.Equal(t, 20, len(Arch().GoFiles()))
assert.Equal(t, 21, len(Arch().GoFiles()))
}

func TestMethodsOfType(t *testing.T) {
Expand Down
55 changes: 39 additions & 16 deletions layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ func ConstantsShouldBeDefinedInOneFileByPackage() error {
return nil
}

func Layer(pkgPaths ...string) ArchLayer {
patterns := internal.PkgPatters(pkgPaths...)
func Layer(pkgPaths ...string) (ArchLayer, error) {
patterns, err := ScopePattern(pkgPaths...)
if err != nil {
return nil, err
}
return lo.Filter(internal.Arch().Packages(), func(pkg *internal.Package, _ int) bool {
return lo.ContainsBy(patterns, func(pattern *regexp.Regexp) bool {
return pattern.MatchString(pkg.ID())
})
})
}), nil
}

func (layer ArchLayer) Name() string {
Expand All @@ -79,22 +82,28 @@ func (layer ArchLayer) Name() string {
return fmt.Sprintf("%v", left)
}

func (layer ArchLayer) Exclude(pkgPaths ...string) ArchLayer {
patterns := internal.PkgPatters(pkgPaths...)
func (layer ArchLayer) Exclude(pkgPaths ...string) (ArchLayer, error) {
patterns, err := ScopePattern(pkgPaths...)
if err != nil {
return nil, err
}
return lo.Filter(layer, func(pkg *internal.Package, _ int) bool {
return lo.NoneBy(patterns, func(pattern *regexp.Regexp) bool {
return pattern.MatchString(pkg.ID())
})
})
}), nil
}

func (layer ArchLayer) Sub(name string, paths ...string) ArchLayer {
patterns := internal.PkgPatters(paths...)
func (layer ArchLayer) Sub(name string, paths ...string) (ArchLayer, error) {
patterns, err := ScopePattern(paths...)
if err != nil {
return nil, err
}
return lo.Filter(layer, func(pkg *internal.Package, _ int) bool {
return lo.SomeBy(patterns, func(pattern *regexp.Regexp) bool {
return pattern.MatchString(pkg.ID())
})
})
}), nil
}

func (layer ArchLayer) Packages() ArchPackage {
Expand Down Expand Up @@ -137,16 +146,19 @@ func (layer ArchLayer) Files() FileSet {
})
}

func (layer ArchLayer) FilesInPackages(paths ...string) FileSet {
patterns := internal.PkgPatters(paths...)
func (layer ArchLayer) FilesInPackages(paths ...string) (FileSet, error) {
patterns, err := ScopePattern(paths...)
if err != nil {
return nil, err
}
return lo.FilterMap(layer, func(pkg *internal.Package, _ int) (PackageFile, bool) {
if lo.SomeBy(patterns, func(reg *regexp.Regexp) bool {
return reg.MatchString(pkg.ID())
}) {
return PackageFile{A: pkg.ID(), B: pkg.GoFiles()}, true
}
return PackageFile{}, false
})
}), nil
}

func (layer ArchLayer) ShouldNotReferLayers(layers ...ArchLayer) error {
Expand All @@ -161,7 +173,11 @@ func (layer ArchLayer) ShouldNotReferLayers(layers ...ArchLayer) error {
}

func (layer ArchLayer) ShouldNotReferPackages(paths ...string) error {
return layer.ShouldNotReferLayers(Layer(paths...))
l, err := Layer(paths...)
if err != nil {
return err
}
return layer.ShouldNotReferLayers(l)
}

func (layer ArchLayer) ShouldOnlyReferLayers(layers ...ArchLayer) error {
Expand All @@ -174,7 +190,11 @@ func (layer ArchLayer) ShouldOnlyReferLayers(layers ...ArchLayer) error {
}

func (layer ArchLayer) ShouldOnlyReferPackages(paths ...string) error {
return layer.ShouldOnlyReferLayers(Layer(paths...))
l, err := Layer(paths...)
if err != nil {
return err
}
return layer.ShouldOnlyReferLayers(l)
}

func (layer ArchLayer) ShouldBeOnlyReferredByLayers(layers ...ArchLayer) error {
Expand All @@ -184,8 +204,11 @@ func (layer ArchLayer) ShouldBeOnlyReferredByLayers(layers ...ArchLayer) error {
}

func (layer ArchLayer) ShouldBeOnlyReferredByPackages(paths ...string) error {
layer1 := Layer(paths...)
return layer.ShouldBeOnlyReferredByLayers(layer1)
l, err := Layer(paths...)
if err != nil {
return err
}
return layer.ShouldBeOnlyReferredByLayers(l)
}

func (layer ArchLayer) DepthShouldLessThan(depth int) error {
Expand Down
26 changes: 13 additions & 13 deletions layer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"testing"
)

func TestPackages(t *testing.T) {
func TestLayerPackages(t *testing.T) {
tests := []struct {
name string
paths []string
Expand Down Expand Up @@ -41,10 +41,10 @@ func TestPackages(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
layer := Layer(test.paths...)
layer, _ := Layer(test.paths...)
assert.Equal(t, test.size1, len(layer.packages()))
if len(test.except) > 0 {
layer = layer.Exclude(test.except...)
layer, _ = layer.Exclude(test.except...)
assert.Equal(t, test.size2, len(layer.packages()))
}
})
Expand All @@ -63,22 +63,22 @@ func TestLayer_Sub(t *testing.T) {
name: "ext sub",
paths: []string{".../service/..."},
sub: []string{".../ext/"},
size1: 4,
size1: 5,
size2: 1,
},
{
name: "ext sub",
paths: []string{".../service/..."},
sub: []string{".../ext/..."},
size1: 4,
size2: 2,
size1: 5,
size2: 3,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
layer := Layer(tt.paths...)
layer, _ := Layer(tt.paths...)
assert.Equal(t, tt.size1, len(layer.packages()))
layer = layer.Sub(tt.name, tt.sub...)
layer, _ = layer.Sub(tt.name, tt.sub...)
assert.Equal(t, tt.size2, len(layer.packages()))
})
}
Expand All @@ -97,7 +97,7 @@ func TestConstantsShouldBeDefinedInOneFileByPackage(t *testing.T) {
}

func TestLayPackages(t *testing.T) {
layer := Layer("sample/controller", "sample/controller/...")
layer, _ := Layer("sample/controller/...")
assert.ElementsMatch(t, []string{"github.com/kcmvp/archunit/internal/sample/controller",
"github.com/kcmvp/archunit/internal/sample/controller/module1"}, layer.packages())
assert.ElementsMatch(t, layer.Imports(),
Expand All @@ -112,10 +112,10 @@ func TestLayPackages(t *testing.T) {
}

func TestLayer_Refer(t *testing.T) {
controller := Layer("sample/controller", "sample/controller/...")
model := Layer("sample/model")
service := Layer("sample/service", "sample/service/...")
repository := Layer("sample/repository", "sample/repository/...")
controller, _ := Layer("sample/controller", "sample/controller/...")
model, _ := Layer("sample/model")
service, _ := Layer("sample/service", "sample/service/...")
repository, _ := Layer("sample/repository", "sample/repository/...")
assert.NoError(t, controller.ShouldNotReferLayers(model))
assert.NoError(t, controller.ShouldNotReferPackages("sample/model"))
assert.Errorf(t, controller.ShouldNotReferLayers(repository), "controller should not refer repository")
Expand Down
22 changes: 16 additions & 6 deletions package.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ func AllPackages() ArchPackage {
return internal.Arch().Packages()
}

func Packages(paths ...string) ArchPackage {
patterns := internal.PkgPatters(paths...)
func Packages(paths ...string) (ArchPackage, error) {
patterns, err := ScopePattern(paths...)
return lo.Filter(AllPackages(), func(pkg *internal.Package, _ int) bool {
return lo.ContainsBy(patterns, func(pattern *regexp.Regexp) bool {
return pattern.MatchString(pkg.ID())
})
})
}), err
}

func (archPkg ArchPackage) ID() []string {
Expand Down Expand Up @@ -104,7 +104,11 @@ func (archPkg ArchPackage) ShouldNotRefer(referred ...ArchPackage) error {
}

func (archPkg ArchPackage) ShouldNotReferPkgPaths(paths ...string) error {
return archPkg.ShouldNotRefer(Packages(paths...))
pkgs, err := Packages(paths...)
if err != nil {
return err
}
return archPkg.ShouldNotRefer(pkgs)
}

func (archPkg ArchPackage) ShouldBeOnlyReferredByPackages(referrings ...ArchPackage) error {
Expand Down Expand Up @@ -134,11 +138,17 @@ func (archPkg ArchPackage) ShouldOnlyReferPackages(referred ...ArchPackage) erro
}

func (archPkg ArchPackage) ShouldOnlyReferPkgPaths(paths ...string) error {
pkg := Packages(paths...)
pkg, err := Packages(paths...)
if err != nil {
return err
}
return archPkg.ShouldOnlyReferPackages(pkg)
}

func (archPkg ArchPackage) ShouldBeOnlyReferredByPkgPaths(paths ...string) error {
pkg := Packages(paths...)
pkg, err := Packages(paths...)
if err != nil {
return err
}
return archPkg.ShouldBeOnlyReferredByPackages(pkg)
}
Loading

0 comments on commit 693f106

Please sign in to comment.