diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-07-02 16:08:04 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-07-02 16:08:04 +0200 |
| commit | eb1cda04f372c32e5e0765783fad09429138408c (patch) | |
| tree | 57de9bf53dbf62b9897b8198fac8f41158ab7142 /pkg | |
| parent | 233bc790fcdf4bc657a5949bd63d0a9db019cf42 (diff) | |
pkg/email: add function that forms reply to an email
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/email/parser.go | 4 | ||||
| -rw-r--r-- | pkg/email/reply.go | 42 | ||||
| -rw-r--r-- | pkg/email/reply_test.go | 87 |
3 files changed, 132 insertions, 1 deletions
diff --git a/pkg/email/parser.go b/pkg/email/parser.go index 42a890472..a764a5826 100644 --- a/pkg/email/parser.go +++ b/pkg/email/parser.go @@ -27,6 +27,8 @@ type Email struct { CommandArgs []string // arguments for the command } +const commandPrefix = "#syzbot " + func Parse(r io.Reader, ownEmail string) (*Email, error) { msg, err := mail.ReadMessage(r) if err != nil { @@ -112,7 +114,7 @@ func extractBugID(from, canonical string) string { // Commands are of the following form: // ^#syzbot cmd args... func extractCommand(body []byte) (cmd string, args []string) { - cmdPos := bytes.Index(append([]byte{'\n'}, body...), []byte("\n#syzbot ")) + cmdPos := bytes.Index(append([]byte{'\n'}, body...), []byte("\n"+commandPrefix)) if cmdPos == -1 { return } diff --git a/pkg/email/reply.go b/pkg/email/reply.go new file mode 100644 index 000000000..65aec4509 --- /dev/null +++ b/pkg/email/reply.go @@ -0,0 +1,42 @@ +// Copyright 2017 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package email + +import ( + "bufio" + "bytes" + "strings" +) + +func FormReply(email, reply string) string { + s := bufio.NewScanner(strings.NewReader(email)) + out := new(bytes.Buffer) + replied := false + for s.Scan() { + ln := s.Bytes() + out.WriteByte('>') + if len(ln) != 0 && ln[0] != '>' { + out.WriteByte(' ') + } + out.Write(ln) + out.WriteByte('\n') + if !replied && bytes.HasPrefix(ln, []byte(commandPrefix)) { + replied = true + writeReply(out, reply) + } + } + if !replied { + writeReply(out, reply) + } + return out.String() +} + +func writeReply(out *bytes.Buffer, reply string) { + out.WriteByte('\n') + out.WriteString(reply) + if reply != "" && reply[len(reply)-1] != '\n' { + out.WriteByte('\n') + } + out.WriteByte('\n') +} diff --git a/pkg/email/reply_test.go b/pkg/email/reply_test.go new file mode 100644 index 000000000..2dd9d894d --- /dev/null +++ b/pkg/email/reply_test.go @@ -0,0 +1,87 @@ +// Copyright 2017 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package email + +import ( + "fmt" + "testing" +) + +func TestFormReply(t *testing.T) { + for i, test := range formReplyTests { + t.Run(fmt.Sprint(i), func(t *testing.T) { + result := FormReply(test.email, test.reply) + if test.result != result { + t.Logf("expect:\n%s", test.result) + t.Logf("got:\n%s", result) + t.Fail() + } + }) + } +} + +var formReplyTests = []struct { + email string + reply string + result string +}{ + { + email: `line1 +line2 +#syzbot foo +line3 +`, + reply: "this is reply", + result: `> line1 +> line2 +> #syzbot foo + +this is reply + +> line3 +`, + }, + { + email: `> line1 +> line2 +#syzbot foo +line3 +`, + reply: "this is reply\n", + result: `>> line1 +>> line2 +> #syzbot foo + +this is reply + +> line3 +`, + }, + { + email: `line1 +line2 +#syzbot foo`, + reply: "this is reply 1\nthis is reply 2", + result: `> line1 +> line2 +> #syzbot foo + +this is reply 1 +this is reply 2 + +`, + }, + { + email: `line1 +line2 +`, + reply: "this is reply", + result: `> line1 +> line2 + +this is reply + +`, + }, +} |
