-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
137 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package builder | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/fsnotify/fsnotify" | ||
) | ||
|
||
type Watcher struct { | ||
sourceDir string | ||
} | ||
|
||
func NewWatcher( | ||
sourceDir string, | ||
) *Watcher { | ||
return &Watcher{ | ||
sourceDir: sourceDir, | ||
} | ||
} | ||
|
||
func (w *Watcher) Execute(fn func(string) error) error { | ||
watcher, err := fsnotify.NewWatcher() | ||
if err != nil { | ||
return fmt.Errorf("could not create file watcher: %w", err) | ||
} | ||
defer watcher.Close() | ||
|
||
err = watcher.Add(w.sourceDir) | ||
if err != nil { | ||
return fmt.Errorf("could add watching path: %w", err) | ||
} | ||
|
||
for event := range watcher.Events { | ||
err := fn(event.Name) | ||
if err != nil { | ||
return fmt.Errorf("could not execute fn in watcher: %w", err) | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package builder_test | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/jtarchie/builder" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
"go.uber.org/atomic" | ||
) | ||
|
||
var _ = Describe("Watcher", func() { | ||
When("a file gets updated", func() { | ||
It("executes the callback with the affected filename", func() { | ||
var foundFilename atomic.String | ||
|
||
sourceDir, err := os.MkdirTemp("", "") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
watcher := builder.NewWatcher(sourceDir) | ||
|
||
//nolint:errcheck,unparam | ||
go watcher.Execute(func(filename string) error { | ||
foundFilename.Store(filename) | ||
|
||
return nil | ||
}) | ||
|
||
Consistently(foundFilename.Load).Should(Equal("")) | ||
|
||
expectedFilename := filepath.Join(sourceDir, "file") | ||
|
||
err = os.WriteFile(expectedFilename, []byte(""), os.ModePerm) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Eventually(foundFilename.Load).Should(Equal(expectedFilename)) | ||
}) | ||
}) | ||
|
||
When("the source path does not exists", func() { | ||
It("returns an error", func() { | ||
watcher := builder.NewWatcher("asdf") | ||
|
||
err := watcher.Execute(func(s string) error { | ||
return nil | ||
}) | ||
Expect(err).To(HaveOccurred()) | ||
}) | ||
}) | ||
|
||
When("the callback returns an error", func() { | ||
It("stops watching altogether", func() { | ||
var callbackCount atomic.Int32 | ||
|
||
sourceDir, err := os.MkdirTemp("", "") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
watcher := builder.NewWatcher(sourceDir) | ||
|
||
//nolint:errcheck,unparam | ||
go watcher.Execute(func(filename string) error { | ||
callbackCount.Add(1) | ||
|
||
return fmt.Errorf("some error") | ||
}) | ||
|
||
Consistently(callbackCount.Load).Should(BeEquivalentTo(0)) | ||
|
||
for i := 0; i < 10; i++ { | ||
expectedFilename := filepath.Join(sourceDir, "file") | ||
|
||
err = os.WriteFile(expectedFilename, []byte(fmt.Sprintf("%d", i)), os.ModePerm) | ||
Expect(err).NotTo(HaveOccurred()) | ||
} | ||
|
||
Consistently(callbackCount.Load).Should(BeEquivalentTo(1)) | ||
}) | ||
}) | ||
}) |