Skip to content

Commit

Permalink
FEAT: (wip) Add support for regex patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
Cian911 committed Mar 5, 2022
1 parent 9033c4c commit e8ed493
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 3 deletions.
19 changes: 17 additions & 2 deletions cli/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"fmt"
"log"
"regexp"

"github.com/cian911/switchboard/utils"
"github.com/cian911/switchboard/watcher"
Expand All @@ -17,8 +18,10 @@ const (
)

var (
configFile string
ws Watchers
configFile string
ws Watchers
regexPattern *regexp.Regexp
regexErr error
)

// Watchers is a struct that contains a list of watchers.
Expand Down Expand Up @@ -70,11 +73,13 @@ func initCmd(runCmd cobra.Command) {
runCmd.PersistentFlags().StringP("ext", "e", "", "File type you want to watch for.")
runCmd.PersistentFlags().IntP("poll", "", 60, "Specify a polling time in seconds.")
runCmd.PersistentFlags().StringVar(&configFile, "config", "", "Pass an optional config file containing multiple paths to watch.")
runCmd.PersistentFlags().StringP("regex-pattern", "r", "", "Pass a regex pattern to watch for any files mathcing this pattern.")

viper.BindPFlag("path", runCmd.PersistentFlags().Lookup("path"))
viper.BindPFlag("destination", runCmd.PersistentFlags().Lookup("destination"))
viper.BindPFlag("ext", runCmd.PersistentFlags().Lookup("ext"))
viper.BindPFlag("poll", runCmd.PersistentFlags().Lookup("poll"))
viper.BindPFlag("regex-pattern", runCmd.PersistentFlags().Lookup("regex-pattern"))

var rootCmd = &cobra.Command{}
rootCmd.AddCommand(&runCmd)
Expand Down Expand Up @@ -114,6 +119,15 @@ func validateFlags() {
if !utils.ValidateFileExt(viper.GetString("ext")) {
log.Fatalf("Ext is not valid. A file extention should contain a '.': %s", viper.GetString("ext"))
}

if len(viper.GetString("regex-pattern")) > 0 {
// Validate regex pattern
regexPattern, regexErr = utils.ValidateRegexPattern(viper.GetString("regex-pattern"))

if regexErr != nil {
log.Fatalf("Regex pattern is not valid. Please check it again: %v", regexErr)
}
}
}

func registerMultiConsumers() {
Expand Down Expand Up @@ -160,6 +174,7 @@ func registerSingleConsumer() {
Path: viper.GetString("path"),
Destination: viper.GetString("destination"),
Ext: viper.GetString("ext"),
Pattern: *regexPattern,
}

pw.Register(&pc)
Expand Down
7 changes: 6 additions & 1 deletion event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import (
"github.com/cian911/switchboard/utils"
)

var ValidOperations = map[string]bool{
"CREATE": true,
"WRITE": true,
}

// Event is a struct that holds the information for a file event
type Event struct {
// File is the name of the file
Expand Down Expand Up @@ -72,7 +77,7 @@ func (e *Event) Move(path, file string) error {

// IsValidEvent checks if the event operation and file extension is valid
func (e *Event) IsValidEvent(ext string) bool {
if ext == e.Ext && e.Operation == "CREATE" || e.Operation == "WRITE" {
if ext == e.Ext && ValidOperations[e.Operation] {
return true
}

Expand Down
12 changes: 12 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"os"
"path/filepath"
"regexp"
"strings"
)

Expand Down Expand Up @@ -75,3 +76,14 @@ func IsDir(path string) bool {

return false
}

// ValidateRegexPattern takes a regex pattern string as arg
// and returns an error if invalid
func ValidateRegexPattern(pattern string) (*regexp.Regexp, error) {
r, err := regexp.Compile(pattern)
if err != nil {
return nil, err
}

return r, nil
}
19 changes: 19 additions & 0 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@ func TestUtils(t *testing.T) {
}
}
})

t.Run("It tests ValidateRegexPattern()", func(t *testing.T) {
tests := []struct {
pattern string
expectedOutput bool
}{
{`[0-9]`, true},
{`S[0-9]+EP[0-9]+`, true},
{`\\\\?m)^[0-9]{2}$`, false},
}

for _, tt := range tests {
_, err := ValidateRegexPattern(tt.pattern)

if err != nil && tt.expectedOutput != false {
t.Errorf("%s failed validation - Not a validate regex pattern. want=%t, got=%t", tt.pattern, tt.expectedOutput, err)
}
}
})
}

func setupTempDir(name string, t *testing.T) string {
Expand Down
15 changes: 15 additions & 0 deletions watcher/watcher.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package watcher

import (
"fmt"
"log"
"os"
"path/filepath"
"regexp"
"time"

"github.com/cian911/switchboard/event"
Expand Down Expand Up @@ -56,6 +58,8 @@ type PathConsumer struct {
Destination string
// File extenstion
Ext string
// Regex Pattern
Pattern regexp.Regexp
}

// Receive takes a path and an event operation, determines its validity
Expand All @@ -78,6 +82,17 @@ func (pc *PathConsumer) Receive(path, ev string) {

if e.IsNewDirEvent() {
pc.ProcessDirEvent(e)
} else if &pc.Pattern != nil {
// Check if event matches regex pattern
p := fmt.Sprintf(`%s/%s`, e.Path, e.File)
match := pc.Pattern.Match([]byte(p))

if match {
log.Println("Regex Pattern matched")
pc.Process(e)
} else {
log.Println("Regex did not match")
}
} else if e.IsValidEvent(pc.Ext) {
pc.Process(e)
}
Expand Down

0 comments on commit e8ed493

Please sign in to comment.