summaryrefslogtreecommitdiffstats
path: root/src/go/plugin/go.d/pkg/multipath
diff options
context:
space:
mode:
Diffstat (limited to 'src/go/plugin/go.d/pkg/multipath')
-rw-r--r--src/go/plugin/go.d/pkg/multipath/multipath.go90
-rw-r--r--src/go/plugin/go.d/pkg/multipath/multipath_test.go60
-rw-r--r--src/go/plugin/go.d/pkg/multipath/testdata/data1/test-empty.conf0
-rw-r--r--src/go/plugin/go.d/pkg/multipath/testdata/data1/test.conf1
-rw-r--r--src/go/plugin/go.d/pkg/multipath/testdata/data2/test-empty.conf0
-rw-r--r--src/go/plugin/go.d/pkg/multipath/testdata/data2/test.conf1
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