Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
.envrc
/cmdg
/med
/conductor/
13 changes: 6 additions & 7 deletions cmd/cmdg/cmdg.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,10 @@
verbose = flag.Bool("verbose", false, "Turn on verbose logging.")
shell = flag.String("shell", "/bin/sh", "Shell to shell out to.")
versionFlag = flag.Bool("version", false, "Show version and exit.")
lynx = flag.String("lynx", "lynx", "HTML render binary.")
enableSign = flag.Bool("sign", false, "Send signed emails by default.")
imageProtocol = flag.String("image_protocol", "none", "Terminal image protocol (none, kitty, iterm2, auto).")

updateSender = flag.String("update_sender", "", `Update default sender address. E.g.: "John Doe" <john.doe@example.com>`)

conn *cmdg.CmdG

// Relative to configDir.
Expand Down Expand Up @@ -133,6 +132,9 @@
log.Errorf("Bailing due to error: %v", err)
}
log.Infof("MessageView returned, stopping keys")
if *imageProtocol != "none" {
cmdg.ClearImages(*imageProtocol)
}
keys.Stop()
log.Infof("Shutting down")
return nil
Expand All @@ -146,8 +148,7 @@
syscall.Umask(0077)
flag.Parse()
cmdg.Version = version

cmdg.Lynx = *lynx
cmdg.PreferredImageProtocol = *imageProtocol

log.Infof("cmdg %s", version)

Expand Down Expand Up @@ -281,9 +282,7 @@
if err != nil {
log.Fatalf("Can't create logfile %q: %v", *logFile, err)
}
defer func() {
_ = f.Close()
}()
defer f.Close()

Check failure on line 285 in cmd/cmdg/cmdg.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `f.Close` is not checked (errcheck)
log.SetOutput(f)
if *logJSON {
log.SetFormatter(&log.JSONFormatter{})
Expand Down
23 changes: 7 additions & 16 deletions cmd/cmdg/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
}
}()
if _, err := tmpf.Write([]byte(prefill)); err != nil {
_ = tmpf.Close()
tmpf.Close()

Check failure on line 44 in cmd/cmdg/compose.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `tmpf.Close` is not checked (errcheck)
return "", errors.Wrapf(err, "prefilling compose file %q with %d bytes", tmpf.Name(), len(prefill))
}
if err := tmpf.Close(); err != nil {
Expand All @@ -50,11 +50,7 @@

// Stop UI.
keys.Stop()
defer func() {
if err := keys.Start(); err != nil {
log.Errorf("Failed to restart input: %v", err)
}
}()
defer keys.Start()

Check failure on line 53 in cmd/cmdg/compose.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `keys.Start` is not checked (errcheck)

cmd := exec.CommandContext(ctx, visualBinary, tmpf.Name())
cmd.Stdin = os.Stdin
Expand Down Expand Up @@ -255,7 +251,7 @@
return errors.Wrapf(err, "couldn't open local file")
}
if _, err := f.Write([]byte(msg)); err != nil {
_ = f.Close()
f.Close()

Check failure on line 254 in cmd/cmdg/compose.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `f.Close` is not checked (errcheck)
return errors.Wrapf(err, "couldn't write to local file")
}
if err := f.Close(); err != nil {
Expand All @@ -272,11 +268,9 @@
break
}
}
/*
if a == "S" {
// TODO: also archive.
}
*/
if a == "S" {
// TODO: also archive.
}
return nil
case "d":
st := time.Now()
Expand All @@ -293,7 +287,7 @@
break
}
if err != nil {
_ = dialog.Message("Failed to attach", fmt.Sprintf("Failed to attach file: %v", err), keys)
dialog.Message("Failed to attach", fmt.Sprintf("Failed to attach file: %v", err), keys)

Check failure on line 290 in cmd/cmdg/compose.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `dialog.Message` is not checked (errcheck)
}
doEdit = false
attachments = append(attachments, f)
Expand Down Expand Up @@ -369,9 +363,6 @@
full := path.Join(startDir, fis[o.KeyInt].Name())
// TODO: attach a ReadCloser?
b, err := ioutil.ReadFile(full)
if err != nil {
return nil, err
}
return &file{
name: fis[o.KeyInt].Name(),
content: b,
Expand Down
40 changes: 33 additions & 7 deletions cmd/cmdg/compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@

func (fs *fakeSend) bad(w http.ResponseWriter, f string, args ...interface{}) {
w.WriteHeader(http.StatusBadRequest)
if _, err := fmt.Fprintf(w, f, args...); err != nil {
fs.bad(w, "writing response failed: %v", err)
}
fmt.Fprintf(w, f, args...)

Check failure on line 26 in cmd/cmdg/compose_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `fmt.Fprintf` is not checked (errcheck)
}

func (fs *fakeSend) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -61,9 +59,7 @@
}
fs.msg = string(raw)
w.WriteHeader(http.StatusOK)
if _, err := fmt.Fprintf(w, `{ "id": "12345" }`); err != nil {
fs.bad(w, "failed to write reply: %v", err)
}
fmt.Fprintf(w, `{ "id": "12345" }`)
}

