grim/youtrack-import

Split the version field into AffectedVersion and FixVersion while having trac and bitbucket use AffectedVersion. Also put the trac milestone into the Fix Version.
package youtrack
import (
"bytes"
"encoding/xml"
"fmt"
"net/http"
"strings"
)
type User struct {
Login string
FullName string
Email string
Jabber string
}
func NewUser(login, fullName, email string) *User {
return &User{
Login: login,
FullName: fullName,
Email: email,
}
}
func (u *User) encode() xmlUser {
return xmlUser{
Login: u.Login,
FullName: u.FullName,
Email: u.Email,
}
}
func (c *Client) importUsersRange(u []*User, s, e int) []error {
users := &xmlUsers{}
users.Users = make([]xmlUser, e-s)
for i := s; i < e; i++ {
users.Users[i-s] = u[i].encode()
}
data, err := xml.Marshal(users)
if err != nil {
return []error{err}
}
// create the body
putBody := bytes.NewReader(data)
resp, err := c.xmlRequest(
http.MethodPut,
c.uri+"/import/users",
putBody,
)
if err != nil {
return []error{err}
}
defer resp.Body.Close()
if err := c.checkStatuses(resp, []int{http.StatusOK, http.StatusBadRequest}); err != nil {
return []error{err}
}
report := xmlImportReport{}
if err := xml.NewDecoder(resp.Body).Decode(&report); err != nil {
return []error{err}
}
return report.Validate()
}
func (c *Client) ImportUsers(p *Project) error {
r := 5
users := []*User{}
// loop through the users we were given and create a new list based on the
// ones that we need to create.
for _, user := range p.Users {
fmt.Printf("checking if user %q exists ... ", user.Login)
exists, err := c.UserExists(user.Login)
if err != nil {
fmt.Printf("failed.\n")
return err
}
if !exists {
fmt.Printf("no, will be created.\n")
users = append(users, user)
} else {
fmt.Printf("yes.\n")
}
}
if len(users) == 0 {
fmt.Printf("all users exist, nothing to import.\n")
return nil
}
for s := 0; s < len(users); s += r {
e := s + r
if e > len(users) {
e = len(users)
}
sUsers := make([]string, e-s)
for idx, user := range users[s:e] {
sUsers[idx] = user.Login
}
fmt.Printf("importing users %s ... ", strings.Join(sUsers, ", "))
if errs := c.importUsersRange(users, s, e); len(errs) > 0 {
fmt.Printf("failed.\n")
for _, err := range errs {
fmt.Printf("%v\n", err)
}
return fmt.Errorf("error importing users")
}
fmt.Printf("done.\n")
}
return nil
}
func (c *Client) UserExists(username string) (bool, error) {
resp, err := c.xmlRequest(
http.MethodHead,
c.uri+"/user/"+username,
nil,
)
if err != nil {
return false, err
}
if resp.StatusCode == http.StatusBadRequest {
return false, nil
}
return true, nil
}