diff options
Diffstat (limited to 'src/go/plugin/go.d/pkg/multipath')
6 files changed, 152 insertions, 0 deletions
diff --git a/src/go/plugin/go.d/pkg/multipath/multipath.go b/src/go/plugin/go.d/pkg/multipath/multipath.go new file mode 100644 index 00000000..6172def0 --- /dev/null +++ b/src/go/plugin/go.d/pkg/multipath/multipath.go @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package multipath + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "slices" + "strings" + + "github.com/mitchellh/go-homedir" +) + +type ErrNotFound struct{ msg string } + +func (e ErrNotFound) Error() string { return e.msg } + +// IsNotFound returns a boolean indicating whether the error is ErrNotFound or not. +func IsNotFound(err error) bool { + var errNotFound ErrNotFound + return errors.As(err, &errNotFound) +} + +// MultiPath multi-paths +type MultiPath []string + +// New multi-paths +func New(paths ...string) MultiPath { + set := map[string]bool{} + mPath := make(MultiPath, 0) + + for _, dir := range paths { + if dir == "" { + continue + } + if d, err := homedir.Expand(dir); err != nil { + dir = d + } + if !set[dir] { + mPath = append(mPath, dir) + set[dir] = true + } + } + + return mPath +} + +// Find finds a file in given paths +func (p MultiPath) Find(filename string) (string, error) { + for _, dir := range p { + file := filepath.Join(dir, filename) + if _, err := os.Stat(file); !os.IsNotExist(err) { + return file, nil + } + } + return "", ErrNotFound{msg: fmt.Sprintf("can't find '%s' in %v", filename, p)} +} + +func (p MultiPath) FindFiles(suffixes ...string) ([]string, error) { + set := make(map[string]bool) + var files []string + + for _, dir := range p { + entries, err := os.ReadDir(dir) + if err != nil { + continue + } + + for _, e := range entries { + if !e.Type().IsRegular() { + continue + } + + ext := filepath.Ext(e.Name()) + name := strings.TrimSuffix(e.Name(), ext) + + if (len(suffixes) != 0 && !slices.Contains(suffixes, ext)) || set[name] { + continue + } + + set[name] = true + file := filepath.Join(dir, e.Name()) + files = append(files, file) + } + } + + return files, nil +} diff --git a/src/go/plugin/go.d/pkg/multipath/multipath_test.go b/src/go/plugin/go.d/pkg/multipath/multipath_test.go new file mode 100644 index 00000000..cd6c90d9 --- /dev/null +++ b/src/go/plugin/go.d/pkg/multipath/multipath_test.go @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package multipath + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNew(t *testing.T) { + assert.Len( + t, + New("path1", "path2", "path2", "", "path3"), + 3, + ) +} + +func TestMultiPath_Find(t *testing.T) { + m := New("path1", "testdata/data1") + + v, err := m.Find("not exist") + assert.Zero(t, v) + assert.Error(t, err) + + v, err = m.Find("test-empty.conf") + assert.Equal(t, "testdata/data1/test-empty.conf", v) + assert.Nil(t, err) + + v, err = m.Find("test.conf") + assert.Equal(t, "testdata/data1/test.conf", v) + assert.Nil(t, err) +} + +func TestIsNotFound(t *testing.T) { + assert.True(t, IsNotFound(ErrNotFound{})) + assert.False(t, IsNotFound(errors.New(""))) +} + +func TestMultiPath_FindFiles(t *testing.T) { + m := New("path1", "testdata/data2", "testdata/data1") + + files, err := m.FindFiles(".conf") + assert.NoError(t, err) + assert.Equal(t, []string{"testdata/data2/test-empty.conf", "testdata/data2/test.conf"}, files) + + files, err = m.FindFiles() + assert.NoError(t, err) + assert.Equal(t, []string{"testdata/data2/test-empty.conf", "testdata/data2/test.conf"}, files) + + files, err = m.FindFiles(".not_exist") + assert.NoError(t, err) + assert.Equal(t, []string(nil), files) + + m = New("path1", "testdata/data1", "testdata/data2") + files, err = m.FindFiles(".conf") + assert.NoError(t, err) + assert.Equal(t, []string{"testdata/data1/test-empty.conf", "testdata/data1/test.conf"}, files) +} diff --git a/src/go/plugin/go.d/pkg/multipath/testdata/data1/test-empty.conf b/src/go/plugin/go.d/pkg/multipath/testdata/data1/test-empty.conf new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/go/plugin/go.d/pkg/multipath/testdata/data1/test-empty.conf diff --git a/src/go/plugin/go.d/pkg/multipath/testdata/data1/test.conf b/src/go/plugin/go.d/pkg/multipath/testdata/data1/test.conf new file mode 100644 index 00000000..aebe6473 --- /dev/null +++ b/src/go/plugin/go.d/pkg/multipath/testdata/data1/test.conf @@ -0,0 +1 @@ +not empty!
\ No newline at end of file diff --git a/src/go/plugin/go.d/pkg/multipath/testdata/data2/test-empty.conf b/src/go/plugin/go.d/pkg/multipath/testdata/data2/test-empty.conf new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/go/plugin/go.d/pkg/multipath/testdata/data2/test-empty.conf diff --git a/src/go/plugin/go.d/pkg/multipath/testdata/data2/test.conf b/src/go/plugin/go.d/pkg/multipath/testdata/data2/test.conf new file mode 100644 index 00000000..aebe6473 --- /dev/null +++ b/src/go/plugin/go.d/pkg/multipath/testdata/data2/test.conf @@ -0,0 +1 @@ +not empty!
\ No newline at end of file |