// net.RoundTripper that rewrites requests to the local fake.
Expand All @@ -84,7 +80,7 @@
}

func crnl(s string) string {
return strings.ReplaceAll(s, "\n", "\r\n")
return strings.Replace(s, "\n", "\r\n", -1)
}

func TestSendMessage(t *testing.T) {
Expand Down Expand Up @@ -208,6 +204,36 @@
Content-Type: text/plain; charset="UTF-8"

World
--[a-z0-9]+--`)),
},
{
name: "With attachments",
msg: "To: foo@bar.com\nSubject: hello\n\nWorld",
attachments: []*file{
{name: "test1.txt", content: []byte("content1")},
{name: "test2.txt", content: []byte("content2")},
},
matching: regexp.MustCompile(crnl(`MIME-Version: 1.0
Subject: hello
To: foo@bar.com
Content-Type: multipart/mixed; boundary="[a-z0-9]+"
Content-Disposition: inline

--[a-z0-9]+
Content-Disposition: inline
Content-Type: text/plain; charset="UTF-8"

World
--[a-z0-9]+
Content-Disposition: attachment; filename="test1.txt"
Content-Type: application/octet-stream; name="test1.txt"

content1
--[a-z0-9]+
Content-Disposition: attachment; filename="test2.txt"
Content-Type: application/octet-stream; name="test2.txt"

content2
--[a-z0-9]+--`)),
},
}
Expand Down
1 change: 0 additions & 1 deletion cmd/cmdg/reply.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ func replyOrForward(ctx context.Context, conn *cmdg.CmdG, keys *input.Input, to,
refs, err := msg.GetReferences(ctx)
if err != nil {
// don't care
_ = err
}

headOps := []headOp{
Expand Down
17 changes: 4 additions & 13 deletions cmd/cmdg/reply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"net/url"
Expand All @@ -28,15 +27,11 @@
var d struct {
Raw string `json:"raw"`
}
if err := json.Unmarshal(content, &d); err != nil {
log.Fatalf("Failed to marshal: %v", err)
}
json.Unmarshal(content, &d)

Check failure on line 30 in cmd/cmdg/reply_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `json.Unmarshal` is not checked (errcheck)
raw, _ := base64.URLEncoding.DecodeString(d.Raw)
h.sentMsg = string(raw)
w.WriteHeader(http.StatusOK)
if _, err := fmt.Fprint(w, `{"id": "sent-123"}`); err != nil {
log.Fatalf("Failed to write reply: %v", err)
}
fmt.Fprint(w, `{"id": "sent-123"}`)

Check failure on line 34 in cmd/cmdg/reply_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `fmt.Fprint` is not checked (errcheck)
return
}
if r.Method == "GET" && strings.Contains(r.URL.Path, "/messages/msg-123") && !strings.Contains(r.URL.Path, "/attachments") {
Expand All @@ -63,18 +58,14 @@
},
},
}
if err := json.NewEncoder(w).Encode(msg); err != nil {
log.Fatalf("Failed to encode: %v", err)
}
json.NewEncoder(w).Encode(msg)

Check failure on line 61 in cmd/cmdg/reply_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `(*encoding/json.Encoder).Encode` is not checked (errcheck)
return
}
if r.Method == "GET" && strings.Contains(r.URL.Path, "/attachments/att-123") {
att := &gmail.MessagePartBody{
Data: base64.URLEncoding.EncodeToString([]byte("attachment content")),
}
if err := json.NewEncoder(w).Encode(att); err != nil {
log.Fatalf("Failed to encode: %v", err)
}
json.NewEncoder(w).Encode(att)

Check failure on line 68 in cmd/cmdg/reply_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `(*encoding/json.Encoder).Encode` is not checked (errcheck)
return
}
w.WriteHeader(http.StatusNotFound)
Expand Down
2 changes: 1 addition & 1 deletion cmd/cmdg/view_attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func listAttachments(ctx context.Context, keys *input.Input, msg *cmdg.Message)
if err != nil {
return err
}
ass := make([]string, len(as))
ass := make([]string, len(as), len(as))
for n, a := range as {
ass[n] = a.Part.Filename
}
Expand Down
6 changes: 2 additions & 4 deletions cmd/cmdg/view_messagelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Press [enter] to exit
)

var (
//messageListReloadTime = time.Minute
messageListReloadTime = time.Minute
messageListReloadTimeout = 40 * time.Second
messageListHistoryCheckTime = 10 * time.Second
messageListHistoryCheckTimeout = 10 * time.Second
Expand Down Expand Up @@ -712,9 +712,7 @@ func (mv *MessageView) Run(ctx context.Context) error {
log.Debugf("MessageListView got key %q", key)
switch key {
case "?", input.F1:
if err := help(messageListViewHelp, mv.keys); err != nil {
log.Infof("help() failed: %v", err)
}
help(messageListViewHelp, mv.keys)
case input.Enter, input.Right:
if len(mv.messages) == 0 {
// Let's assume we've never gotten to the state where mv.pos >= len(mv.messages)
Expand Down
Loading
Loading