Add govet parsing
This commit is contained in:
parent
4627bbbcb9
commit
aad8c6b884
5 changed files with 126 additions and 52 deletions
73
cmd/add.go
73
cmd/add.go
|
@ -5,20 +5,19 @@ import (
|
|||
"encoding/csv"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"git.ctrlz.es/mgdelacroix/campaigner/campaign"
|
||||
"git.ctrlz.es/mgdelacroix/campaigner/model"
|
||||
"git.ctrlz.es/mgdelacroix/campaigner/parsers"
|
||||
)
|
||||
|
||||
func GrepAddCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "grep",
|
||||
Short: "Generates the tickets reading grep's output from stdin",
|
||||
Long: `Generates tickets for the campaign reading from the standard input the output grep. The grep command must be run with the -n flag. The generated ticket will contain three fields:
|
||||
Long: `Generates tickets for the campaign reading the output of grep from the standard input. The grep command must be run with the -n flag. The generated ticket will contain three fields:
|
||||
|
||||
- filename: the filename yield by grep
|
||||
- lineNo: the line number yield by grep
|
||||
|
@ -53,10 +52,15 @@ func GovetAddCmd() *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "govet",
|
||||
Short: "Generates the tickets reading govet's output from stdin",
|
||||
Long: "Generates tickets for the campaign reading from the standard input the output grep. The grep command must be run with the -json flag",
|
||||
Example: ` govet -json ./... | campaigner add govet`,
|
||||
Long: `Generates tickets for the campaign reading the output of govet from the standard input. Govet usually writes to the standard error descriptor, so the output must be redirected. The generated ticket will contain three fields:
|
||||
|
||||
- filename: the filename yield by grep
|
||||
- lineNo: the line number yield by grep
|
||||
- text: the text containing the govet error
|
||||
`,
|
||||
Example: ` govet ./... 2>&1 | campaigner add govet`,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: govetAddCmdF,
|
||||
Run: govetAddCmdF,
|
||||
}
|
||||
|
||||
cmd.Flags().BoolP("file-only", "f", false, "Generates one ticket per file instead of per match")
|
||||
|
@ -91,46 +95,10 @@ func AddCmd() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func parseGrepLine(line string) (*model.Ticket, error) {
|
||||
// ToDo: it would be great to be able to relate a line with its
|
||||
// parent method, at least for JS and Golang
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("cannot parse line: %s", line)
|
||||
}
|
||||
|
||||
filename := parts[0]
|
||||
lineNo, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
text := strings.Join(parts[2:], "")
|
||||
|
||||
return &model.Ticket{
|
||||
Data: map[string]interface{}{
|
||||
"filename": filename,
|
||||
"lineNo": lineNo,
|
||||
"text": strings.TrimSpace(text),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseGrep() []*model.Ticket {
|
||||
tickets := []*model.Ticket{}
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
ticket, _ := parseGrepLine(scanner.Text())
|
||||
if ticket != nil {
|
||||
tickets = append(tickets, ticket)
|
||||
}
|
||||
}
|
||||
return tickets
|
||||
}
|
||||
|
||||
func grepAddCmdF(cmd *cobra.Command, _ []string) {
|
||||
fileOnly, _ := cmd.Flags().GetBool("file-only")
|
||||
|
||||
tickets := parseGrep()
|
||||
tickets := parsers.ParseWith(parsers.GREP)
|
||||
|
||||
cmp, err := campaign.Read()
|
||||
if err != nil {
|
||||
|
@ -150,8 +118,23 @@ func agAddCmdF(_ *cobra.Command, _ []string) error {
|
|||
return fmt.Errorf("not implemented yet")
|
||||
}
|
||||
|
||||
func govetAddCmdF(_ *cobra.Command, _ []string) error {
|
||||
return fmt.Errorf("not implemented yet")
|
||||
func govetAddCmdF(cmd *cobra.Command, _ []string) {
|
||||
fileOnly, _ := cmd.Flags().GetBool("file-only")
|
||||
|
||||
tickets := parsers.ParseWith(parsers.GOVET)
|
||||
|
||||
cmp, err := campaign.Read()
|
||||
if err != nil {
|
||||
ErrorAndExit(cmd, err)
|
||||
}
|
||||
|
||||
cmp.Tickets = append(cmp.Tickets, tickets...)
|
||||
cmp.Tickets = model.RemoveDuplicateTickets(cmp.Tickets, fileOnly)
|
||||
|
||||
if err := campaign.Save(cmp); err != nil {
|
||||
ErrorAndExit(cmd, err)
|
||||
}
|
||||
cmd.Printf("%d tickets have been added\n", len(tickets))
|
||||
}
|
||||
|
||||
func csvAddCmdF(cmd *cobra.Command, args []string) {
|
||||
|
|
|
@ -71,6 +71,10 @@ func (c *GithubClient) PublishNextTicket(cmp *model.Campaign, dryRun bool) (bool
|
|||
}
|
||||
|
||||
ticket.GithubLink = issue.GetNumber()
|
||||
if user := issue.GetUser(); user != nil {
|
||||
ticket.GithubAssignee = user.GetLogin()
|
||||
}
|
||||
ticket.GithubStatus = issue.GetState()
|
||||
if err := campaign.Save(cmp); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -135,6 +135,7 @@ func (c *JiraClient) PublishNextTicket(cmp *model.Campaign, dryRun bool) (bool,
|
|||
ticket.JiraLink = issue.Key
|
||||
ticket.Summary = issue.Fields.Summary
|
||||
ticket.Description = issue.Fields.Description
|
||||
// ToDo: sync JiraStatus
|
||||
if err := campaign.Save(cmp); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -5,13 +5,14 @@ import (
|
|||
)
|
||||
|
||||
type Ticket struct {
|
||||
GithubLink int `json:"github_link,omitempty"`
|
||||
GithubStatus string `json:"github_status,omitempty"`
|
||||
JiraLink string `json:"jira_link,omitempty"`
|
||||
JiraStatus string `json:"jira_status,omitempty"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
GithubLink int `json:"github_link,omitempty"`
|
||||
GithubStatus string `json:"github_status,omitempty"`
|
||||
GithubAssignee string `json:"github_assignee,omitempty"`
|
||||
JiraLink string `json:"jira_link,omitempty"`
|
||||
JiraStatus string `json:"jira_status,omitempty"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
func RemoveDuplicateTickets(tickets []*Ticket, fileOnly bool) []*Ticket {
|
||||
|
|
85
parsers/parsers.go
Normal file
85
parsers/parsers.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package parsers
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.ctrlz.es/mgdelacroix/campaigner/model"
|
||||
)
|
||||
|
||||
const (
|
||||
GREP = "grep"
|
||||
GOVET = "govet"
|
||||
)
|
||||
|
||||
func parseGrepLine(line string) (*model.Ticket, error) {
|
||||
// ToDo: it would be great to be able to relate a line with its
|
||||
// parent method, at least for JS and Golang
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("cannot parse line: %s", line)
|
||||
}
|
||||
|
||||
filename := parts[0]
|
||||
lineNo, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
text := strings.Join(parts[2:], "")
|
||||
|
||||
return &model.Ticket{
|
||||
Data: map[string]interface{}{
|
||||
"filename": filename,
|
||||
"lineNo": lineNo,
|
||||
"text": strings.TrimSpace(text),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseGovetLine(line string) (*model.Ticket, error) {
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) < 4 {
|
||||
return nil, fmt.Errorf("cannot parse line: %s", line)
|
||||
}
|
||||
|
||||
filename := parts[0]
|
||||
lineNo, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
text := strings.Join(parts[3:], "")
|
||||
|
||||
return &model.Ticket{
|
||||
Data: map[string]interface{}{
|
||||
"filename": filename,
|
||||
"lineNo": lineNo,
|
||||
"text": strings.TrimSpace(text),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ParseWith(parser string) []*model.Ticket {
|
||||
var parseFn func(string) (*model.Ticket, error)
|
||||
switch parser {
|
||||
case GREP:
|
||||
parseFn = parseGrepLine
|
||||
case GOVET:
|
||||
parseFn = parseGovetLine
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unknown parser %s", parser)
|
||||
return nil
|
||||
}
|
||||
|
||||
tickets := []*model.Ticket{}
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
ticket, _ := parseFn(scanner.Text())
|
||||
if ticket != nil {
|
||||
tickets = append(tickets, ticket)
|
||||
}
|
||||
}
|
||||
return tickets
|
||||
}
|
Loading…
Reference in a new issue