From 1ae358d6224242c38905443836dfb891de4ea7be Mon Sep 17 00:00:00 2001 From: hedhyw Date: Sun, 2 Jun 2024 15:26:59 +0200 Subject: [PATCH 1/4] fix: stdin pipe --- cmd/jlv/main.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/jlv/main.go b/cmd/jlv/main.go index 9fee1a9..14595f2 100644 --- a/cmd/jlv/main.go +++ b/cmd/jlv/main.go @@ -4,6 +4,7 @@ import ( "bytes" "flag" "fmt" + "io/fs" "os" "path" @@ -42,7 +43,7 @@ func main() { switch flag.NArg() { case 0: - sourceInput, err = getStdinSource(cfg) + sourceInput, err = getStdinSource(cfg, os.Stdin) if err != nil { fatalf("Stdin: %s\n", err) } @@ -60,17 +61,17 @@ func main() { } } -func getStdinSource(cfg *config.Config) (source.Input, error) { - stat, err := os.Stdin.Stat() +func getStdinSource(cfg *config.Config, defaultInput fs.File) (source.Input, error) { + stat, err := defaultInput.Stat() if err != nil { return nil, fmt.Errorf("stat: %w", err) } - if stat.Mode()&os.ModeNamedPipe == 0 { + if stat.Mode()&os.ModeCharDevice != 0 { return readerinput.New(bytes.NewReader(nil), cfg.StdinReadTimeout), nil } - return readerinput.New(os.Stdin, cfg.StdinReadTimeout), nil + return readerinput.New(defaultInput, cfg.StdinReadTimeout), nil } func fatalf(message string, args ...any) { From 5a8f8a8ad4bb5fe1a544ee0b0bd0c36a3f055161 Mon Sep 17 00:00:00 2001 From: hedhyw Date: Sun, 2 Jun 2024 15:27:14 +0200 Subject: [PATCH 2/4] test: add TestGetStdinSource --- cmd/jlv/main_test.go | 105 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 cmd/jlv/main_test.go diff --git a/cmd/jlv/main_test.go b/cmd/jlv/main_test.go new file mode 100644 index 0000000..98d4837 --- /dev/null +++ b/cmd/jlv/main_test.go @@ -0,0 +1,105 @@ +package main + +import ( + "bytes" + "context" + "errors" + "io" + "io/fs" + "os" + "testing" + + "github.com/hedhyw/json-log-viewer/internal/pkg/config" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetStdinSource(t *testing.T) { + t.Parallel() + + ctx := context.Background() + + t.Run("ModeNamedPipe", func(t *testing.T) { + t.Parallel() + + content := t.Name() + "\n" + + file := fakeFile{ + Reader: bytes.NewReader([]byte(content)), + StatFileInfo: fakeFileInfo{ + FileMode: os.ModeNamedPipe, + }, + } + + input, err := getStdinSource(config.GetDefaultConfig(), file) + require.NoError(t, err) + + readCloser, err := input.ReadCloser(ctx) + require.NoError(t, err) + + t.Cleanup(func() { assert.NoError(t, readCloser.Close()) }) + + data, err := io.ReadAll(readCloser) + require.NoError(t, err) + assert.Equal(t, content, string(data)) + }) + + t.Run("ModeCharDevice", func(t *testing.T) { + t.Parallel() + + file := fakeFile{ + Reader: bytes.NewReader([]byte(t.Name() + "\n")), + StatFileInfo: fakeFileInfo{ + FileMode: os.ModeCharDevice, + }, + } + + input, err := getStdinSource(config.GetDefaultConfig(), file) + require.NoError(t, err) + + readCloser, err := input.ReadCloser(ctx) + require.NoError(t, err) + + t.Cleanup(func() { assert.NoError(t, readCloser.Close()) }) + + data, err := io.ReadAll(readCloser) + require.NoError(t, err) + assert.Empty(t, data) + }) + + t.Run("Stat_error", func(t *testing.T) { + t.Parallel() + + errStat := errors.New(t.Name()) + + file := fakeFile{ErrStat: errStat} + + _, err := getStdinSource(config.GetDefaultConfig(), file) + require.Error(t, err) + require.ErrorIs(t, err, errStat) + }) +} + +type fakeFile struct { + io.Closer + io.Reader + + StatFileInfo os.FileInfo + ErrStat error +} + +// Stat implements fs.File. +func (f fakeFile) Stat() (os.FileInfo, error) { + return f.StatFileInfo, f.ErrStat +} + +type fakeFileInfo struct { + fs.FileInfo + FileMode fs.FileMode +} + +// Mode implements fs.FileInfo +func (f fakeFileInfo) Mode() fs.FileMode { + return f.FileMode +} From b680be2192b1595ac000c49d8bffcf829550800b Mon Sep 17 00:00:00 2001 From: hedhyw Date: Sun, 2 Jun 2024 15:28:16 +0200 Subject: [PATCH 3/4] fix: linter --- cmd/jlv/main_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/jlv/main_test.go b/cmd/jlv/main_test.go index 98d4837..5104a07 100644 --- a/cmd/jlv/main_test.go +++ b/cmd/jlv/main_test.go @@ -71,6 +71,7 @@ func TestGetStdinSource(t *testing.T) { t.Run("Stat_error", func(t *testing.T) { t.Parallel() + // nolint: err113 // Test. errStat := errors.New(t.Name()) file := fakeFile{ErrStat: errStat} @@ -99,7 +100,7 @@ type fakeFileInfo struct { FileMode fs.FileMode } -// Mode implements fs.FileInfo +// Mode implements fs.FileInfo. func (f fakeFileInfo) Mode() fs.FileMode { return f.FileMode } From 7229d491544402163e8ea1291abdcb9b42eb5b2b Mon Sep 17 00:00:00 2001 From: hedhyw Date: Sun, 2 Jun 2024 15:33:03 +0200 Subject: [PATCH 4/4] docs: update docker logs command example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 95b8003..8180212 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ jlv << EOF EOF kubectl logs pod/POD_NAME -f | jlv -docker logs 000000000000 | jlv +docker logs -f 000000000000 2>&1 | jlv ``` ### Hotkeys