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  }