github.com/wtfutil/wtf@v0.43.0/modules/jira/client.go (about)

     1  package jira
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/tls"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"net/url"
    10  	"strings"
    11  
    12  	"github.com/wtfutil/wtf/utils"
    13  )
    14  
    15  // IssuesFor returns a collection of issues for a given collection of projects.
    16  // If username is provided, it scopes the issues to that person
    17  func (widget *Widget) IssuesFor(username string, projects []string, jql string) (*SearchResult, error) {
    18  	query := []string{}
    19  
    20  	var projQuery = getProjectQuery(projects)
    21  	if projQuery != "" {
    22  		query = append(query, projQuery)
    23  	}
    24  
    25  	if username != "" {
    26  		query = append(query, buildJql("assignee", username))
    27  	}
    28  
    29  	if jql != "" {
    30  		query = append(query, jql)
    31  	}
    32  
    33  	v := url.Values{}
    34  
    35  	v.Set("jql", strings.Join(query, " AND "))
    36  
    37  	url := fmt.Sprintf("/rest/api/2/search?%s", v.Encode())
    38  
    39  	resp, err := widget.jiraRequest(url)
    40  	if err != nil {
    41  		return &SearchResult{}, err
    42  	}
    43  
    44  	searchResult := &SearchResult{}
    45  	err = utils.ParseJSON(searchResult, bytes.NewReader(resp))
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	return searchResult, nil
    51  }
    52  
    53  func buildJql(key string, value string) string {
    54  	return fmt.Sprintf("%s = \"%s\"", key, value)
    55  }
    56  
    57  /* -------------------- Unexported Functions -------------------- */
    58  
    59  func (widget *Widget) jiraRequest(path string) ([]byte, error) {
    60  	url := fmt.Sprintf("%s%s", widget.settings.domain, path)
    61  
    62  	req, err := http.NewRequest("GET", url, http.NoBody)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	if widget.settings.personalAccessToken != "" {
    67  		req.Header.Set("Authorization", "Bearer "+widget.settings.personalAccessToken)
    68  	} else {
    69  		req.SetBasicAuth(widget.settings.email, widget.settings.apiKey)
    70  	}
    71  
    72  	httpClient := &http.Client{
    73  		Transport: &http.Transport{
    74  			TLSClientConfig: &tls.Config{
    75  				InsecureSkipVerify: !widget.settings.verifyServerCertificate,
    76  			},
    77  			Proxy: http.ProxyFromEnvironment,
    78  		},
    79  	}
    80  
    81  	resp, err := httpClient.Do(req)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	defer func() { _ = resp.Body.Close() }()
    86  
    87  	if resp.StatusCode < 200 || resp.StatusCode > 299 {
    88  		return nil, fmt.Errorf(resp.Status)
    89  	}
    90  
    91  	body, err := io.ReadAll(resp.Body)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	return body, nil
    97  }
    98  
    99  func getProjectQuery(projects []string) string {
   100  	singleEmptyProject := len(projects) == 1 && projects[0] == ""
   101  	if len(projects) == 0 || singleEmptyProject {
   102  		return ""
   103  	} else if len(projects) == 1 {
   104  		return buildJql("project", projects[0])
   105  	}
   106  
   107  	quoted := make([]string, len(projects))
   108  	for i := range projects {
   109  		quoted[i] = fmt.Sprintf("\"%s\"", projects[i])
   110  	}
   111  	return fmt.Sprintf("project in (%s)", strings.Join(quoted, ", "))
   112  }