commit 0254f2be89712d6952cb4fdd5c8d0524b61e69ea from: Oliver Lowe date: Thu Jun 19 01:55:09 2025 UTC cmd/Jira: add issue creation using Put 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 +}