github.com/mongodb/grip@v0.0.0-20240213223901-f906268d82b9/message/jira_issue.go (about) 1 package message 2 3 import "fmt" 4 5 type jiraMessage struct { 6 issue *JiraIssue 7 Base 8 } 9 10 // JiraIssue requires project and summary to create a real jira issue. 11 // Other fields depend on permissions given to the specific project, and 12 // all fields must be legitimate custom fields defined for the project. 13 // To see whether you have the right permissions to create an issue with certain 14 // fields, check your JIRA interface on the web. 15 type JiraIssue struct { 16 IssueKey string `bson:"issue_key" json:"issue_key" yaml:"issue_key"` 17 Project string `bson:"project" json:"project" yaml:"project"` 18 Summary string `bson:"summary" json:"summary" yaml:"summary"` 19 Description string `bson:"description" json:"description" yaml:"description"` 20 Reporter string `bson:"reporter" json:"reporter" yaml:"reporter"` 21 Assignee string `bson:"assignee" json:"assignee" yaml:"assignee"` 22 Type string `bson:"type" json:"type" yaml:"type"` 23 Components []string `bson:"components" json:"components" yaml:"components"` 24 Labels []string `bson:"labels" json:"labels" yaml:"labels"` 25 FixVersions []string `bson:"versions" json:"versions" yaml:"versions"` 26 // ... other fields 27 Fields map[string]interface{} `bson:"fields" json:"fields" yaml:"fields"` 28 Callback func(string) `bson:"-" json:"-" yaml:"-"` 29 } 30 31 // JiraField is a struct composed of a key-value pair. 32 type JiraField struct { 33 Key string 34 Value interface{} 35 } 36 37 // MakeJiraMessage creates a jiraMessage instance with the given JiraIssue. 38 func MakeJiraMessage(issue *JiraIssue) Composer { 39 return &jiraMessage{ 40 issue: issue, 41 } 42 } 43 44 // NewJiraMessage creates and returns a fully formed jiraMessage, which implements 45 // message.Composer. project string and summary string are required, and any 46 // number of additional fields may be included. Fields with keys Reporter, Assignee, 47 // Type, and Labels will be specifically assigned to respective fields in the new 48 // jiraIssue included in the jiraMessage, (e.g. JiraIssue.Reporter, etc), and 49 // all other fields will be included in jiraIssue.Fields. 50 func NewJiraMessage(project, summary string, fields ...JiraField) Composer { 51 issue := JiraIssue{ 52 Project: project, 53 Summary: summary, 54 Fields: map[string]interface{}{}, 55 } 56 57 // Assign given fields to jira issue fields 58 for _, f := range fields { 59 switch f.Key { 60 case "reporter", "Reporter": 61 issue.Reporter = f.Value.(string) 62 case "assignee", "Assignee": 63 issue.Assignee = f.Value.(string) 64 case "type", "Type": 65 issue.Type = f.Value.(string) 66 case "labels", "Labels": 67 issue.Labels = f.Value.([]string) 68 case "component", "Component": 69 issue.Components = f.Value.([]string) 70 default: 71 issue.Fields[f.Key] = f.Value 72 } 73 } 74 75 // Setting "Task" as the default value for IssueType 76 if issue.Type == "" { 77 issue.Type = "Task" 78 } 79 80 return MakeJiraMessage(&issue) 81 } 82 83 func (m *jiraMessage) String() string { return m.issue.Summary } 84 func (m *jiraMessage) Raw() interface{} { return m.issue } 85 func (m *jiraMessage) Loggable() bool { return m.issue.Summary != "" && m.issue.Type != "" } 86 func (m *jiraMessage) Annotate(k string, v interface{}) error { 87 if m.issue.Fields == nil { 88 m.issue.Fields = map[string]interface{}{} 89 } 90 91 value, ok := v.(string) 92 if !ok { 93 return fmt.Errorf("value %+v for key %s is not a string, which is required for jira fields", 94 k, v) 95 } 96 97 if _, ok := m.issue.Fields[k]; ok { 98 return fmt.Errorf("value %s already exists", k) 99 } 100 101 m.issue.Fields[k] = value 102 103 return nil 104 }