grim/youtrack-import

Fix the maxIssues bug where if you didn't specify a number of issues to import it didn't import any issues.
package youtrack
import (
"encoding/xml"
"fmt"
"net/http"
"strings"
"time"
)
type xmlField struct {
XMLName xml.Name `xml:"field"`
Name string `xml:"name,attr"`
Values []string `xml:"value"`
}
type xmlComment struct {
Author string `xml:"author,attr,omitempty"`
Text string `xml:"text,attr,omitempty"`
Created int64 `xml:"created,attr,omitempty"`
Updated int64 `xml:"updated,attr,omitempty"`
Markdown bool `xml:"markdown,attr,omitempty"`
}
type xmlIssue struct {
XMLName xml.Name `xml:"issue"`
Fields []xmlField
Comments []xmlComment `xml:"comment,omitempty"`
}
func (x *xmlIssue) AddField(name, value string) {
x.AddFieldSlice(name, []string{value})
}
func (x *xmlIssue) AddFieldSlice(name string, values []string) {
x.Fields = append(x.Fields, xmlField{Name: name, Values: values})
}
func (x *xmlIssue) AddComment(author, text string, created, updated time.Time, markdown bool) {
c := xmlComment{
Author: author,
Text: text,
Created: formatTime(created),
Updated: formatTime(updated),
Markdown: markdown,
}
x.Comments = append(x.Comments, c)
}
type xmlIssues struct {
XMLName xml.Name `xml:"issues"`
Issues []xmlIssue
}
type xmlImportReportItemError struct {
FieldName string `xml:"fieldName,attr"`
Value string `xml:"value,attr"`
Message string `xml:",chardata"`
}
type xmlImportReportItem struct {
Imported bool `xml:"imported,attr"`
ID string `xml:"id,attr"`
Errors []xmlImportReportItemError `xml:"error"`
}
type xmlImportReport struct {
XMLName xml.Name `xml:"importReport"`
Items []xmlImportReportItem `xml:"item"`
}
func (c *Client) validateXmlImportReport(statusCodes []int, resp *http.Response) error {
if err := c.checkStatuses(resp, statusCodes); err != nil {
return err
}
report := xmlImportReport{}
if err := xml.NewDecoder(resp.Body).Decode(&report); err != nil {
return err
}
if errs := report.Validate(); len(errs) > 0 {
for _, err := range errs {
fmt.Printf("%v\n", err)
}
return fmt.Errorf("failed to import values")
}
return nil
}
func (x *xmlImportReport) Validate() []error {
ret := []error{}
for _, item := range x.Items {
if item.Imported == false {
errMsg := []string{}
for _, e := range item.Errors {
msg := fmt.Sprintf(
"field: %q; value: %q: %s",
e.FieldName,
e.Value,
e.Message,
)
errMsg = append(errMsg, msg)
}
ret = append(ret, fmt.Errorf("%s", strings.Join(errMsg, "\n")))
}
}
return ret
}
type xmlError struct {
XMLName xml.Name `xml:"error"`
Message string `xml:",chardata"`
}
type xmlUser struct {
Login string `xml:"login,attr"`
FullName string `xml:"fullName,attr,omitempty"`
Email string `xml:"email,attr,omitempty"`
}
type xmlUsers struct {
XMLName xml.Name `xml:"list"`
Users []xmlUser `xml:"user"`
}