From 6cc4f0b53c106fab6e23ce658727c96c4d75cb9c Mon Sep 17 00:00:00 2001 From: Roi Martin Date: Tue, 31 Dec 2019 01:16:22 +0100 Subject: [PATCH 1/2] issue: fix nil pointer dereference on plumb error plumbserve() fails with a nil pointer dereference when it tries to print errors via w.Err(). This happens because w is a dummy window with a nil *acme.Win. This commit replaces w.Err() calls in plumbserve() with acme.Errf(). It also extracts the plumbserve() method out of *awin, given that the previous change removes this dependency. Fixes issue #5. --- issue/acme.go | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/issue/acme.go b/issue/acme.go index 0254288..b812e42 100644 --- a/issue/acme.go +++ b/issue/acme.go @@ -14,6 +14,7 @@ import ( "fmt" "log" "os" + "path" "regexp" "strconv" "strings" @@ -25,9 +26,11 @@ import ( "github.com/google/go-github/github" ) +const root = "/issue/" + func (w *awin) project() string { p := w.prefix - p = strings.TrimPrefix(p, "/issue/") + p = strings.TrimPrefix(p, root) i := strings.Index(p, "/") if i >= 0 { j := strings.Index(p[i+1:], "/") @@ -40,7 +43,7 @@ func (w *awin) project() string { func acmeMode() { var dummy awin - dummy.prefix = "/issue/" + *project + "/" + dummy.prefix = path.Join(root, *project) + "/" if flag.NArg() > 0 { // TODO(rsc): Without -a flag, the query is conatenated into one query. // Decide which behavior should be used, and use it consistently. @@ -59,59 +62,59 @@ func acmeMode() { dummy.Look("all") } - go dummy.plumbserve() + go plumbserve() select {} } -func (w *awin) plumbserve() { +func plumbserve() { fid, err := plumb.Open("githubissue", 0) if err != nil { - w.Err(fmt.Sprintf("plumb: %v", err)) + acme.Errf(root, "plumb: %v", err) return } r := bufio.NewReader(fid) for { var m plumb.Message if err := m.Recv(r); err != nil { - w.Err(fmt.Sprintf("plumb recv: %v", err)) + acme.Errf(root, "plumb recv: %v", err) return } if m.Type != "text" { - w.Err(fmt.Sprintf("plumb recv: unexpected type: %s\n", m.Type)) + acme.Errf(root, "plumb recv: unexpected type: %s", m.Type) continue } if m.Dst != "githubissue" { - w.Err(fmt.Sprintf("plumb recv: unexpected dst: %s\n", m.Dst)) + acme.Errf(root, "plumb recv: unexpected dst: %s", m.Dst) continue } // TODO use m.Dir data := string(m.Data) var project, what string - if strings.HasPrefix(data, "/issue/") { - project = data[len("/issue/"):] + if strings.HasPrefix(data, root) { + project = data[len(root):] i := strings.LastIndex(project, "/") if i < 0 { - w.Err(fmt.Sprintf("plumb recv: bad text %q", data)) + acme.Errf(root, "plumb recv: bad text %q", data) continue } project, what = project[:i], project[i+1:] } else { i := strings.Index(data, "#") if i < 0 { - w.Err(fmt.Sprintf("plumb recv: bad text %q", data)) + acme.Errf(root, "plumb recv: bad text %q", data) continue } project, what = data[:i], data[i+1:] } if strings.Count(project, "/") != 1 { - w.Err(fmt.Sprintf("plumb recv: bad text %q", data)) + acme.Errf(root, "plumb recv: bad text %q", data) continue } var plummy awin - plummy.prefix = "/issue/" + project + "/" + plummy.prefix = path.Join(root, project) + "/" if !plummy.Look(what) { - w.Err(fmt.Sprintf("plumb recv: can't look %s%s", plummy.prefix, what)) + acme.Errf(root, "plumb recv: can't look %s%s", plummy.prefix, what) } } } @@ -251,7 +254,7 @@ func (w *awin) Look(text string) bool { if m := repoHashRE.FindStringSubmatch(text); m != nil { project := m[1] what := m[2] - prefix := "/issue/" + project + "/" + prefix := path.Join(root, project) + "/" if acme.Show(prefix+what) != nil { return true } From 087a7d8257c8ec3bf01d23edce9b137c7360bc0d Mon Sep 17 00:00:00 2001 From: Roi Martin Date: Sat, 11 Jan 2020 22:35:32 +0100 Subject: [PATCH 2/2] issue: document plumb port requirement Document "githubissue" plumb port requirement and how to create it under the section "Acme Editor Integration". --- issue/issue.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/issue/issue.go b/issue/issue.go index bc84549..06240f1 100644 --- a/issue/issue.go +++ b/issue/issue.go @@ -39,6 +39,11 @@ If the -a flag is specified, issue runs as a collection of acme windows instead of a command-line tool. In this mode, the query is optional. If no query is given, issue uses "state:open". +This mode requires an existing plumb port called "githubissue", which can +be created with the following plumbing rule: + + plumb to githubissue + There are three kinds of acme windows: issue, issue creation, issue list, search result, and milestone list.