Skip to content

Commit

Permalink
Big rework and expanded test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
danawoodman committed Feb 19, 2024
1 parent b0d658c commit 64d3cee
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 122 deletions.
38 changes: 30 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
.PHONY: dev build install test watch-test
#------------------------------------------------------------------------------
# TESTS
#------------------------------------------------------------------------------

dev:
@cng -ik '**/*.go' -- make build
.PHONY: test
test:
@make -j test-unit test-e2e

# @cng -ik '**/*.go' -- go run ./cmd/cng $(ARGS)
.PHONY: test-e2e
test-e2e:
@go test -v ./test/...

test:
@go test -v ./...
.PHONY: test-unit
test-unit:
@go test -v ./internal/...

.PHONY: watch-test
watch-test:
@cng -ik '**/*.go' -- make install test
@make -j watch-unit-test watch-e2e-test

.PHONY: watch-unit-test
watch-unit-test:
@cng -ik -e 'test' '**/*.go' -- make test-unit

.PHONY: watch-e2e-test
watch-e2e-test:
@cng -ik '**/*.go' -- make install test-e2e

#------------------------------------------------------------------------------
# BUILDING
#------------------------------------------------------------------------------

.PHONY: build
build:
@CGO_ENABLED=0 go build -a -gcflags=all="-l -B" -ldflags="-s -w" -o bin/cng ./cmd/cng
@echo "🎉 cng built to bin/cng"

.PHONY: install
install:
@go install ./cmd/cng
@echo "🎉 cng installed to: $(shell which cng)"

.PHONY: watch-install
watch-install:
@cng -ik '**/*.go' -- make install

.DEFAULT_GOAL := dev
.DEFAULT_GOAL := watch-test
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ go install github.com/danawoodman/cng
cng -i -k '**/*.go' 'templates/**/*.html' -- go run ./cmd/myapp

# Run tests when your source or tests change:
cng 'app/**/*.tsx?' '**/*.test.ts' -- npm test
cng 'app/**/*.{ts,tsx}' '**/*.test.ts' -- npm test

# Wait 500ms before running the command:
cng -d 500 '*.md' -- echo "changed!"
Expand Down
16 changes: 8 additions & 8 deletions cmd/cng/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ func execute(cmd *cobra.Command, args []string) {

watchedPaths := args[:cmdIndex]

internal.NewWatcher(&internal.WatcherConfig{
Command: cmdToRun,
Paths: watchedPaths,
Verbose: verbose,
Initial: initial,
Kill: kill,
Exclude: exclude,
Delay: delay,
internal.NewWatcher(internal.WatcherConfig{
Command: cmdToRun,
ExcludePaths: watchedPaths,
Verbose: verbose,
Initial: initial,
Kill: kill,
Exclude: exclude,
Delay: delay,
}).Start()
}

Expand Down
50 changes: 50 additions & 0 deletions internal/domain/skip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package domain

import (
"fmt"
"path/filepath"

"github.com/bmatcuk/doublestar/v4"
)

type Skipper interface {
ShouldExclude(path string) bool
}

type skipper struct {
workDir string
exclude []string
}

func NewSkipper(workDir string, exclude []string) Skipper {
return skipper{workDir: workDir, exclude: exclude}
}

// shouldExclude returns true if the given path should be excluded from
// triggering a command run based on the `-e, --exclude` flag.
func (s skipper) ShouldExclude(path string) bool {
// skip common things like .git and node_modules dirs
// todo: make this configurable
ignores := []string{".git", "node_modules"}
for _, ignore := range ignores {
if matches, _ := doublestar.PathMatch(fmt.Sprintf("**/%s/**", ignore), path); matches {
return true
}
}

// fmt.Println("EXCLUDE:", s.exclude)
// fmt.Println("PATH:", path)

// check if the path matches any of the exclude patterns
for _, pattern := range s.exclude {
// s.log("Checking exclude pattern", "pattern", pattern, "path", path)
expandedPattern := filepath.Join(s.workDir, pattern)
// fmt.Println("EXPANDED:", expandedPattern)
if matches, _ := doublestar.PathMatch(expandedPattern, path); matches {
// s.log("File in exclude path, skipping", "exclude", pattern)
return true
}
}

return false
}
102 changes: 102 additions & 0 deletions internal/domain/skip_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package domain_test

import (
"path/filepath"
"testing"

"github.com/danawoodman/cng/internal/domain"
"github.com/stretchr/testify/assert"
)

func Test(t *testing.T) {
tests := []struct {
name string
workDir string
exclusions []string
expected map[string]bool
}{
{
name: "ignore common directories",
workDir: "/foo",
exclusions: []string{"**/*.txt"},
expected: map[string]bool{
"/foo/.git/test.txt": true,
"/foo/bar/.git/test.txt": true,
"/foo/node_modules/test.txt": true,
"/foo/bar/node_modules/test.txt": true,
},
},
{
name: "absolute paths",
workDir: "/foo",
exclusions: []string{"**/*.txt"},
expected: map[string]bool{
"/foo/bar/baz/test.txt": true,
"/biz/bang/bop/test.md": false,
},
},
{
name: "relative paths",
workDir: "/foo/bar",
exclusions: []string{"**/*.txt"},
expected: map[string]bool{
"/test.txt": false,
"/foo/test.txt": false,
"/foo/bar/test.txt": true,
"/test.md": false,
"/foo/test.md": false,
"/foo/bar/test.md": false,
},
},
{
name: "current dir",
workDir: "/foo",
exclusions: []string{"*.txt"},
expected: map[string]bool{
"/foo/test.txt": true,
"/foo/foo.txt": true,
"/test.txt": false,
"/test.md": false,
"/foo/test.md": false,
},
},
{
name: "fragment pattern",
workDir: "/",
exclusions: []string{"foo_*.txt"},
expected: map[string]bool{
"/test.txt": false,
"/foo.txt": false,
"/foo_bar.txt": true,
"/foo_1.txt": true,
},
},
{
name: "optional ending",
workDir: "/foo",
exclusions: []string{"*.{js,jsx}"},
expected: map[string]bool{
"/foo/a.js": true,
"/foo/b.jsx": true,
"/foo/c.j": false,
"/foo/c.jsxx": false,
},
},
// todo: test windows \ paths
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
var exclusions []string
for _, e := range test.exclusions {
exclusions = append(exclusions, filepath.Join(test.workDir, e))
}
s := domain.NewSkipper(test.workDir, exclusions)
for path, val := range test.expected {
p := filepath.Join(test.workDir, path)
assert.Equal(t, val, s.ShouldExclude(p), "exclude patterns %v should skip path '%s' but didn't", test.exclusions, path)
}
})
}
}
22 changes: 0 additions & 22 deletions internal/types.go

This file was deleted.

Loading

0 comments on commit 64d3cee

Please sign in to comment.