Skip to content

Commit a781d18

Browse files
authored
fix(#77): stdin redirect (#78)
1 parent 041a4d6 commit a781d18

File tree

3 files changed

+113
-6
lines changed

3 files changed

+113
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jlv << EOF
7070
EOF
7171

7272
kubectl logs pod/POD_NAME -f | jlv
73-
docker logs 000000000000 | jlv
73+
docker logs -f 000000000000 2>&1 | jlv
7474
```
7575

7676
### Hotkeys

cmd/jlv/main.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"flag"
66
"fmt"
7+
"io/fs"
78
"os"
89
"path"
910

@@ -42,7 +43,7 @@ func main() {
4243

4344
switch flag.NArg() {
4445
case 0:
45-
sourceInput, err = getStdinSource(cfg)
46+
sourceInput, err = getStdinSource(cfg, os.Stdin)
4647
if err != nil {
4748
fatalf("Stdin: %s\n", err)
4849
}
@@ -60,17 +61,17 @@ func main() {
6061
}
6162
}
6263

63-
func getStdinSource(cfg *config.Config) (source.Input, error) {
64-
stat, err := os.Stdin.Stat()
64+
func getStdinSource(cfg *config.Config, defaultInput fs.File) (source.Input, error) {
65+
stat, err := defaultInput.Stat()
6566
if err != nil {
6667
return nil, fmt.Errorf("stat: %w", err)
6768
}
6869

69-
if stat.Mode()&os.ModeNamedPipe == 0 {
70+
if stat.Mode()&os.ModeCharDevice != 0 {
7071
return readerinput.New(bytes.NewReader(nil), cfg.StdinReadTimeout), nil
7172
}
7273

73-
return readerinput.New(os.Stdin, cfg.StdinReadTimeout), nil
74+
return readerinput.New(defaultInput, cfg.StdinReadTimeout), nil
7475
}
7576

7677
func fatalf(message string, args ...any) {

cmd/jlv/main_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"errors"
7+
"io"
8+
"io/fs"
9+
"os"
10+
"testing"
11+
12+
"github.com/hedhyw/json-log-viewer/internal/pkg/config"
13+
14+
"github.com/stretchr/testify/assert"
15+
"github.com/stretchr/testify/require"
16+
)
17+
18+
func TestGetStdinSource(t *testing.T) {
19+
t.Parallel()
20+
21+
ctx := context.Background()
22+
23+
t.Run("ModeNamedPipe", func(t *testing.T) {
24+
t.Parallel()
25+
26+
content := t.Name() + "\n"
27+
28+
file := fakeFile{
29+
Reader: bytes.NewReader([]byte(content)),
30+
StatFileInfo: fakeFileInfo{
31+
FileMode: os.ModeNamedPipe,
32+
},
33+
}
34+
35+
input, err := getStdinSource(config.GetDefaultConfig(), file)
36+
require.NoError(t, err)
37+
38+
readCloser, err := input.ReadCloser(ctx)
39+
require.NoError(t, err)
40+
41+
t.Cleanup(func() { assert.NoError(t, readCloser.Close()) })
42+
43+
data, err := io.ReadAll(readCloser)
44+
require.NoError(t, err)
45+
assert.Equal(t, content, string(data))
46+
})
47+
48+
t.Run("ModeCharDevice", func(t *testing.T) {
49+
t.Parallel()
50+
51+
file := fakeFile{
52+
Reader: bytes.NewReader([]byte(t.Name() + "\n")),
53+
StatFileInfo: fakeFileInfo{
54+
FileMode: os.ModeCharDevice,
55+
},
56+
}
57+
58+
input, err := getStdinSource(config.GetDefaultConfig(), file)
59+
require.NoError(t, err)
60+
61+
readCloser, err := input.ReadCloser(ctx)
62+
require.NoError(t, err)
63+
64+
t.Cleanup(func() { assert.NoError(t, readCloser.Close()) })
65+
66+
data, err := io.ReadAll(readCloser)
67+
require.NoError(t, err)
68+
assert.Empty(t, data)
69+
})
70+
71+
t.Run("Stat_error", func(t *testing.T) {
72+
t.Parallel()
73+
74+
// nolint: err113 // Test.
75+
errStat := errors.New(t.Name())
76+
77+
file := fakeFile{ErrStat: errStat}
78+
79+
_, err := getStdinSource(config.GetDefaultConfig(), file)
80+
require.Error(t, err)
81+
require.ErrorIs(t, err, errStat)
82+
})
83+
}
84+
85+
type fakeFile struct {
86+
io.Closer
87+
io.Reader
88+
89+
StatFileInfo os.FileInfo
90+
ErrStat error
91+
}
92+
93+
// Stat implements fs.File.
94+
func (f fakeFile) Stat() (os.FileInfo, error) {
95+
return f.StatFileInfo, f.ErrStat
96+
}
97+
98+
type fakeFileInfo struct {
99+
fs.FileInfo
100+
FileMode fs.FileMode
101+
}
102+
103+
// Mode implements fs.FileInfo.
104+
func (f fakeFileInfo) Mode() fs.FileMode {
105+
return f.FileMode
106+
}

0 commit comments

Comments
 (0)