From ae6292ade86ce2ed16a885513a02aeca79277be7 Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Wed, 15 Dec 2021 11:47:09 +0100 Subject: [PATCH 01/13] Add config options for time handling in JQL --- config/config.example.yaml | 4 ++++ config/config.go | 33 ++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/config/config.example.yaml b/config/config.example.yaml index f3f027b..880f56b 100644 --- a/config/config.example.yaml +++ b/config/config.example.yaml @@ -51,6 +51,8 @@ jira: "Raccoon": ":raccoon:" "Double Trouble": ":busts_in_silhouette:" + timeformat: "2006-01-02 03:04" + bugoverview: listall: - ABC @@ -154,6 +156,8 @@ regex: jirasorting: "(?i:)" jirastatus: "(?i:)" jiratime: "(?i:)" + jiraoffsettime: "(?i:)" + jiraoffsetfield: "(?i:)" replycolor: "(?i:)" replylayout: "(?i:)" replylist: "(?i:)" diff --git a/config/config.go b/config/config.go index f8ae423..de14cb7 100644 --- a/config/config.go +++ b/config/config.go @@ -22,6 +22,7 @@ type JiraConfig struct { Statuses map[string]string `yaml:",flow"` Priorities map[string]Priority `yaml:",flow"` FeatureTeams TeamConfig + TimeFormat string BugOverview struct { ListAll []string `yaml:",flow"` All string @@ -68,19 +69,21 @@ type TeamConfig struct { // RegexConfig contains the various regex expressions to parse Slack messages for commands type RegexConfig struct { - JiraAssignee string - JiraCustom string - JiraIssueType string - JiraOption string - JiraPriority string - JiraProject string - JiraSorting string - JiraStatus string - JiraTime string - ReplyColor string - ReplyLayout string - ReplyList string - ReplyTitle string - CronCommand string - CronTime string + JiraAssignee string + JiraCustom string + JiraIssueType string + JiraOption string + JiraPriority string + JiraProject string + JiraSorting string + JiraStatus string + JiraTime string + JiraOffsetTime string + JiraOffsetField string + ReplyColor string + ReplyLayout string + ReplyList string + ReplyTitle string + CronCommand string + CronTime string } From bc9e1130436476748962658f87c0d8a9a7c6cd5b Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Wed, 15 Dec 2021 11:47:37 +0100 Subject: [PATCH 02/13] Extend JQL Builder with time option --- utils/jira_query.go | 79 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/utils/jira_query.go b/utils/jira_query.go index 07339d5..1a402b7 100644 --- a/utils/jira_query.go +++ b/utils/jira_query.go @@ -5,34 +5,41 @@ import ( "github.com/tigerteufel85/boggy/client" "github.com/tigerteufel85/boggy/config" "html" + "regexp" + "strconv" "strings" + "time" ) // JQL is a wrapper with all information for a JIRA JQL type JQL struct { - Project string - Type string - Priority string - Status string - Option string - Time string - Custom string - Assignee string - Sorting string + Project string + Type string + Priority string + Status string + Option string + Time string + OffsetTime string + OffsetField string + Custom string + Assignee string + Sorting string } // NewJQL provides all information needed for a JIRA JQL func NewJQL(config config.RegexConfig, input string) *JQL { return &JQL{ - Project: ParseRegex(input, config.JiraProject), - Type: ParseRegex(input, config.JiraIssueType), - Priority: ParseRegex(input, config.JiraPriority), - Status: ParseRegex(input, config.JiraStatus), - Option: ParseRegex(input, config.JiraOption), - Time: ParseRegex(input, config.JiraTime), - Custom: ParseRegex(input, config.JiraCustom), - Assignee: ParseRegex(input, config.JiraAssignee), - Sorting: ParseRegex(input, config.JiraSorting), + Project: ParseRegex(input, config.JiraProject), + Type: ParseRegex(input, config.JiraIssueType), + Priority: ParseRegex(input, config.JiraPriority), + Status: ParseRegex(input, config.JiraStatus), + Option: ParseRegex(input, config.JiraOption), + Time: ParseRegex(input, config.JiraTime), + OffsetTime: ParseRegex(input, config.JiraOffsetTime), + OffsetField: ParseRegex(input, config.JiraOffsetField), + Custom: ParseRegex(input, config.JiraCustom), + Assignee: ParseRegex(input, config.JiraAssignee), + Sorting: ParseRegex(input, config.JiraSorting), } } @@ -72,6 +79,22 @@ func (jql *JQL) BuildJqlQuery(config config.JiraConfig) (string, error) { } } + // prepare field with offset + if jql.OffsetField != "" && jql.OffsetTime != "" && jql.Time != "" { + loc, _ := time.LoadLocation("Europe/Berlin") + timein := time.Now().In(loc) + timein = addTime(timein, strings.ToLower(jql.OffsetTime)) + timeout := addTime(timein, strings.ToLower(jql.Time)) + + results = append(results, fmt.Sprintf( + "\"%s\" >= -%s AND \"%s\" <= %s", + jql.OffsetField, + timein.Format(config.TimeFormat), + jql.OffsetField, + timeout.Format(config.TimeFormat), + )) + } + // prepare assignee with time if jql.Assignee != "" && jql.Time != "" { results = append(results, fmt.Sprintf("assignee changed TO %s DURING (-%s,now())", jql.Assignee, jql.Time)) @@ -121,3 +144,23 @@ func getStatus(statuses map[string]string, input string) string { return "" } + +func addTime(startTime time.Time, offset string) time.Time { + timeMinutes := regexp.MustCompile(`^[0-9]*m$`) + timeHours := regexp.MustCompile(`^[0-9]*h$`) + timeDays := regexp.MustCompile(`^[0-9]*d$`) + + switch { + case timeMinutes.MatchString(offset): + timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "m", "")) + startTime.Add(time.Minute * time.Duration(timeOffset)) + case timeHours.MatchString(offset): + timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "h", "")) + startTime.Add(time.Hour * time.Duration(timeOffset)) + case timeDays.MatchString(offset): + timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "d", "")) + startTime.Add(time.Hour * 24 * time.Duration(timeOffset)) + } + + return startTime +} From dccbe79328059556b186115c6531c21f9e2e4d9e Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 16:26:14 +0100 Subject: [PATCH 03/13] Update information during initialisation of the bot --- bot/user.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bot/user.go b/bot/user.go index 22cfba8..1a7b0c7 100644 --- a/bot/user.go +++ b/bot/user.go @@ -2,6 +2,7 @@ package bot import ( "bufio" + "fmt" "github.com/nlopes/slack" "github.com/tigerteufel85/boggy/client" "github.com/tigerteufel85/boggy/config" @@ -78,7 +79,7 @@ func getAllowedUsers() []User { // load the public and private channels and list of all users from current space func (b *Bot) loadChannelsUsersAndProjects(config *config.Config) error { - // load channels + fmt.Println("...Loading Channels") var err error var cursor string var channels []slack.Channel @@ -100,7 +101,7 @@ func (b *Bot) loadChannelsUsersAndProjects(config *config.Config) error { } } - // load users + fmt.Println("...Loading Users") users, err := b.slackClient.GetUsers() if err != nil { return err @@ -111,7 +112,7 @@ func (b *Bot) loadChannelsUsersAndProjects(config *config.Config) error { client.Users[user.ID] = user.Name } - // load projects + fmt.Println("...Loading Projects") client.Projects = make(map[string]string) for _, project := range config.Jira.Projects { client.Projects[project] = project From 429eebbde508ed1b6076894d90975de126650a5c Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 16:27:28 +0100 Subject: [PATCH 04/13] Add config options for timezone and component emojis --- config/config.example.yaml | 6 ++++++ config/config.go | 2 ++ 2 files changed, 8 insertions(+) diff --git a/config/config.example.yaml b/config/config.example.yaml index 880f56b..7c40997 100644 --- a/config/config.example.yaml +++ b/config/config.example.yaml @@ -10,6 +10,12 @@ jira: - DEF - GHI + location: "Europe/Berlin" + + components: + "Backend": ":be:" + "Frontend": ":fe:" + statuses: open: "Unresolved" unresolved: "Unresolved" diff --git a/config/config.go b/config/config.go index de14cb7..ceceb38 100644 --- a/config/config.go +++ b/config/config.go @@ -19,6 +19,8 @@ type JiraConfig struct { Username string Password string Projects []string `yaml:",flow"` + Location string + Components map[string]string `yaml:",flow"` Statuses map[string]string `yaml:",flow"` Priorities map[string]Priority `yaml:",flow"` FeatureTeams TeamConfig From 48b529295502a05eedead167f8c330a4e38d31b0 Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 16:27:43 +0100 Subject: [PATCH 05/13] Fix time calculation --- utils/jira_query.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/utils/jira_query.go b/utils/jira_query.go index 1a402b7..02215d3 100644 --- a/utils/jira_query.go +++ b/utils/jira_query.go @@ -81,13 +81,13 @@ func (jql *JQL) BuildJqlQuery(config config.JiraConfig) (string, error) { // prepare field with offset if jql.OffsetField != "" && jql.OffsetTime != "" && jql.Time != "" { - loc, _ := time.LoadLocation("Europe/Berlin") + loc, _ := time.LoadLocation(config.Location) timein := time.Now().In(loc) timein = addTime(timein, strings.ToLower(jql.OffsetTime)) timeout := addTime(timein, strings.ToLower(jql.Time)) results = append(results, fmt.Sprintf( - "\"%s\" >= -%s AND \"%s\" <= %s", + "\"%s\" >= \"%s\" AND \"%s\" <= \"%s\"", jql.OffsetField, timein.Format(config.TimeFormat), jql.OffsetField, @@ -150,17 +150,19 @@ func addTime(startTime time.Time, offset string) time.Time { timeHours := regexp.MustCompile(`^[0-9]*h$`) timeDays := regexp.MustCompile(`^[0-9]*d$`) + returnTime := startTime + switch { case timeMinutes.MatchString(offset): timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "m", "")) - startTime.Add(time.Minute * time.Duration(timeOffset)) + returnTime = startTime.Add(time.Minute * time.Duration(timeOffset)) case timeHours.MatchString(offset): timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "h", "")) - startTime.Add(time.Hour * time.Duration(timeOffset)) + returnTime = startTime.Add(time.Hour * time.Duration(timeOffset)) case timeDays.MatchString(offset): timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "d", "")) - startTime.Add(time.Hour * 24 * time.Duration(timeOffset)) + returnTime = startTime.Add(time.Hour * 24 * time.Duration(timeOffset)) } - return startTime + return returnTime } From fa558d0ff3c1974f24f8d854aaa4e7dbaa5fca9f Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 16:28:43 +0100 Subject: [PATCH 06/13] Create new bot command which provides a single slack response per found issue --- command/default.go | 1 + command/jira_issues_single.go | 114 ++++++++++++++++++++++++++++++++++ command/schedule_add.go | 1 + 3 files changed, 116 insertions(+) create mode 100644 command/jira_issues_single.go diff --git a/command/default.go b/command/default.go index d475b81..944d466 100644 --- a/command/default.go +++ b/command/default.go @@ -15,6 +15,7 @@ func GetDefaultCommands(slackClient client.SlackClient, jira *jira.Client, confi Commands: []bot.Command{ NewHelp(slackClient, &commands), NewJiraIssues(slackClient, jira, config.Jira, config.Replies, config.Regex), + NewJiraIssuesSingle(slackClient, jira, config.Jira, config.Replies, config.Regex), NewJiraIssue(slackClient, jira, config.Jira, config.Replies), NewJiraOverview(slackClient, jira, config.Jira, config.Replies, config.Regex), NewAdminAddUser(slackClient), diff --git a/command/jira_issues_single.go b/command/jira_issues_single.go new file mode 100644 index 0000000..ff18885 --- /dev/null +++ b/command/jira_issues_single.go @@ -0,0 +1,114 @@ +package command + +import ( + "context" + "github.com/nlopes/slack" + "github.com/tigerteufel85/boggy/bot" + "github.com/tigerteufel85/boggy/client" + "github.com/tigerteufel85/boggy/config" + "github.com/tigerteufel85/boggy/utils" + "gopkg.in/andygrunwald/go-jira.v1" + "strings" +) + +type jiraIssuesSingle struct { + slackClient client.SlackClient + jira *jira.Client + jiraCfg config.JiraConfig + jiraReplies config.ReplyConfig + regex config.RegexConfig +} + +func NewJiraIssuesSingle(slackClient client.SlackClient, jira *jira.Client, jiraCfg config.JiraConfig, jiraReplies config.ReplyConfig, regex config.RegexConfig) *jiraIssuesSingle { + return &jiraIssuesSingle{ + slackClient, + jira, + jiraCfg, + jiraReplies, + regex, + } +} + +func (c *jiraIssuesSingle) GetName() string { + return "jira single" +} + +func (c *jiraIssuesSingle) IsValid(b *bot.Bot, command string) bool { + if !strings.HasPrefix(command, c.GetName()) { + return false + } + + _, err := utils.NewJQL(c.regex, command).BuildJqlQuery(c.jiraCfg) + if err != nil { + return false + } + + return true +} + +func (c *jiraIssuesSingle) Execute(ctx context.Context, b *bot.Bot, eventText string, event *slack.MessageEvent, user bot.User) bool { + if !strings.HasPrefix(eventText, c.GetName()) { + return false + } + + // Create JQL Query + jql := utils.NewJQL(c.regex, eventText) + query, err := jql.BuildJqlQuery(c.jiraCfg) + if err != nil { + c.slackClient.Respond(event, err.Error()) + return true + } + + // Search issues on JIRA + issues, searchResponse, err := c.jira.Issue.Search(query, &jira.SearchOptions{MaxResults: 50, Expand: "names"}) + if err != nil { + auth, _ := c.slackClient.AuthTest() + if user.Name != auth.User { + c.slackClient.Respond(event, err.Error()) + } + return true + } + + if searchResponse.Total == 0 { + return true + } + + // Get all fields + allFields, _, err := c.jira.Field.GetList() + if err != nil { + auth, _ := c.slackClient.AuthTest() + if user.Name != auth.User { + c.slackClient.Respond(event, err.Error()) + } + return true + } + + for _, issue := range issues { + customFields, _, err := c.jira.Issue.GetCustomFields(issue.ID) + if err != nil { + auth, _ := c.slackClient.AuthTest() + if user.Name != auth.User { + c.slackClient.Respond(event, err.Error()) + } + return true + } + + responseText := utils.NewLayout(c.regex, eventText).BuildSimpleTextResponse(c.jiraCfg, issue, customFields, allFields, jql) + + c.slackClient.Respond(event, responseText) + } + + return true +} + +func (c *jiraIssuesSingle) GetHelp() []bot.Help { + return []bot.Help{ + { + "jira issues single", + "creates a slack response for each crm sale which will start", + []string{ + "jira issues single“Campaign Category” = Sale", + }, + }, + } +} diff --git a/command/schedule_add.go b/command/schedule_add.go index e2ddd68..1747db9 100644 --- a/command/schedule_add.go +++ b/command/schedule_add.go @@ -43,6 +43,7 @@ func (c *scheduleAdd) IsValid(b *bot.Bot, command string) bool { func (c *scheduleAdd) getAllowedCommands() []bot.Command { return []bot.Command{ NewJiraIssues(c.slackClient, c.jira, c.jiraCfg, c.jiraReplies, c.regex), + NewJiraIssuesSingle(c.slackClient, c.jira, c.jiraCfg, c.jiraReplies, c.regex), NewJiraOverview(c.slackClient, c.jira, c.jiraCfg, c.jiraReplies, c.regex), } } From 54c19719b7bdb56d88b22f08638d074e7529e80c Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 16:29:22 +0100 Subject: [PATCH 07/13] Update go version to 1.17 --- .travis.yml | 4 +--- Dockerfile | 2 +- go.mod | 22 ++++++++++------------ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index c80c361..2e6ff1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,7 @@ language: go go: - - "1.11" - - "1.12" - - "1.13" + - "1.17" env: - GO111MODULE=on \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 5daee83..30afa52 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.11-alpine as builder +FROM golang:1.17-alpine as builder ENV GO111MODULE=on WORKDIR /boggy/ COPY . ./ diff --git a/go.mod b/go.mod index fd7e326..6a97f63 100644 --- a/go.mod +++ b/go.mod @@ -1,23 +1,21 @@ module github.com/tigerteufel85/boggy +go 1.17 + +require ( + github.com/imdario/mergo v0.3.7 + github.com/nlopes/slack v0.5.0 + gopkg.in/andygrunwald/go-jira.v1 v1.6.0 + gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5 + gopkg.in/yaml.v2 v2.2.2 +) + require ( - github.com/ae6rt/retry v2.0.0+incompatible // indirect - github.com/blend/go-sdk v1.1.1 // indirect github.com/fatih/structs v1.1.0 // indirect - github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/gorilla/websocket v1.4.0 // indirect - github.com/imdario/mergo v0.3.7 - github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5 // indirect github.com/lusis/slack-test v0.0.0-20180109053238-3c758769bfa6 // indirect - github.com/nlopes/slack v0.5.0 github.com/pkg/errors v0.8.1 // indirect github.com/stretchr/testify v1.3.0 // indirect github.com/trivago/tgo v1.0.5 // indirect - github.com/wcharczuk/go-chart v2.0.1+incompatible - github.com/xoom/stash v1.3.1 - golang.org/x/image v0.0.0-20190118043309-183bebdce1b2 // indirect - gopkg.in/andygrunwald/go-jira.v1 v1.6.0 - gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5 - gopkg.in/yaml.v2 v2.2.2 ) From bcfd2e9aaa4eff4dace486433f0e743adc75cfda Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 16:49:56 +0100 Subject: [PATCH 08/13] Update regex queries Add response layout for simple text responses --- config/config.example.yaml | 4 ++-- utils/response_layout.go | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/config/config.example.yaml b/config/config.example.yaml index 7c40997..e9edd88 100644 --- a/config/config.example.yaml +++ b/config/config.example.yaml @@ -167,6 +167,6 @@ regex: replycolor: "(?i:)" replylayout: "(?i:)" replylist: "(?i:)" - replytitle: "(?i:)([a-zA-Z0-9 .,;:=\"()><\\-+!?&|_]*)()" - croncommand: "(?i:)([a-zA-Z0-9 .,;~:=\"()><\\-+!&|\\/_]*)()" + replytitle: "(?i:)([a-zA-Z0-9 .,;:=\"()><\\-%+!?&|_]*)()" + croncommand: "(?i:)([a-zA-Z0-9 .,;~:=\"()><\\-%+!&|\\/_]*)()" crontime: "(?i:)" \ No newline at end of file diff --git a/utils/response_layout.go b/utils/response_layout.go index f04b965..55ef44f 100644 --- a/utils/response_layout.go +++ b/utils/response_layout.go @@ -6,6 +6,7 @@ import ( "github.com/tigerteufel85/boggy/config" "gopkg.in/andygrunwald/go-jira.v1" "strings" + "time" ) // Layout is a wrapper for layouting the Slack replies @@ -30,6 +31,39 @@ func NewLayout(config config.RegexConfig, input string) *Layout { } } +func (layout *Layout) BuildSimpleTextResponse(config config.JiraConfig, issue jira.Issue, customFields jira.CustomFields, allFields []jira.Field, jql *JQL) string { + responseText := layout.Title + + var components []string + for _, component := range issue.Fields.Components { + components = append(components, component.Name) + } + + var offsetFieldId string + for _, field := range allFields { + if field.Name == jql.OffsetField { + offsetFieldId = field.ID + break + } + } + + loc, _ := time.LoadLocation(config.Location) + timeNow := time.Now().In(loc).Format("2006-01-02") + jiraTime, _ := time.Parse("2006-01-02T15:04:05.000+0000", customFields[offsetFieldId]) + + jiraDate := jiraTime.In(loc).Format("2006-01-02") + if strings.HasPrefix(jiraDate, timeNow) { + jiraDate = "today" + } + + responseText = strings.Replace(responseText, "%component%", getComponentIcon(config, strings.Join(components, ", ")), -1) + responseText = strings.Replace(responseText, "%summary%", issue.Fields.Summary, -1) + responseText = strings.Replace(responseText, "%date%", jiraDate, -1) + responseText = strings.Replace(responseText, "%time%", jiraTime.In(loc).Format("15:04"), -1) + + return responseText +} + // BuildAttachment creates Slack Attachments for Slack replies func (layout *Layout) BuildAttachment(replies config.ReplyConfig, config config.JiraConfig, amount int, issues []jira.Issue) slack.Attachment { option := layout.Option @@ -207,6 +241,14 @@ func createJiraLink(config config.JiraConfig, issueKey string) string { return fmt.Sprintf("<%s/browse/%s|%s>", config.Host, issueKey, issueKey) } +func getComponentIcon(config config.JiraConfig, component string) string { + if val, ok := config.Components[component]; ok { + return val + } + + return component +} + func getPriorityIcon(priorities map[string]config.Priority, id string) string { if val, ok := priorities[strings.ToLower(id)]; ok { return val.Icon From 6c04c134092ee232d9963868e74861ebb3c994b5 Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 17:04:06 +0100 Subject: [PATCH 09/13] Update help and readme --- command/jira_issues_single.go | 4 ++-- readme.md | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/command/jira_issues_single.go b/command/jira_issues_single.go index ff18885..8dd8002 100644 --- a/command/jira_issues_single.go +++ b/command/jira_issues_single.go @@ -105,9 +105,9 @@ func (c *jiraIssuesSingle) GetHelp() []bot.Help { return []bot.Help{ { "jira issues single", - "creates a slack response for each crm sale which will start", + "creates a slack response for each crm sale which will start, the placeholders will be replaced respectively", []string{ - "jira issues single“Campaign Category” = Sale", + "jira single “Campaign Category” = SaleA sale will start in %component% %date% at %time% : %summary%", }, }, } diff --git a/readme.md b/readme.md index 695c094..1579f9e 100644 --- a/readme.md +++ b/readme.md @@ -104,6 +104,17 @@ Query information from Jira for or a whole list of tickets. - filters by a JQL query, please do not add any ordering to it - please use with care as it makes the commands flexible but also more error prone +## JIRA Single +Query information from Jira and posts each issue one by one. + +### Parameters +Generally the same parameters as for "JIRA Issues" can be used but there are a few additional ones. + +#### `` + `` + `` +- queries tickets where the time from the Start Time field starts in 1h and lasts for 10m +- if current time is 2022-01-01 10:00 and with an offset of 1h and time of 10m +- it creates a query like `"Start Time" >= "2022-01-01 11:00" AND "Start Time" <= "2022-01-01 11:10"` + ## Bugs Overview Creates an overview of the current bug status of a project. From f0850006ccc7991f6357fd303ca2b2484914d3e4 Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 17:09:03 +0100 Subject: [PATCH 10/13] Update Dockerfile --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 30afa52..fd8653c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ WORKDIR /boggy/ COPY . ./ RUN apk add git +RUN go mod tidy RUN CGO_ENABLED=0 go build -o /app boggy.go FROM alpine:latest as alpine From 01632b3916ebf35f219c25ff9f9ab315434737e8 Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 17:12:57 +0100 Subject: [PATCH 11/13] Update Makefile --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index f6cc731..1c8f8a6 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ all: clean dep bin/boggy bin/boggy: dep mkdir -p bin/ + go mod tidy GO111MODULE=on go build -ldflags="-s -w" -o bin/boggy *.go clean: From 2a800757ef380c14c40cca5e2c0221c683569f66 Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Tue, 4 Jan 2022 17:27:07 +0100 Subject: [PATCH 12/13] Update build status link --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1579f9e..ef83429 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@ # Boggy -[![Build Status](https://travis-ci.com/tigerteufel85/boggy.svg)](https://travis-ci.com/tigerteufel85/boggy) +[![Build Status](https://app.travis-ci.com/tigerteufel85/boggy.svg)](https://app.travis-ci.com/github/tigerteufel85/boggy) [![GoDoc](https://godoc.org/github.com/tigerteufel85/boggy?status.svg)](https://godoc.org/github.com/innogames/boggy) [![Go Report Card](https://goreportcard.com/badge/github.com/tigerteufel85/boggy)](https://goreportcard.com/report/github.com/tigerteufel85/boggy) [![Release](https://img.shields.io/github/release/tigerteufel85/boggy.svg)](https://github.com/tigerteufel85/boggy/releases) From f43327de490ab484a2e9d848869a2a805f6a2b3e Mon Sep 17 00:00:00 2001 From: Jana Gierloff Date: Wed, 5 Jan 2022 14:10:38 +0100 Subject: [PATCH 13/13] Fix offset parsing --- config/config.example.yaml | 2 +- utils/jira_query.go | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/config/config.example.yaml b/config/config.example.yaml index e9edd88..0edd53f 100644 --- a/config/config.example.yaml +++ b/config/config.example.yaml @@ -162,7 +162,7 @@ regex: jirasorting: "(?i:)" jirastatus: "(?i:)" jiratime: "(?i:)" - jiraoffsettime: "(?i:)" + jiraoffsettime: "(?i:)" jiraoffsetfield: "(?i:)" replycolor: "(?i:)" replylayout: "(?i:)" diff --git a/utils/jira_query.go b/utils/jira_query.go index 02215d3..01da193 100644 --- a/utils/jira_query.go +++ b/utils/jira_query.go @@ -146,9 +146,10 @@ func getStatus(statuses map[string]string, input string) string { } func addTime(startTime time.Time, offset string) time.Time { - timeMinutes := regexp.MustCompile(`^[0-9]*m$`) - timeHours := regexp.MustCompile(`^[0-9]*h$`) - timeDays := regexp.MustCompile(`^[0-9]*d$`) + timeMinutes := regexp.MustCompile(`^[0-9]+m$`) + timeHours := regexp.MustCompile(`^[0-9]+h$`) + timeDays := regexp.MustCompile(`^[0-9]+d$`) + timeWeeks := regexp.MustCompile(`^[0-9]+w$`) returnTime := startTime @@ -162,6 +163,9 @@ func addTime(startTime time.Time, offset string) time.Time { case timeDays.MatchString(offset): timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "d", "")) returnTime = startTime.Add(time.Hour * 24 * time.Duration(timeOffset)) + case timeWeeks.MatchString(offset): + timeOffset, _ := strconv.Atoi(strings.ReplaceAll(offset, "w", "")) + returnTime = startTime.Add(time.Hour * 24 * 7 * time.Duration(timeOffset)) } return returnTime