ref: c8821dbf8966b4e565ad90083ffb50c6987e914d
dir: /utils.go/
package main import ( "fmt" "net/url" "strings" "github.com/andygrunwald/go-jira" "github.com/joushou/qp" ) type SearchResult struct { Issues []jira.Issue `json:"issues"` } func GetProject(jc *Client, projectKey string) (*jira.Project, error) { var project jira.Project url := fmt.Sprintf("/rest/api/2/project/%s", projectKey) if err := jc.RPC("GET", url, nil, &project); err != nil { return nil, fmt.Errorf("could not query projects: %v", err) } return &project, nil } func GetProjects(jc *Client) ([]jira.Project, error) { var projects []jira.Project if err := jc.RPC("GET", "/rest/api/2/project", nil, &projects); err != nil { return nil, fmt.Errorf("could not query projects: %v", err) } return projects, nil } func GetTypesForProject(jc *Client, projectKey string) ([]string, error) { p, err := GetProject(jc, projectKey) if err != nil { return nil, err } ss := make([]string, len(p.IssueTypes)) for i, tp := range p.IssueTypes { ss[i] = tp.Name } return ss, nil } func GetKeysForSearch(jc *Client, query string, max int) ([]string, error) { var s SearchResult url := fmt.Sprintf("/rest/api/2/search?fields=key&maxResults=%d&jql=%s", max, url.QueryEscape(query)) if err := jc.RPC("GET", url, nil, &s); err != nil { return nil, fmt.Errorf("could not execute search: %v", err) } ss := make([]string, len(s.Issues)) for i, issue := range s.Issues { ss[i] = issue.Key } return ss, nil } func GetKeysForNIssuesInProject(jc *Client, project string, max int) ([]string, error) { var s SearchResult url := fmt.Sprintf("/rest/api/2/search?fields=key&maxResults=%d&jql=project=%s", max, project) if err := jc.RPC("GET", url, nil, &s); err != nil { return nil, fmt.Errorf("could not execute search: %v", err) } ss := make([]string, len(s.Issues)) for i, issue := range s.Issues { s := strings.Split(issue.Key, "-") if len(s) != 2 { continue } ss[i] = s[1] } return ss, nil } func GetIssue(jc *Client, key string) (*jira.Issue, error) { var i jira.Issue u := fmt.Sprintf("/rest/api/2/issue/%s", key) if err := jc.RPC("GET", u, nil, &i); err != nil { return nil, fmt.Errorf("could not query issue: %v", err) } return &i, nil } type CreateIssueResult struct { ID string `json:"id,omitempty"` Key string `json:"key,omitempty"` } func CreateIssue(jc *Client, issue *jira.Issue) (string, error) { var cir CreateIssueResult if err := jc.RPC("POST", "/rest/api/2/issue", issue, &cir); err != nil { return "", fmt.Errorf("could not create issue: %v", err) } return cir.Key, nil } func DeleteIssue(jc *Client, issue string) error { url := fmt.Sprintf("/rest/api/2/issue/%s", issue) if err := jc.RPC("DELETE", url, nil, nil); err != nil { return fmt.Errorf("could not delete issue: %v", err) } return nil } func DeleteIssueLink(jc *Client, issueLinkID string) error { url := fmt.Sprintf("/rest/api/2/issueLink/%s", issueLinkID) if err := jc.RPC("DELETE", url, nil, nil); err != nil { return fmt.Errorf("could not delete issue link: %v", err) } return nil } func LinkIssues(jc *Client, inwardKey, outwardKey, relation string) error { issueLink := &jira.IssueLink{ Type: jira.IssueLinkType{ Name: relation, }, InwardIssue: &jira.Issue{ Key: inwardKey, }, OutwardIssue: &jira.Issue{ Key: outwardKey, }, } if err := jc.RPC("POST", "/rest/api/2/issueLink", issueLink, nil); err != nil { return fmt.Errorf("could not create issue link: %v", err) } return nil } func GetWorklogForIssue(jc *Client, issue string) (*jira.Worklog, error) { var w jira.Worklog url := fmt.Sprintf("/rest/api/2/issue/%s/worklog", issue) if err := jc.RPC("GET", url, nil, &w); err != nil { return nil, fmt.Errorf("could not get worklog: %v", err) } return &w, nil } func GetSpecificWorklogForIssue(jc *Client, issue, worklog string) (*jira.WorklogRecord, error) { var w jira.WorklogRecord url := fmt.Sprintf("/rest/api/2/issue/%s/worklog/%s", issue, worklog) if err := jc.RPC("GET", url, nil, &w); err != nil { return nil, fmt.Errorf("could not get worklog: %v", err) } return &w, nil } type Transition struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Fields *jira.IssueFields `json:"fields,omitempty"` } type TransitionResult struct { Transitions []Transition `json:"transitions,omitempty"` } func GetTransitionsForIssue(jc *Client, issue string) ([]Transition, error) { var tr TransitionResult url := fmt.Sprintf("/rest/api/2/issue/%s/transitions", issue) if err := jc.RPC("GET", url, nil, &tr); err != nil { return nil, fmt.Errorf("could not get transitions: %v", err) } return tr.Transitions, nil } func TransitionIssue(jc *Client, issue, transition string) error { transition = strings.Replace(transition, "\n", "", -1) transitions, err := GetTransitionsForIssue(jc, issue) if err != nil { return err } var id string for _, t := range transitions { if transition == t.Name { id = t.ID break } } if id == "" { return fmt.Errorf("no such transition") } post := map[string]interface{}{ "transition": map[string]interface{}{ "id": id, }, } url := fmt.Sprintf("/rest/api/2/issue/%s/transitions", issue) if err := jc.RPC("POST", url, post, nil); err != nil { return fmt.Errorf("could not transition issue: %v", err) } return nil } func SetIssueRaw(jc *Client, issueNo string, b []byte) error { url := fmt.Sprintf("/rest/api/2/issue/%s", issueNo) if err := jc.RPC("PUT", url, b, nil); err != nil { return fmt.Errorf("could not set issue: %v", err) } return nil } func SetFieldInIssue(jc *Client, issue, field, val string) error { switch field { case "type": field = "issuetype" } url := fmt.Sprintf("/rest/api/2/issue/%s", issue) method := "PUT" var value interface{} if val == "" { value = nil } else { value = val } fields := make(map[string]interface{}) post := map[string]interface{}{ "fields": fields, } switch field { case "labels": var labels []string if val != "" && val != "\n" { labels = strings.Split(val, "\n") if labels[len(labels)-1] == "" { labels = labels[:len(labels)-1] } } fields[field] = labels case "components": componentThing := []map[string]string{} components := strings.Split(val, "\n") for _, s := range components { if s == "" || s == "\n" { continue } thing := map[string]string{ "name": s, } componentThing = append(componentThing, thing) } fields[field] = componentThing case "issuetype", "assignee", "reporter", "creator", "priority", "resolution": fields[field] = map[string]interface{}{ "name": value, } default: fields[field] = value } if err := jc.RPC(method, url, post, nil); err != nil { return fmt.Errorf("could not set field for issue: %v", err) } return nil } type CommentResult struct { Comments []jira.Comment `json:"comments,omitempty"` } func GetCommentsForIssue(jc *Client, issue string) ([]string, error) { var cr CommentResult url := fmt.Sprintf("/rest/api/2/issue/%s/comment?maxResults=1000", issue) if err := jc.RPC("GET", url, nil, &cr); err != nil { return nil, fmt.Errorf("could not get comments: %v", err) } var ss []string for _, c := range cr.Comments { ss = append(ss, c.ID) } return ss, nil } func GetComment(jc *Client, issue, id string) (*jira.Comment, error) { var c jira.Comment url := fmt.Sprintf("/rest/api/2/issue/%s/comment/%s", issue, id) if err := jc.RPC("GET", url, nil, &c); err != nil { return nil, fmt.Errorf("could not get comment: %v", err) } return &c, nil } func SetComment(jc *Client, issue, id, body string) error { c := jira.Comment{ Body: body, } url := fmt.Sprintf("/rest/api/2/issue/%s/comment/%s", issue, id) if err := jc.RPC("PUT", url, c, nil); err != nil { return fmt.Errorf("could not set comment: %v", err) } return nil } func AddComment(jc *Client, issue, body string) error { c := jira.Comment{ Body: body, } url := fmt.Sprintf("/rest/api/2/issue/%s/comment/", issue) if err := jc.RPC("POST", url, c, nil); err != nil { return fmt.Errorf("could not add comment: %v", err) } return nil } func RemoveComment(jc *Client, issue, id string) error { url := fmt.Sprintf("/rest/api/2/issue/%s/comment/%s", issue, id) if err := jc.RPC("DELETE", url, nil, nil); err != nil { return fmt.Errorf("could not delete comment: %v", err) } return nil } func StringsToStats(strs []string, Perm qp.FileMode, user, group string) []qp.Stat { var stats []qp.Stat for _, str := range strs { stat := qp.Stat{ Name: str, UID: user, GID: group, MUID: user, Mode: Perm, } stats = append(stats, stat) } return stats } func StringExistsInSets(str string, sets ...[]string) bool { for _, set := range sets { for _, s := range set { if str == s { return true } } } return false }