Add the app struct

This commit is contained in:
Miguel de la Cruz 2020-04-29 19:52:15 +02:00
parent 8732aee990
commit 114f73f9f5
11 changed files with 208 additions and 198 deletions

75
app/app.go Normal file
View file

@ -0,0 +1,75 @@
package app
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"github.com/google/go-github/v29/github"
jira "gopkg.in/andygrunwald/go-jira.v1"
"git.ctrlz.es/mgdelacroix/campaigner/model"
)
type App struct {
Path string
jiraClient *jira.Client
githubClient *github.Client
Campaign *model.Campaign
}
func SaveCampaign(campaign *model.Campaign, path string) error {
marshaledCampaign, err := json.MarshalIndent(campaign, "", " ")
if err != nil {
return err
}
if err := ioutil.WriteFile(path, marshaledCampaign, 0600); err != nil {
return fmt.Errorf("cannot save campaign: %w", err)
}
return nil
}
func (a *App) Save() error {
return SaveCampaign(a.Campaign, a.Path)
}
func (a *App) Load() error {
if _, err := os.Stat("."); err != nil {
return fmt.Errorf("cannot read campaign: %w", err)
}
fileContents, err := ioutil.ReadFile(a.Path)
if err != nil {
return fmt.Errorf("there was a problem reading the campaign file: %w", err)
}
var campaign model.Campaign
if err := json.Unmarshal(fileContents, &campaign); err != nil {
return fmt.Errorf("there was a problem parsing the campaign file: %w", err)
}
a.Campaign = &campaign
return nil
}
func (a *App) InitClients() error {
if err := a.InitGithubClient(); err != nil {
return err
}
if err := a.InitJiraClient(); err != nil {
return err
}
return nil
}
func NewApp(path string) (*App, error) {
app := &App{Path: path}
if err := app.Load(); err != nil {
return nil, err
}
return app, nil
}

View file

