Commit Diff


commit - 6de81a7b43fe19e0a9e9791192ffa8c723c0c4ad
commit + 0254f2be89712d6952cb4fdd5c8d0524b61e69ea
blob - d0a8e176313ba42944e5e951b7579bb96c551fa1
blob + 4d1e1db84b507a58115d0337db70d758bbdbda88
--- cmd/Jira/Jira.go
+++ cmd/Jira/Jira.go
@@ -111,7 +111,7 @@ func (w *awin) Execute(cmd string) bool {
 		query := strings.Join(fields[1:], " ")
 		go newSearch(w.fsys, query)
 		return true
-	case "Comment":
+	case "Comment", "New":
 		if len(fields) > 1 {
 			return false
 		}
@@ -122,15 +122,16 @@ func (w *awin) Execute(cmd string) bool {
 		}
 		dname := path.Dir(w.name())
 		win.Name(path.Join("/jira", dname, "new"))
-		win.Fprintf("tag", "Post ")
+		win.Fprintf("tag", "Put ")
 		a := &awin{win, w.fsys}
 		go a.EventLoop(a)
 		return true
-	case "Post":
-		if err := w.postComment(); err != nil {
-			w.Errf("post comment: %s", err.Error())
+	case "Put":
+		if err := w.put(); err != nil {
+			w.Errf(err.Error())
+		} else {
+			w.Del(true)
 		}
-		w.Del(true)
 		return true
 	}
 	return false
@@ -184,22 +185,6 @@ func (w *awin) Get(f fs.File) error {
 	return nil
 }
 
-func (w *awin) postComment() error {
-	defer w.Ctl("clean")
-	body, err := w.ReadAll("body")
-	if err != nil {
-		return fmt.Errorf("read body: %w", err)
-	}
-	f, ok := w.fsys.(*jira.FS)
-	if !ok {
-		return fmt.Errorf("cannot write comment with filesystem type %T", w.fsys)
-	}
-	elems := strings.Split(w.name(), "/")
-	ikey := fmt.Sprintf("%s-%s", elems[0], elems[1])
-	jtf := toJTF(string(body))
-	return f.Client.PostComment(ikey, strings.NewReader(jtf))
-}
-
 func newSearch(fsys fs.FS, query string) {
 	win, err := acme.New()
 	if err != nil {
blob - /dev/null
blob + 523255765024b9f0f9ea234cd25ea610ab786149 (mode 644)
--- /dev/null
+++ cmd/Jira/create.go
@@ -0,0 +1,71 @@
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/fs"
+	"net/mail"
+	"strings"
+
+	"olowe.co/issues/jira"
+)
+
+func (w *awin) put() error {
+	f, ok := w.fsys.(*jira.FS)
+	if !ok {
+		return fmt.Errorf("cannot write with filesystem type %T", w.fsys)
+	}
+
+	defer w.Ctl("clean")
+	body, err := w.ReadAll("body")
+	if err != nil {
+		return fmt.Errorf("read body: %w", err)
+	}
+
+	// are we creating an issue or a comment?
+	//	PROJECT/123/new
+	//	PROJECT/new
+	elems := strings.Split(w.name(), "/")
+	switch len(elems) {
+	case 3:
+		ikey := fmt.Sprintf("%s-%s", elems[0], elems[1])
+		jtf := toJTF(string(body))
+		return f.Client.PostComment(ikey, strings.NewReader(jtf))
+	case 2:
+		issue, err := readIssue(bytes.NewReader(body), elems[0])
+		if err != nil {
+			return fmt.Errorf("read issue: %w", err)
+		}
+		if _, err := f.Client.CreateIssue(*issue); err != nil {
+			return fmt.Errorf("create issue: %w", err)
+		}
+	}
+	return &fs.PathError{"write", w.name(), fs.ErrPermission}
+}
+
+func readIssue(rd io.Reader, project string) (*jira.Issue, error) {
+	msg, err := mail.ReadMessage(rd)
+	if err != nil {
+		return nil, err
+	}
+	typ := "Task"
+	if msg.Header.Get("Type") != "" {
+		typ = msg.Header.Get("Type")
+	}
+	issue := jira.Issue{
+		Summary: msg.Header.Get("Subject"),
+		Project: jira.Project{
+			Key: project,
+		},
+		Type: struct {
+			Name string `json:"name"`
+		}{typ},
+	}
+	body, err := io.ReadAll(msg.Body)
+	if err != nil {
+		return nil, fmt.Errorf("read issue body: %w", err)
+	}
+	issue.Description = string(bytes.TrimSpace(body))
+	return &issue, nil
+}