Skip to content

Commit fca4b2c

Browse files
Apply suggestions
Signed-off-by: eternal-flame-AD <[email protected]>
1 parent a0550b1 commit fca4b2c

File tree

4 files changed

+87
-71
lines changed

4 files changed

+87
-71
lines changed

command/push.go

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,8 @@ func Push() cli.Command {
3939
func doPush(ctx *cli.Context) {
4040
conf, confErr := config.ReadConfig(config.GetLocations())
4141

42-
msgText := make(chan string)
43-
null := '\x00'
44-
if ctx.Bool("no-split") {
45-
go readMessage(ctx.Args(), os.Stdin, msgText, nil)
46-
} else {
47-
go readMessage(ctx.Args(), os.Stdin, msgText, &null)
48-
}
42+
msgTextChan := make(chan string)
43+
go readMessage(ctx.Args(), os.Stdin, msgTextChan, !ctx.Bool("no-split"))
4944

5045
priority := ctx.Int("priority")
5146
title := ctx.String("title")
@@ -81,8 +76,24 @@ func doPush(ctx *cli.Context) {
8176
return
8277
}
8378

79+
parsedExtras := make(map[string]interface{})
80+
81+
if contentType != "" {
82+
parsedExtras["client::display"] = map[string]interface{}{
83+
"contentType": contentType,
84+
}
85+
}
86+
87+
if clickUrl != "" {
88+
parsedExtras["client::notification"] = map[string]interface{}{
89+
"click": map[string]string{
90+
"url": clickUrl,
91+
},
92+
}
93+
}
94+
8495
var sent bool
85-
for msgText := range msgText {
96+
for msgText := range msgTextChan {
8697
if !ctx.Bool("disable-unescape-backslash") {
8798
msgText = utils.Evaluate(msgText)
8899
}
@@ -91,22 +102,7 @@ func doPush(ctx *cli.Context) {
91102
Message: msgText,
92103
Title: title,
93104
Priority: priority,
94-
}
95-
96-
msg.Extras = map[string]interface{}{}
97-
98-
if contentType != "" {
99-
msg.Extras["client::display"] = map[string]interface{}{
100-
"contentType": contentType,
101-
}
102-
}
103-
104-
if clickUrl != "" {
105-
msg.Extras["client::notification"] = map[string]interface{}{
106-
"click": map[string]string{
107-
"url": clickUrl,
108-
},
109-
}
105+
Extras: parsedExtras,
110106
}
111107

112108
pushMessage(parsedURL, token, msg, quiet)

command/read.go

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,49 @@
11
package command
22

33
import (
4+
"bufio"
5+
"errors"
46
"io"
57
"strings"
68

79
"github.com/gotify/cli/v2/utils"
810
)
911

10-
func readMessage(args []string, r io.Reader, output chan<- string, split *rune) {
11-
msgArgs := strings.Join(args, " ")
12+
func readMessage(args []string, r io.Reader, output chan<- string, splitOnNull bool) {
13+
defer close(output)
1214

13-
if msgArgs != "" {
15+
switch {
16+
case len(args) > 0:
1417
if utils.ProbeStdin(r) {
1518
utils.Exit1With("message is set via arguments and stdin, use only one of them")
1619
}
1720

18-
output <- msgArgs
19-
close(output)
20-
return
21-
}
22-
23-
var buf strings.Builder
24-
for {
25-
var tmp [256]byte
26-
n, err := r.Read(tmp[:])
27-
if err != nil {
28-
if err.Error() == "EOF" {
29-
break
21+
output <- strings.Join(args, " ")
22+
case splitOnNull:
23+
read := bufio.NewReader(r)
24+
for {
25+
s, err := read.ReadString('\x00')
26+
if err != nil {
27+
if !errors.Is(err, io.EOF) {
28+
utils.Exit1With("read error", err)
29+
}
30+
if len(s) > 0 {
31+
output <- s
32+
}
33+
return
34+
} else {
35+
if len(s) > 1 {
36+
output <- strings.TrimSuffix(s, "\x00")
37+
}
3038
}
31-
utils.Exit1With(err)
3239
}
33-
tmpStr := string(tmp[:n])
34-
if split != nil {
35-
// split the message on the null character
36-
parts := strings.Split(tmpStr, string(*split))
37-
if len(parts) == 1 {
38-
buf.WriteString(parts[0])
39-
continue
40-
}
41-
42-
previous := buf.String()
43-
// fuse previous with parts[0], send parts[1] .. parts[n-2] and set parts[n-1] as new previous
44-
firstMsg := previous + parts[0]
45-
output <- firstMsg
46-
for _, part := range parts[1 : len(parts)-1] {
47-
output <- part
48-
}
49-
buf.Reset()
50-
buf.WriteString(parts[len(parts)-1])
51-
} else {
52-
buf.WriteString(tmpStr)
40+
default:
41+
bytes, err := io.ReadAll(r)
42+
if err != nil {
43+
utils.Exit1With("cannot read", err)
5344
}
45+
output <- string(bytes)
46+
return
5447
}
5548

56-
if buf.Len() > 0 {
57-
output <- buf.String()
58-
}
59-
60-
close(output)
6149
}

command/read_test.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package command
22

33
import (
4+
"bufio"
5+
"bytes"
46
"strings"
57
"testing"
68
)
@@ -27,29 +29,59 @@ func readChanAll[T any](c chan T) []T {
2729
}
2830

2931
func TestReadMessage(t *testing.T) {
30-
var split rune = '\x00'
31-
32+
if bytes.IndexByte([]byte("Hello\x00World"), '\x00') != len("Hello") {
33+
t.Errorf("Expected %v, but got %v", len("Hello"), bytes.IndexByte([]byte("Hello\x00World"), '\x00'))
34+
}
35+
rdr := bufio.NewReader(strings.NewReader("Hello\x00World"))
36+
if s, _ := rdr.ReadString('\x00'); s != "Hello\x00" {
37+
t.Errorf("Expected %x, but got %x", "Hello\x00", s)
38+
}
3239
// Test case 1: message set via arguments
3340
output := make(chan string)
34-
go readMessage([]string{"Hello", "World"}, nil, output, nil)
41+
go readMessage([]string{"Hello", "World"}, nil, output, false)
3542

3643
if res := readChanAll(output); !(slicesEqual(res, []string{"Hello World"})) {
3744
t.Errorf("Expected %v, but got %v", []string{"Hello World"}, res)
3845
}
3946

4047
// Test case 2: message set via arguments should not split on 'split' character
4148
output = make(chan string)
42-
go readMessage([]string{"Hello\x00World"}, nil, output, &split)
49+
go readMessage([]string{"Hello\x00World"}, nil, output, true)
4350

4451
if res := readChanAll(output); !(slicesEqual(res, []string{"Hello\x00World"})) {
4552
t.Errorf("Expected %v, but got %v", []string{"Hello\x00World"}, res)
4653
}
4754

4855
// Test case 3: message set via stdin
4956
output = make(chan string)
50-
go readMessage([]string{}, strings.NewReader("Hello\x00World"), output, &split)
57+
go readMessage([]string{}, strings.NewReader("Hello\x00World"), output, true)
58+
59+
if res := readChanAll(output); !(slicesEqual(res, []string{"Hello", "World"})) {
60+
t.Errorf("Expected %v, but got %v", []string{"Hello", "World"}, res)
61+
}
62+
63+
// Test case 4: multiple null bytes should be split as one
64+
output = make(chan string)
65+
go readMessage([]string{}, strings.NewReader("Hello\x00\x00World"), output, true)
5166

5267
if res := readChanAll(output); !(slicesEqual(res, []string{"Hello", "World"})) {
5368
t.Errorf("Expected %v, but got %v", []string{"Hello", "World"}, res)
5469
}
70+
71+
// Test case 5: multiple null bytes at the end should be split as one
72+
output = make(chan string)
73+
go readMessage([]string{}, strings.NewReader("Hello\x00\x00"), output, true)
74+
75+
if res := readChanAll(output); !(slicesEqual(res, []string{"Hello"})) {
76+
t.Errorf("Expected %v, but got %v", []string{"Hello"}, res)
77+
}
78+
79+
// Test case 6: multiple null bytes at the start should be split as one
80+
output = make(chan string)
81+
go readMessage([]string{}, strings.NewReader("\x00\x00World"), output, true)
82+
83+
if res := readChanAll(output); !(slicesEqual(res, []string{"World"})) {
84+
t.Errorf("Expected %v, but got %v", []string{"World"}, res)
85+
}
86+
5587
}

command/watch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func doWatch(ctx *cli.Context) {
131131
fmt.Fprintln(msgData, output)
132132
fmt.Fprintln(msgData, "== END NEW OUTPUT ==")
133133
case "short":
134-
fmt.Fprintln(msgData, output)
134+
fmt.Fprint(msgData, output)
135135
}
136136

137137
msgString := msgData.String()

0 commit comments

Comments
 (0)