@ -1,4 +1,4 @@
package github package app
import ( import (
"bytes" "bytes"
@ -7,7 +7,6 @@ import (
"fmt" "fmt"
"text/template" "text/template"
"git.ctrlz.es/mgdelacroix/campaigner/campaign"
"git.ctrlz.es/mgdelacroix/campaigner/model" "git.ctrlz.es/mgdelacroix/campaigner/model"
"github.com/StevenACoffman/j2m" "github.com/StevenACoffman/j2m"
@ -15,21 +14,13 @@ import (
"golang.org/x/oauth2" "golang.org/x/oauth2"
) )
type GithubClient struct { func (a *App) InitGithubClient() error {
*github.Client
Repo string
}
func NewClient(repo, token string) *GithubClient {
ctx := context.Background() ctx := context.Background()
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}) ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: a.Campaign.Github.Token})
tc := oauth2.NewClient(ctx, ts) tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc) a.githubClient = github.NewClient(tc)
return &GithubClient{ return nil
Client: client,
Repo: repo,
}
} }
func getFooterTemplate(ticket *model.Ticket, templatePath string) (string, error) { func getFooterTemplate(ticket *model.Ticket, templatePath string) (string, error) {
@ -45,10 +36,10 @@ func getFooterTemplate(ticket *model.Ticket, templatePath string) (string, error
return footerBytes.String(), nil return footerBytes.String(), nil
} }
func (c *GithubClient) PublishTicket(ticket *model.Ticket, cmp *model.Campaign, dryRun bool) (*github.Issue, error) { func (a *App) PublishInGithub(ticket *model.Ticket, dryRun bool) (*github.Issue, error) {
mdDescription := j2m.JiraToMD(ticket.Description) mdDescription := j2m.JiraToMD(ticket.Description)
if cmp.FooterTemplate != "" { if a.Campaign.FooterTemplate != "" {
footer, err := getFooterTemplate(ticket, cmp.FooterTemplate) footer, err := getFooterTemplate(ticket, a.Campaign.FooterTemplate)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -59,7 +50,7 @@ func (c *GithubClient) PublishTicket(ticket *model.Ticket, cmp *model.Campaign,
issueRequest := &github.IssueRequest{ issueRequest := &github.IssueRequest{
Title: &ticket.Summary, Title: &ticket.Summary,
Body: &mdDescription, Body: &mdDescription,
Labels: &cmp.Github.Labels, Labels: &a.Campaign.Github.Labels,
} }
if dryRun { if dryRun {
@ -71,21 +62,21 @@ func (c *GithubClient) PublishTicket(ticket *model.Ticket, cmp *model.Campaign,
}, nil }, nil
} }
owner, repo := cmp.RepoComponents() owner, repo := a.Campaign.RepoComponents()
newIssue, _, err := c.Issues.Create(context.Background(), owner, repo, issueRequest) newIssue, _, err := a.githubClient.Issues.Create(context.Background(), owner, repo, issueRequest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return newIssue, nil return newIssue, nil
} }
func (c *GithubClient) PublishNextTicket(cmp *model.Campaign, dryRun bool) (bool, error) { func (a *App) PublishNextInGithub(dryRun bool) (bool, error) {
ticket := cmp.NextGithubUnpublishedTicket() ticket := a.Campaign.NextGithubUnpublishedTicket()
if ticket == nil { if ticket == nil {
return false, nil return false, nil
} }
issue, err := c.PublishTicket(ticket, cmp, dryRun) issue, err := a.PublishInGithub(ticket, dryRun)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -99,16 +90,16 @@ func (c *GithubClient) PublishNextTicket(cmp *model.Campaign, dryRun bool) (bool
ticket.GithubAssignee = user.GetLogin() ticket.GithubAssignee = user.GetLogin()
} }
ticket.GithubStatus = issue.GetState() ticket.GithubStatus = issue.GetState()
if err := campaign.Save(cmp); err != nil { if err := a.Save(); err != nil {
return false, err return false, err
} }
return true, nil return true, nil
} }
func (c *GithubClient) PublishAll(cmp *model.Campaign, dryRun bool) (int, error) { func (a *App) PublishAllInGithub(dryRun bool) (int, error) {
count := 0 count := 0
for { for {
next, err := c.PublishNextTicket(cmp, dryRun) next, err := a.PublishNextInGithub(dryRun)
if err != nil { if err != nil {
return count, err return count, err
} }
@ -120,9 +111,9 @@ func (c *GithubClient) PublishAll(cmp *model.Campaign, dryRun bool) (int, error)
return count, nil return count, nil
} }
func (c *GithubClient) PublishBatch(cmp *model.Campaign, batch int, dryRun bool) error { func (a *App) PublishBatchInGithub(batch int, dryRun bool) error {
for i := 1; i <= batch; i++ { for i := 1; i <= batch; i++ {
next, err := c.PublishNextTicket(cmp, dryRun) next, err := a.PublishNextInGithub(dryRun)
if err != nil { if err != nil {
return err return err
} }

View file

@ -1,4 +1,4 @@
package jira package app
import ( import (
"bytes" "bytes"
@ -6,32 +6,28 @@ import (
"fmt" "fmt"
"text/template" "text/template"
"git.ctrlz.es/mgdelacroix/campaigner/campaign"
"git.ctrlz.es/mgdelacroix/campaigner/model" "git.ctrlz.es/mgdelacroix/campaigner/model"
jira "gopkg.in/andygrunwald/go-jira.v1" jira "gopkg.in/andygrunwald/go-jira.v1"
) )
type JiraClient struct { func (a *App) InitJiraClient() error {
*jira.Client
}
func NewClient(url, username, token string) (*JiraClient, error) {
tp := jira.BasicAuthTransport{ tp := jira.BasicAuthTransport{
Username: username, Username: a.Campaign.Jira.Username,
Password: token, Password: a.Campaign.Jira.Token,
} }
client, err := jira.NewClient(tp.Client(), url) client, err := jira.NewClient(tp.Client(), a.Campaign.Jira.Url)
if err != nil { if err != nil {
return nil, err return err
} }
return &JiraClient{client}, nil a.jiraClient = client
return nil
} }
func (c *JiraClient) GetIssueFromTicket(ticket *model.Ticket, cmp *model.Campaign) (*jira.Issue, error) { func (a *App) GetJiraIssueFromTicket(ticket *model.Ticket) (*jira.Issue, error) {
summaryTmpl, err := template.New("").Parse(cmp.Summary) summaryTmpl, err := template.New("").Parse(a.Campaign.Summary)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -42,7 +38,7 @@ func (c *JiraClient) GetIssueFromTicket(ticket *model.Ticket, cmp *model.Campaig
} }
summary := summaryBytes.String() summary := summaryBytes.String()
descriptionTemplate, err := template.ParseFiles(cmp.IssueTemplate) descriptionTemplate, err := template.ParseFiles(a.Campaign.IssueTemplate)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -56,22 +52,22 @@ func (c *JiraClient) GetIssueFromTicket(ticket *model.Ticket, cmp *model.Campaig
data := map[string]string{ data := map[string]string{
"Description": description, "Description": description,
"Summary": summary, "Summary": summary,
"Project": cmp.Jira.Project, "Project": a.Campaign.Jira.Project,
"Issue Type": cmp.Jira.IssueType, "Issue Type": a.Campaign.Jira.IssueType,
"Epic Link": cmp.Jira.Epic, "Epic Link": a.Campaign.Jira.Epic,
} }
createMetaInfo, _, err := c.Issue.GetCreateMeta(cmp.Jira.Project) createMetaInfo, _, err := a.jiraClient.Issue.GetCreateMeta(a.Campaign.Jira.Project)
if err != nil { if err != nil {
return nil, err return nil, err
} }
project := createMetaInfo.GetProjectWithKey(cmp.Jira.Project) project := createMetaInfo.GetProjectWithKey(a.Campaign.Jira.Project)
if project == nil { if project == nil {
return nil, fmt.Errorf("Error retrieving project with key %s", cmp.Jira.Project) return nil, fmt.Errorf("Error retrieving project with key %s", a.Campaign.Jira.Project)
} }
issueType := project.GetIssueTypeWithName(cmp.Jira.IssueType) issueType := project.GetIssueTypeWithName(a.Campaign.Jira.IssueType)
if issueType == nil { if issueType == nil {
return nil, fmt.Errorf("Error retrieving issue type with name Story") return nil, fmt.Errorf("Error retrieving issue type with name Story")
} }
@ -84,8 +80,8 @@ func (c *JiraClient) GetIssueFromTicket(ticket *model.Ticket, cmp *model.Campaig
return issue, nil return issue, nil
} }
func (c *JiraClient) PublishTicket(ticket *model.Ticket, cmp *model.Campaign, dryRun bool) (*jira.Issue, error) { func (a *App) PublishInJira(ticket *model.Ticket, dryRun bool) (*jira.Issue, error) {
issue, err := c.GetIssueFromTicket(ticket, cmp) issue, err := a.GetJiraIssueFromTicket(ticket)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -96,7 +92,7 @@ func (c *JiraClient) PublishTicket(ticket *model.Ticket, cmp *model.Campaign, dr
return issue, nil return issue, nil
} }
newIssue, _, err := c.Issue.Create(issue) newIssue, _, err := a.jiraClient.Issue.Create(issue)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -104,21 +100,21 @@ func (c *JiraClient) PublishTicket(ticket *model.Ticket, cmp *model.Campaign, dr
return newIssue, nil return newIssue, nil
} }
func (c *JiraClient) GetIssue(issueNo string) (*jira.Issue, error) { func (a *App) GetIssue(issueNo string) (*jira.Issue, error) {
issue, _, err := c.Issue.Get(issueNo, nil) issue, _, err := a.jiraClient.Issue.Get(issueNo, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return issue, nil return issue, nil
} }
func (c *JiraClient) PublishNextTicket(cmp *model.Campaign, dryRun bool) (bool, error) { func (a *App) PublishNextInJira(dryRun bool) (bool, error) {
ticket := cmp.NextJiraUnpublishedTicket() ticket := a.Campaign.NextJiraUnpublishedTicket()
if ticket == nil { if ticket == nil {
return false, nil return false, nil
} }
issue, err := c.PublishTicket(ticket, cmp, dryRun) issue, err := a.PublishInJira(ticket, dryRun)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -127,25 +123,25 @@ func (c *JiraClient) PublishNextTicket(cmp *model.Campaign, dryRun bool) (bool,
return true, nil return true, nil
} }
issue, _, err = c.Issue.Get(issue.Key, nil) issue, _, err = a.jiraClient.Issue.Get(issue.Key, nil)
if err != nil { if err != nil {
return false, err return false, err
} }
ticket.JiraLink = fmt.Sprintf("%s/browse/%s", cmp.Jira.Url, issue.Key) ticket.JiraLink = fmt.Sprintf("%s/browse/%s", a.Campaign.Jira.Url, issue.Key)
ticket.Summary = issue.Fields.Summary ticket.Summary = issue.Fields.Summary
ticket.Description = issue.Fields.Description ticket.Description = issue.Fields.Description
ticket.JiraStatus = issue.Fields.Status.Name ticket.JiraStatus = issue.Fields.Status.Name
if err := campaign.Save(cmp); err != nil { if err := a.Save(); err != nil {
return false, err return false, err
} }
return true, nil return true, nil
} }
func (c *JiraClient) PublishAll(cmp *model.Campaign, dryRun bool) (int, error) { func (a *App) PublishAllInJira(dryRun bool) (int, error) {
count := 0 count := 0
for { for {
next, err := c.PublishNextTicket(cmp, dryRun) next, err := a.PublishNextInJira(dryRun)
if err != nil { if err != nil {
return count, err return count, err
} }
@ -157,9 +153,9 @@ func (c *JiraClient) PublishAll(cmp *model.Campaign, dryRun bool) (int, error) {
return count, nil return count, nil
} }
func (c *JiraClient) PublishBatch(cmp *model.Campaign, batch int, dryRun bool) error { func (a *App) PublishBatchInJira(batch int, dryRun bool) error {
for i := 1; i <= batch; i++ { for i := 1; i <= batch; i++ {
next, err := c.PublishNextTicket(cmp, dryRun) next, err := a.PublishNextInJira(dryRun)
if err != nil { if err != nil {
return err return err
} }

View file

@ -1,40 +0,0 @@
package campaign
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"git.ctrlz.es/mgdelacroix/campaigner/model"
)
func Save(campaign *model.Campaign) error {
marshaledCampaign, err := json.MarshalIndent(campaign, "", " ")
if err != nil {
return err
}
if err := ioutil.WriteFile("./campaign.json", marshaledCampaign, 0600); err != nil {
return fmt.Errorf("cannot save campaign: %w", err)
}
return nil
}
func Read() (*model.Campaign, error) {
if _, err := os.Stat("."); err != nil {
return nil, fmt.Errorf("cannot read campaign: %w", err)
}
fileContents, err := ioutil.ReadFile("./campaign.json")
if err != nil {
return nil, fmt.Errorf("there was a problem reading the campaign file: %w", err)
}
var campaign model.Campaign
if err := json.Unmarshal(fileContents, &campaign); err != nil {
return nil, fmt.Errorf("there was a problem parsing the campaign file: %w", err)
}
return &campaign, nil
}

View file

@ -8,7 +8,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"git.ctrlz.es/mgdelacroix/campaigner/campaign" "git.ctrlz.es/mgdelacroix/campaigner/app"
"git.ctrlz.es/mgdelacroix/campaigner/model" "git.ctrlz.es/mgdelacroix/campaigner/model"
"git.ctrlz.es/mgdelacroix/campaigner/parsers" "git.ctrlz.es/mgdelacroix/campaigner/parsers"
) )
@ -25,7 +25,7 @@ func GrepAddCmd() *cobra.Command {
`, `,
Example: ` grep -nriIF --include \*.go cobra.Command | campaigner add grep`, Example: ` grep -nriIF --include \*.go cobra.Command | campaigner add grep`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: grepAddCmdF, Run: withApp(grepAddCmdF),
} }
cmd.Flags().BoolP("file-only", "f", false, "Generates one ticket per file instead of per match") cmd.Flags().BoolP("file-only", "f", false, "Generates one ticket per file instead of per match")
@ -60,7 +60,7 @@ func GovetAddCmd() *cobra.Command {
`, `,
Example: ` govet ./... 2>&1 | campaigner add govet`, Example: ` govet ./... 2>&1 | campaigner add govet`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: govetAddCmdF, Run: withApp(govetAddCmdF),
} }
cmd.Flags().BoolP("file-only", "f", false, "Generates one ticket per file instead of per match") cmd.Flags().BoolP("file-only", "f", false, "Generates one ticket per file instead of per match")
@ -74,7 +74,7 @@ func CsvAddCmd() *cobra.Command {
Short: "Generates the tickets reading a csv file", Short: "Generates the tickets reading a csv file",
Example: ` campaigner add csv tickets.csv`, Example: ` campaigner add csv tickets.csv`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: csvAddCmdF, Run: withApp(csvAddCmdF),
} }
} }
@ -95,20 +95,13 @@ func AddCmd() *cobra.Command {
return cmd return cmd
} }
func grepAddCmdF(cmd *cobra.Command, _ []string) { func grepAddCmdF(a *app.App, cmd *cobra.Command, _ []string) {
fileOnly, _ := cmd.Flags().GetBool("file-only") fileOnly, _ := cmd.Flags().GetBool("file-only")
tickets := parsers.ParseWith(parsers.GREP) tickets := parsers.ParseWith(parsers.GREP)
a.Campaign.AddTickets(tickets, fileOnly)
cmp, err := campaign.Read() if err := a.Save(); err != nil {
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) ErrorAndExit(cmd, err)
} }
cmd.Printf("%d tickets have been added\n", len(tickets)) cmd.Printf("%d tickets have been added\n", len(tickets))
@ -118,36 +111,24 @@ func agAddCmdF(_ *cobra.Command, _ []string) error {
return fmt.Errorf("not implemented yet") return fmt.Errorf("not implemented yet")
} }
func govetAddCmdF(cmd *cobra.Command, _ []string) { func govetAddCmdF(a *app.App, cmd *cobra.Command, _ []string) {
fileOnly, _ := cmd.Flags().GetBool("file-only") fileOnly, _ := cmd.Flags().GetBool("file-only")
tickets := parsers.ParseWith(parsers.GOVET) tickets := parsers.ParseWith(parsers.GOVET)
a.Campaign.AddTickets(tickets, fileOnly)
cmp, err := campaign.Read() if err := a.Save(); err != nil {
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) ErrorAndExit(cmd, err)
} }
cmd.Printf("%d tickets have been added\n", len(tickets)) cmd.Printf("%d tickets have been added\n", len(tickets))
} }
func csvAddCmdF(cmd *cobra.Command, args []string) { func csvAddCmdF(a *app.App, cmd *cobra.Command, args []string) {
file, err := os.Open(args[0]) file, err := os.Open(args[0])
if err != nil { if err != nil {
ErrorAndExit(cmd, err) ErrorAndExit(cmd, err)
} }
cmp, err := campaign.Read()
if err != nil {
ErrorAndExit(cmd, err)
}
csvReader := csv.NewReader(bufio.NewReader(file)) csvReader := csv.NewReader(bufio.NewReader(file))
records, err := csvReader.ReadAll() records, err := csvReader.ReadAll()
if err != nil { if err != nil {
@ -160,10 +141,10 @@ func csvAddCmdF(cmd *cobra.Command, args []string) {
for i, header := range headers { for i, header := range headers {
data[header] = line[i] data[header] = line[i]
} }
cmp.Tickets = append(cmp.Tickets, &model.Ticket{Data: data}) a.Campaign.Tickets = append(a.Campaign.Tickets, &model.Ticket{Data: data})
} }
if err := campaign.Save(cmp); err != nil { if err := a.Save(); err != nil {
ErrorAndExit(cmd, err) ErrorAndExit(cmd, err)
} }
cmd.Printf("%d tickets have been added\n", len(records[1:])) cmd.Printf("%d tickets have been added\n", len(records[1:]))

View file

@ -6,7 +6,7 @@ import (
"os" "os"
"strings" "strings"
"git.ctrlz.es/mgdelacroix/campaigner/campaign" "git.ctrlz.es/mgdelacroix/campaigner/app"
"git.ctrlz.es/mgdelacroix/campaigner/model" "git.ctrlz.es/mgdelacroix/campaigner/model"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -78,7 +78,7 @@ func initCmdF(cmd *cobra.Command, _ []string) {
project := strings.Split(epic, "-")[0] project := strings.Split(epic, "-")[0]
cmp := &model.Campaign{ campaign := &model.Campaign{
Jira: model.ConfigJira{ Jira: model.ConfigJira{
Url: url, Url: url,
Username: jiraUsername, Username: jiraUsername,
@ -96,7 +96,7 @@ func initCmdF(cmd *cobra.Command, _ []string) {
IssueTemplate: issueTemplate, IssueTemplate: issueTemplate,
FooterTemplate: footerTemplate, FooterTemplate: footerTemplate,
} }
if err := campaign.Save(cmp); err != nil { if err := app.SaveCampaign(campaign, "./campaign.json"); err != nil {
ErrorAndExit(cmd, err) ErrorAndExit(cmd, err)
} }
} }

View file

@ -3,9 +3,7 @@ package cmd
import ( import (
"fmt" "fmt"
"git.ctrlz.es/mgdelacroix/campaigner/campaign" "git.ctrlz.es/mgdelacroix/campaigner/app"
"git.ctrlz.es/mgdelacroix/campaigner/github"
"git.ctrlz.es/mgdelacroix/campaigner/jira"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -15,7 +13,7 @@ func JiraPublishCmd() *cobra.Command {
Use: "jira", Use: "jira",
Short: "Publishes the campaign tickets in jira", Short: "Publishes the campaign tickets in jira",
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: jiraPublishCmdF, RunE: withAppE(jiraPublishCmdF),
} }
cmd.Flags().BoolP("all", "a", false, "Publish all the tickets of the campaign") cmd.Flags().BoolP("all", "a", false, "Publish all the tickets of the campaign")
@ -30,7 +28,7 @@ func GithubPublishCmd() *cobra.Command {
Use: "github", Use: "github",
Short: "Publishes the campaign tickets in github", Short: "Publishes the campaign tickets in github",
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: githubPublishCmdF, RunE: withAppE(githubPublishCmdF),
} }
cmd.Flags().BoolP("all", "a", false, "Publish all the tickets of the campaign") cmd.Flags().BoolP("all", "a", false, "Publish all the tickets of the campaign")
@ -55,7 +53,7 @@ func PublishCmd() *cobra.Command {
return cmd return cmd
} }
func jiraPublishCmdF(cmd *cobra.Command, _ []string) error { func jiraPublishCmdF(a *app.App, cmd *cobra.Command, _ []string) error {
all, _ := cmd.Flags().GetBool("all") all, _ := cmd.Flags().GetBool("all")
batch, _ := cmd.Flags().GetInt("batch") batch, _ := cmd.Flags().GetInt("batch")
dryRun, _ := cmd.Flags().GetBool("dry-run") dryRun, _ := cmd.Flags().GetBool("dry-run")
@ -64,24 +62,14 @@ func jiraPublishCmdF(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("One of --all or --batch flags is required") return fmt.Errorf("One of --all or --batch flags is required")
} }
cmp, err := campaign.Read()
if err != nil {
ErrorAndExit(cmd, err)
}
jiraClient, err := jira.NewClient(cmp.Jira.Url, cmp.Jira.Username, cmp.Jira.Token)
if err != nil {
ErrorAndExit(cmd, err)
}
if all { if all {
count, err := jiraClient.PublishAll(cmp, dryRun) count, err := a.PublishAllInJira(dryRun)
if err != nil { if err != nil {
ErrorAndExit(cmd, err) ErrorAndExit(cmd, err)
} }
cmd.Printf("All %d tickets successfully published in jira\n", count) cmd.Printf("All %d tickets successfully published in jira\n", count)
} else { } else {
if err := jiraClient.PublishBatch(cmp, batch, dryRun); err != nil { if err := a.PublishBatchInJira(batch, dryRun); err != nil {
ErrorAndExit(cmd, err) ErrorAndExit(cmd, err)
} }
cmd.Printf("Batch of %d tickets successfully published in jira\n", batch) cmd.Printf("Batch of %d tickets successfully published in jira\n", batch)
@ -90,7 +78,7 @@ func jiraPublishCmdF(cmd *cobra.Command, _ []string) error {
return nil return nil
} }
func githubPublishCmdF(cmd *cobra.Command, _ []string) error { func githubPublishCmdF(a *app.App, cmd *cobra.Command, _ []string) error {
all, _ := cmd.Flags().GetBool("all") all, _ := cmd.Flags().GetBool("all")
batch, _ := cmd.Flags().GetInt("batch") batch, _ := cmd.Flags().GetInt("batch")
dryRun, _ := cmd.Flags().GetBool("dry-run") dryRun, _ := cmd.Flags().GetBool("dry-run")
@ -99,21 +87,14 @@ func githubPublishCmdF(cmd *cobra.Command, _ []string) error {
return fmt.Errorf("One of --all or --batch flags is required") return fmt.Errorf("One of --all or --batch flags is required")
} }
cmp, err := campaign.Read()
if err != nil {
ErrorAndExit(cmd, err)
}
githubClient := github.NewClient(cmp.Github.Repo, cmp.Github.Token)
if all { if all {
count, err := githubClient.PublishAll(cmp, dryRun) count, err := a.PublishAllInGithub(dryRun)
if err != nil { if err != nil {
ErrorAndExit(cmd, err) ErrorAndExit(cmd, err)
} }
cmd.Printf("All %d tickets successfully published in github\n", count) cmd.Printf("All %d tickets successfully published in github\n", count)
} else { } else {
if err := githubClient.PublishBatch(cmp, batch, dryRun); err != nil { if err := a.PublishBatchInGithub(batch, dryRun); err != nil {
ErrorAndExit(cmd, err) ErrorAndExit(cmd, err)
} }
cmd.Printf("Batch of %d tickets successfully published in github\n", batch) cmd.Printf("Batch of %d tickets successfully published in github\n", batch)

View file

@ -5,8 +5,34 @@ import (
"os" "os"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"git.ctrlz.es/mgdelacroix/campaigner/app"
) )
func withApp(f func(*app.App, *cobra.Command, []string)) func(*cobra.Command, []string) {
a, err := app.NewApp("./campaign.json")
if err != nil {
fmt.Fprintln(os.Stderr, "ERROR: "+err.Error())
os.Exit(1)
}
return func(cmd *cobra.Command, args []string) {
f(a, cmd, args)
}
}
func withAppE(f func(*app.App, *cobra.Command, []string) error) func(*cobra.Command, []string) error {
a, err := app.NewApp("./campaign.json")
if err != nil {
fmt.Fprintln(os.Stderr, "ERROR: "+err.Error())
os.Exit(1)
}
return func(cmd *cobra.Command, args []string) error {
return f(a, cmd, args)
}
}
func RootCmd() *cobra.Command { func RootCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "campaigner", Use: "campaigner",

View file

@ -1,9 +1,9 @@
package cmd package cmd
import ( import (
"git.ctrlz.es/mgdelacroix/campaigner/campaign"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"git.ctrlz.es/mgdelacroix/campaigner/app"
) )
func StatusCmd() *cobra.Command { func StatusCmd() *cobra.Command {
@ -12,15 +12,10 @@ func StatusCmd() *cobra.Command {
Short: "Prints the campaign status", Short: "Prints the campaign status",
Long: "Prints the current status of the campaign and its tickets", Long: "Prints the current status of the campaign and its tickets",
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: statusCmdF, Run: withApp(statusCmdF),
} }
} }
func statusCmdF(cmd *cobra.Command, _ []string) { func statusCmdF(a *app.App, cmd *cobra.Command, _ []string) {
cmp, err := campaign.Read() a.Campaign.PrintStatus()
if err != nil {
ErrorAndExit(cmd, err)
}
cmp.PrintStatus()
} }

View file

@ -70,6 +70,31 @@ func (c *Campaign) PrintStatus() {
fmt.Printf("\t%d/%d\tpublished in Github\n\n", totalPublishedGithub, totalPublishedJira) fmt.Printf("\t%d/%d\tpublished in Github\n\n", totalPublishedGithub, totalPublishedJira)
} }
func (c *Campaign) AddTickets(tickets []*Ticket, fileOnly bool) {
c.Tickets = append(c.Tickets, tickets...)
c.RemoveDuplicateTickets(fileOnly)
}
func (c *Campaign) RemoveDuplicateTickets(fileOnly bool) {
ticketMap := map[string]*Ticket{}
for _, t := range c.Tickets {
filename, _ := t.Data["filename"].(string)
lineNo, _ := t.Data["lineNo"].(int)
if fileOnly {
ticketMap[filename] = t
} else {
ticketMap[fmt.Sprintf("%s:%d", filename, lineNo)] = t
}
}
cleanTickets := []*Ticket{}
for _, t := range ticketMap {
cleanTickets = append(cleanTickets, t)
}
c.Tickets = cleanTickets
}
func (c *Campaign) FillTicket(t *Ticket) error { func (c *Campaign) FillTicket(t *Ticket) error {
summaryTmpl, err := template.New("").Parse(c.Summary) summaryTmpl, err := template.New("").Parse(c.Summary)
if err != nil { if err != nil {

View file

@ -15,26 +15,6 @@ type Ticket struct {
Data map[string]interface{} `json:"data,omitempty"` Data map[string]interface{} `json:"data,omitempty"`
} }
func RemoveDuplicateTickets(tickets []*Ticket, fileOnly bool) []*Ticket {
ticketMap := map[string]*Ticket{}
for _, t := range tickets {
filename, _ := t.Data["filename"].(string)
lineNo, _ := t.Data["lineNo"].(int)
if fileOnly {
ticketMap[filename] = t
} else {
ticketMap[fmt.Sprintf("%s:%d", filename, lineNo)] = t
}
}
cleanTickets := []*Ticket{}
for _, t := range ticketMap {
cleanTickets = append(cleanTickets, t)
}
return cleanTickets
}
func (t *Ticket) IsPublishedJira() bool { func (t *Ticket) IsPublishedJira() bool {
return t.JiraLink != "" return t.JiraLink != ""
} }