issues

Github, Jira, Gitlab issues from Plan 9's acme
Log | Files | Refs | README | LICENSE

commit 0254f2be89712d6952cb4fdd5c8d0524b61e69ea
parent 6de81a7b43fe19e0a9e9791192ffa8c723c0c4ad
Author: Oliver Lowe <o@olowe.co>
Date:   Thu, 19 Jun 2025 11:55:09 +1000

cmd/Jira: add issue creation using Put

Diffstat:
Mcmd/Jira/Jira.go | 29+++++++----------------------
Acmd/Jira/create.go | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 22 deletions(-)

diff --git a/cmd/Jira/Jira.go b/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 { diff --git a/cmd/Jira/create.go b/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 +}