Skip to content

Commit

Permalink
Merge pull request #35 from catatsuy/feature_add_ignore_case
Browse files Browse the repository at this point in the history
Add ignore case functionality for search patterns
  • Loading branch information
catatsuy authored Apr 6, 2024
2 parents 4c88fa5 + 3aa6da5 commit 57b3c32
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 15 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ staticcheck:
test:
go test -cover -v ./...

.PHONY: cover
cover:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

.PHONY: clean
clean:
rm -rf bin/*
23 changes: 18 additions & 5 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type CLI struct {
excludes rawStrings
help bool
color bool
ignoreCase bool
version bool

appVersion string
Expand Down Expand Up @@ -126,20 +127,24 @@ func (c *CLI) Run(args []string) int {
}
searchPattern, replacement := parts[0], parts[1]

if c.ignoreCase {
searchPattern = "(?i)" + searchPattern
}

if err := c.replaceProcess(searchPattern, replacement, file); err != nil {
fmt.Fprintf(c.errStream, "Failed to process files: %s\n", err)
return ExitCodeFail
}
}

if len(c.filters) > 0 || len(c.excludes) > 0 {
filters, err := compileRegexps(c.filters)
filters, err := compileRegexps(c.filters, c.ignoreCase)
if err != nil {
fmt.Fprintf(c.errStream, "Failed to compile regex patterns: %s\n", err)
return ExitCodeFail
}

excludes, err := compileRegexps(c.excludes)
excludes, err := compileRegexps(c.excludes, c.ignoreCase)
if err != nil {
fmt.Fprintf(c.errStream, "Failed to compile regex patterns: %s\n", err)
return ExitCodeFail
Expand Down Expand Up @@ -169,20 +174,24 @@ func (c *CLI) Run(args []string) int {
}
searchPattern, replacement := parts[0], parts[1]

if c.ignoreCase {
searchPattern = "(?i)" + searchPattern
}

if err := c.replaceProcess(searchPattern, replacement, c.inputStream); err != nil {
fmt.Fprintf(c.errStream, "Failed to process files: %s\n", err)
return ExitCodeFail
}
}

if len(c.filters) > 0 || len(c.excludes) > 0 {
filters, err := compileRegexps(c.filters)
filters, err := compileRegexps(c.filters, c.ignoreCase)
if err != nil {
fmt.Fprintf(c.errStream, "Failed to compile regex patterns: %s\n", err)
return ExitCodeFail
}

excludes, err := compileRegexps(c.excludes)
excludes, err := compileRegexps(c.excludes, c.ignoreCase)
if err != nil {
fmt.Fprintf(c.errStream, "Failed to compile regex patterns: %s\n", err)
return ExitCodeFail
Expand Down Expand Up @@ -211,6 +220,7 @@ func (c *CLI) parseFlags(args []string) (*flag.FlagSet, error) {
flags.Var(&c.excludes, "exclude", "Exclude lines matching regex.")
flags.BoolVar(&c.color, "color", false, "Colored output. Default auto.")
flags.BoolVar(&noColor, "no-color", false, "Disable colored output.")
flags.BoolVar(&c.ignoreCase, "i", false, `Ignore case (prefixes '(?i)' to all regular expressions)`)
flags.BoolVar(&c.help, "help", false, `Show help`)
flags.BoolVar(&c.version, "version", false, "Print version and quit")

Expand Down Expand Up @@ -305,9 +315,12 @@ func (c *CLI) filterProcess(filters []*regexp.Regexp, excludes []*regexp.Regexp,
return nil
}

func compileRegexps(rawPatterns []string) ([]*regexp.Regexp, error) {
func compileRegexps(rawPatterns []string, ignoreCase bool) ([]*regexp.Regexp, error) {
regexps := make([]*regexp.Regexp, 0, len(rawPatterns))
for _, pattern := range rawPatterns {
if ignoreCase {
pattern = "(?i)" + pattern
}
re, err := regexp.Compile(pattern)
if err != nil {
return nil, fmt.Errorf("invalid regex pattern: %w", err)
Expand Down
36 changes: 28 additions & 8 deletions internal/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,24 @@ func TestRun_successProcess(t *testing.T) {
},
"provide file": {
args: []string{"purl", "-replace", "@search@replacement@", "testdata/test.txt"},
expected: "replacementa replacementb\n",
expected: "replacementa replacementb\nSearcha Searchb\n",
},
"provide multiple files for replace": {
args: []string{"purl", "-replace", "@search@replacement@", "testdata/test.txt", "testdata/testa.txt"},
expected: "replacementa replacementb\nreplacementc replacementd\nnot not not\n",
expected: "replacementa replacementb\nSearcha Searchb\nreplacementc replacementd\nnot not not\n",
},
"provide file for ignore case": {
args: []string{"purl", "-i", "-replace", "@search@replacement@", "testdata/test.txt"},
expected: "replacementa replacementb\nreplacementa replacementb\n",
},
"provide multiple files for ignore case": {
args: []string{"purl", "-i", "-replace", "@search@replacement@", "testdata/test.txt", "testdata/testa.txt"},
expected: "replacementa replacementb\nreplacementa replacementb\nreplacementc replacementd\nnot not not\n",
},
"provide stdin for ignore case": {
args: []string{"purl", "-i", "-replace", "@search@replacement@"},
input: "searcha Search\nsearchc Searchd\n",
expected: "replacementa replacement\nreplacementc replacementd\n",
},
"provide multiple files for filter": {
args: []string{"purl", "-filter", "search", "testdata/test.txt", "testdata/testa.txt"},
Expand Down Expand Up @@ -348,15 +361,22 @@ func TestReplaceProcess_noMatch(t *testing.T) {

func TestCompileRegexps(t *testing.T) {
tests := []struct {
name string
patterns []string
wantError bool
name string
patterns []string
ignoreCase bool
wantError bool
}{
{
name: "ValidPatterns",
patterns: []string{"^test", "end$", "[0-9]+"},
wantError: false,
},
{
name: "ValidPatterns for ignore case",
patterns: []string{"^test", "end$", "[0-9]+"},
ignoreCase: true,
wantError: false,
},
{
name: "InvalidPattern",
patterns: []string{"["},
Expand All @@ -376,7 +396,7 @@ func TestCompileRegexps(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := cli.CompileRegexps(tt.patterns)
got, err := cli.CompileRegexps(tt.patterns, tt.ignoreCase)
if tt.wantError {
if err == nil {
t.Errorf("%s: expected an error but got none", tt.name)
Expand Down Expand Up @@ -465,13 +485,13 @@ func TestFilterProcess(t *testing.T) {
cl := cli.NewCLI(outStream, errStream, inputStream)
inputStream.WriteString(tt.input)

filters, err := cli.CompileRegexps(tt.filters)
filters, err := cli.CompileRegexps(tt.filters, false)
if err != nil {
t.Errorf("CompileRegexps() error = %v", err)
return
}

excludes, err := cli.CompileRegexps(tt.excludes)
excludes, err := cli.CompileRegexps(tt.excludes, false)
if err != nil {
t.Errorf("CompileRegexps() error = %v", err)
return
Expand Down
4 changes: 2 additions & 2 deletions internal/cli/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ func (c *CLI) FilterProcess(filters []*regexp.Regexp, notFilters []*regexp.Regex
return c.filterProcess(filters, notFilters, inputStream)
}

func CompileRegexps(rawPatterns []string) ([]*regexp.Regexp, error) {
return compileRegexps(rawPatterns)
func CompileRegexps(rawPatterns []string, ignoreCase bool) ([]*regexp.Regexp, error) {
return compileRegexps(rawPatterns, ignoreCase)
}
1 change: 1 addition & 0 deletions internal/cli/testdata/test.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
searcha searchb
Searcha Searchb

0 comments on commit 57b3c32

Please sign in to comment.