commit - 82b8536397b0c1fe84af1b0ca1aabf33faaabceb
commit + 6de81a7b43fe19e0a9e9791192ffa8c723c0c4ad
blob - fb5a932b3fc71fc0b29256b428ffa3c53f47ffad
blob + 0fca4f89803514e2c44e429cccfbf22ca671a43a
--- jira/http.go
+++ jira/http.go
"net/url"
"os"
"path"
+ "strings"
)
type Client struct {
APIRoot *url.URL
}
+type errorResponse struct {
+ Errors map[string]string
+}
+
+func (resp errorResponse) Error() string {
+ errs := make([]string, len(resp.Errors))
+ var i int
+ for k, v := range resp.Errors {
+ errs[i] = fmt.Sprintf("%s: %s", k, v)
+ i++
+ }
+ return strings.Join(errs, "; ")
+}
+
func (c *Client) Projects() ([]Project, error) {
u := *c.APIRoot
u.Path = path.Join(u.Path, "project")
if err != nil {
return nil, fmt.Errorf("post json: %w", err)
}
+ defer resp.Body.Close()
if resp.StatusCode >= http.StatusBadRequest {
- return nil, fmt.Errorf("non-ok status: %s", resp.Status)
+ var eresp errorResponse
+ if err := json.NewDecoder(resp.Body).Decode(&eresp); err != nil {
+ return nil, fmt.Errorf("status %s: decode error response: %w", resp.Status, err)
+ }
+ return nil, eresp
}
- return nil, fmt.Errorf("TODO")
+ var created Issue
+ if err := json.NewDecoder(resp.Body).Decode(&created); err != nil {
+ return nil, fmt.Errorf("decode created issue: %w", err)
+ }
+ return &created, nil
}
func (c *Client) PostComment(issueKey string, body io.Reader) error {
blob - a4339567b02f6a29f302567eda5fbba16a3fd198
blob + 3eecbeb0c6c3453c9913ab8c323ee8a3e6d4e38e
--- jira/jira.go
+++ jira/jira.go
const timestamp = "2006-01-02T15:04:05.999-0700"
type Issue struct {
- ID string // TODO(otl): int?
- URL string
- Key string
- Reporter User
- Assignee User
- Summary string
- Status struct {
+ ID string `json:"id,omitempty"` // TODO(otl): int?
+ URL string `json:"url,omitempty"`
+ Key string `json:"key,omitempty"`
+ Reporter *User `json:"reporter,omitempty"`
+ Assignee *User `json:"assignee,omitempty"`
+ Summary string `json:"summary"`
+ Status *struct {
Name string `json:"name"`
- } `json:"status"`
- Description string
- Project Project
- Created time.Time
- Updated time.Time
- Comments []Comment
- Links []Issue
- Subtasks []Issue
+ } `json:"status,omitempty"`
+ Description string `json:"description"`
+ Project Project `json:"project"`
+ Created time.Time `json:"created,omitzero"`
+ Updated time.Time `json:"updated,omitzero"`
+ Type struct {
+ Name string `json:"name"`
+ } `json:"issuetype"`
+ Comments []Comment `json:"comments,omitempty"`
+ Links []Issue `json:"links,omitempty"`
+ Subtasks []Issue `json:"subtasks,omitempty"`
}
type Project struct {
- ID string `json:"id"` // TODO(otl): int?
+ ID string `json:"id,omitempty"` // TODO(otl): int?
// Name string `json:"name"`
- Key string `json:"key"`
- URL string `json:"self"`
+ Key string `json:"key,omitempty"`
+ URL string `json:"self,omitempty"`
}
type Comment struct {
type alias Issue
iaux := &struct {
- Created string
- Updated string
+ Created string `json:"created"`
+ Updated string `json:"updated"`
Comment map[string]json.RawMessage
IssueLinks []struct {
InwardIssue *Issue
}
return nil
}
+
+func (issue *Issue) MarshalJSON() ([]byte, error) {
+ type alias Issue
+ aux := struct {
+ Fields *alias `json:"fields"`
+ }{(*alias)(issue)}
+ return json.Marshal(aux)
+}
blob - 2af937f6316d5c2ea8d6b78d866af66a24992d70
blob + 65b1c6661d55328871224e5b858fc401e0e3f060
--- jira/print.go
+++ jira/print.go
func printIssue(i *Issue) string {
buf := &strings.Builder{}
- fmt.Fprintln(buf, "From:", i.Reporter)
+ if i.Reporter != nil {
+ fmt.Fprintln(buf, "From:", i.Reporter)
+ }
fmt.Fprintln(buf, "Date:", i.Created.Format(time.RFC1123Z))
- if i.Assignee.String() != "" {
+ if i.Assignee != nil {
fmt.Fprintln(buf, "Assignee:", i.Assignee)
}
if u, err := url.Parse(i.URL); err == nil {