Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions find_replace.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bytes"
"errors"
"fmt"
"io"
Expand All @@ -13,9 +14,20 @@ import (

// findReplace is a struct used to provide context to all find & replace
// operations, including the strings to search for & replace.
func newFindReplace(find, replace string) findReplace {
return findReplace{
find: find,
replace: replace,
findB: []byte(find),
replaceB: []byte(replace),
}
}

type findReplace struct {
find string
replace string
find string
replace string
findB []byte
replaceB []byte

// errs accumulates non-fatal errors that occurred during a walk. The
// walker logs each error at the point of failure (preserving the
Expand Down Expand Up @@ -82,7 +94,7 @@ func run(args []string, stderr io.Writer) int {
return 1
}

fr := findReplace{find: args[1], replace: args[2]}
fr := newFindReplace(args[1], args[2])

// Recursively explore the hierarchy depth first, rewrite files as needed,
// and rename files last (after we don't have to revisit them).
Expand Down Expand Up @@ -204,9 +216,9 @@ func (fr *findReplace) ReplaceContents(f *File) error {
if err != nil {
return err
}
if !strings.Contains(content, fr.find) {
if !bytes.Contains([]byte(content), fr.findB) {
return nil
}
newContent := strings.ReplaceAll(content, fr.find, fr.replace)
newContent := string(bytes.ReplaceAll([]byte(content), fr.findB, fr.replaceB))
return f.Write(newContent)
}
28 changes: 14 additions & 14 deletions find_replace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func TestWalkDir(t *testing.T) {
f1 := newTestFile(t, d.Path, "why", f1Contents)
defer os.Remove(f1.Path)

fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)
fr.WalkDir(d)
if err := fr.errs.err(); err != nil {
t.Fatalf("WalkDir reported errors: %v", err)
Expand Down Expand Up @@ -228,7 +228,7 @@ func TestHandleFileWithDir(t *testing.T) {
defer os.Remove(f.Path)
expectedPath := filepath.Join(f.Dir(), strings.ReplaceAll(f.Base(), find, replace))
defer os.Remove(expectedPath)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)

assertFileExists(t, f)
if err := fr.HandleFile(f); err != nil {
Expand All @@ -252,7 +252,7 @@ func TestHandleFileWithIgnoredDir(t *testing.T) {
unexpectedName := strings.ReplaceAll(f.Base(), find, replace)
unexpectedPath := filepath.Join(f.Dir(), unexpectedName)
defer os.Remove(unexpectedPath)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)

assertFileExists(t, f)
if err := fr.HandleFile(f); err != nil {
Expand All @@ -272,7 +272,7 @@ func TestHandleFileWithFile(t *testing.T) {
expectedName := strings.ReplaceAll(f.Base(), find, replace)
expectedPath := filepath.Join(f.Dir(), expectedName)
defer os.Remove(expectedPath)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)

assertFileExists(t, f)
if err := fr.HandleFile(f); err != nil {
Expand All @@ -296,7 +296,7 @@ func TestRenameFile(t *testing.T) {
expectedName := strings.ReplaceAll(f.Base(), find, replace)
expectedPath := filepath.Join(f.Dir(), expectedName)
defer os.Remove(expectedPath)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)

assertFileExists(t, f)
if err := fr.RenameFile(f); err != nil {
Expand All @@ -323,7 +323,7 @@ func TestReplaceContents(t *testing.T) {

f := newTestFile(t, "", "*", initial)
defer os.Remove(f.Path)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)
if err := fr.ReplaceContents(f); err != nil {
t.Fatalf("ReplaceContents(%q): %v", f.Path, err)
}
Expand All @@ -338,7 +338,7 @@ func TestReplaceContentsEntireFile(t *testing.T) {

f := newTestFile(t, "", "*", initial)
defer os.Remove(f.Path)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)
if err := fr.ReplaceContents(f); err != nil {
t.Fatalf("ReplaceContents(%q): %v", f.Path, err)
}
Expand All @@ -353,7 +353,7 @@ func TestReplaceContentsMultipleMatchesSingleLine(t *testing.T) {

f := newTestFile(t, "", "*", initial)
defer os.Remove(f.Path)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)
if err := fr.ReplaceContents(f); err != nil {
t.Fatalf("ReplaceContents(%q): %v", f.Path, err)
}
Expand All @@ -368,7 +368,7 @@ func TestReplaceContentsMultipleMatchesMultipleLines(t *testing.T) {

f := newTestFile(t, "", "*", initial)
defer os.Remove(f.Path)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)
if err := fr.ReplaceContents(f); err != nil {
t.Fatalf("ReplaceContents(%q): %v", f.Path, err)
}
Expand All @@ -383,7 +383,7 @@ func TestReplaceContentsNoMatches(t *testing.T) {

f := newTestFile(t, "", "*", initial)
defer os.Remove(f.Path)
fr := findReplace{find: find, replace: replace}
fr := newFindReplace(find, replace)
if err := fr.ReplaceContents(f); err != nil {
t.Fatalf("ReplaceContents(%q): %v", f.Path, err)
}
Expand Down Expand Up @@ -433,7 +433,7 @@ func TestWalkDir_PermissionDeniedSubdirContinues(t *testing.T) {
t.Cleanup(func() { _ = os.Chmod(denied, 0700) })

rootFile := newFileOrFatal(t, root)
fr := findReplace{find: "alpha", replace: "beta"}
fr := newFindReplace("alpha", "beta")
fr.WalkDir(rootFile)

// The sibling file should have been rewritten despite the denied subtree.
Expand Down Expand Up @@ -473,7 +473,7 @@ func TestRenameFile_ReturnsErrorOnExistingDestination(t *testing.T) {
}

f := newFileOrFatal(t, src)
fr := findReplace{find: "alpha", replace: "beta"}
fr := newFindReplace("alpha", "beta")
err := fr.RenameFile(f)
if err == nil {
t.Fatalf("RenameFile(%q): err = nil; want an error referencing the occupied destination", src)
Expand Down Expand Up @@ -516,7 +516,7 @@ func TestWalkDir_BadRenameTargetDoesNotAbortSiblings(t *testing.T) {
}

rootFile := newFileOrFatal(t, root)
fr := findReplace{find: "alpha", replace: "beta"}
fr := newFindReplace("alpha", "beta")
fr.WalkDir(rootFile)

// The free file should have been renamed.
Expand Down Expand Up @@ -679,7 +679,7 @@ func BenchmarkNova(b *testing.B) {
for n := 0; n < b.N; n++ {
b.StopTimer()
d := CloneRepoToTestDir(b, "git@github.com:openstack/nova.git")
fr := findReplace{find: RandomString(2), replace: RandomString(2)}
fr := newFindReplace(RandomString(2), RandomString(2))
b.StartTimer()
fr.WalkDir(d)
}
Expand Down