Skip to content

Commit 7334637

Browse files
committed
feat: Add pullnote command to extract notes detected with pullvet
1 parent 14938c1 commit 7334637

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ build/exec:
77
build:
88
go build -o bin/actions ./cmd
99

10+
install: build
11+
mv bin/actions ~/bin/actions
12+
1013
test/integration:
1114
echo aaa
1215
GITHUB_EVENT_NAME=issues GITHUB_EVENT_PATH=testdata/issues_event.json bin/actions exec -status-context milestone -- bin/actions pullvet -require-any -milestone-match 'test-v.+' label milestone/none

cmd/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"os"
77

8+
"github.com/variantdev/go-actions/cmd/pullnote"
89
"github.com/variantdev/go-actions/cmd/pullvet"
910
"github.com/variantdev/go-actions/pkg/cli"
1011
"github.com/variantdev/go-actions/pkg/exec"
@@ -54,6 +55,7 @@ func main() {
5455

5556
subCommands := []cli.Command{
5657
pullvet.Command,
58+
pullnote.Command,
5759
}
5860

5961
for _, subCmd := range subCommands {

cmd/pullnote/pullnote.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package pullnote
2+
3+
import (
4+
"flag"
5+
6+
"github.com/variantdev/go-actions/pkg/cli"
7+
"github.com/variantdev/go-actions/pkg/pullnote"
8+
"github.com/variantdev/go-actions/pkg/pullvet"
9+
)
10+
11+
var Command cli.Command = &cmd{}
12+
13+
type cmd struct {}
14+
15+
func (c *cmd) Name() string {
16+
return "pullnote"
17+
}
18+
19+
func (c *cmd) Run(args []string) error {
20+
action := pullnote.New()
21+
22+
usage := `pullnote extracts notes detected by pullvet. The input should be provided as NDJSON via stdin or a file
23+
`
24+
25+
if err := cli.Setup(c, args, usage, func(fs *flag.FlagSet) {
26+
fs.StringVar(&action.File, "file", "", "NDJSON file to read")
27+
fs.StringVar(&action.NoteRegex, "note-regex", pullvet.DefaultNoteRegex, "Regexp pattern of each note(including the title and the body)")
28+
fs.StringVar(&action.BodyKey, "body-key", "body", "Read pull request body containing notes from this key in the JSON object read from a NDJSON line")
29+
fs.StringVar(&action.KindKey, "kind-key", "kind", "Extracted kind of the note is set to this key")
30+
fs.StringVar(&action.DescKey, "desc-key", "desc", "Extracted description of the note is set to this key")
31+
}); err != nil {
32+
return err
33+
}
34+
35+
return action.Run()
36+
}

pkg/pullnote/pullnote.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package pullnote
2+
3+
import (
4+
"bufio"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"os"
9+
"regexp"
10+
)
11+
12+
var newlineRegex = regexp.MustCompile(`\r\n|\r|\n`)
13+
14+
type Action struct {
15+
NoteRegex string
16+
File string
17+
BodyKey string
18+
KindKey string
19+
DescKey string
20+
}
21+
22+
func normalizeNewlines(str string) string {
23+
return newlineRegex.ReplaceAllString(str, "\n")
24+
}
25+
26+
func New() *Action {
27+
return &Action{
28+
}
29+
}
30+
31+
func (c *Action) Run() error {
32+
regex := regexp.MustCompile(c.NoteRegex)
33+
34+
var in io.Reader
35+
36+
if c.File != "" {
37+
file, err := os.Open(c.File)
38+
if err != nil {
39+
return err
40+
}
41+
defer file.Close()
42+
in = file
43+
} else {
44+
in = os.Stdin
45+
}
46+
47+
scanner := bufio.NewScanner(in)
48+
for scanner.Scan() {
49+
line := scanner.Text()
50+
m := map[string]interface{}{}
51+
if err := json.Unmarshal([]byte(line), &m); err != nil {
52+
return err
53+
}
54+
key := c.BodyKey
55+
value, ok := m[key]
56+
if !ok {
57+
return fmt.Errorf("required key %q does not exist: %s", key, line)
58+
}
59+
60+
body, ok := value.(string)
61+
if !ok {
62+
return fmt.Errorf("unexpected type of body: expected string, got %T(%v)", value, value)
63+
}
64+
65+
allNoteMatches := regex.FindAllStringSubmatch(normalizeNewlines(body), -1)
66+
for _, match := range allNoteMatches {
67+
kind, desc := match[1], match[2]
68+
delete(m, c.BodyKey)
69+
m[c.KindKey] = kind
70+
m[c.DescKey] = desc
71+
res, err := json.Marshal(m)
72+
if err != nil {
73+
return err
74+
}
75+
println(string(res))
76+
}
77+
}
78+
79+
return nil
80+
}

0 commit comments

Comments
 (0)