grim/youtrack-import

d591598025d7
Replace mentions with the youtrack login name. Fixes YI-7
package bitbucket
import (
"fmt"
"hg.sr.ht/~grim/youtrack-import/youtrack"
)
var (
kindMap = map[string]string{
"bug": "Bug",
"enhancement": "Feature",
"proposal": "Feature",
"task": "Task",
}
statusMap = map[string]string{
"new": "Submitted",
"open": "Open",
"resolved": "Fixed",
"on hold": "Incomplete",
"invalid": "Can't Reproduce",
"duplicate": "Duplicate",
"wontfix": "Won't Fix",
"closed": "Fixed",
}
priorityMap = map[string]string{
"trivial": "Minor",
"minor": "Normal",
"major": "Major",
"critical": "Critical",
"blocker": "Show-stopper",
}
)
func (a *Archive) convertIssue(bb Issue, userMap map[string]*youtrack.User) *youtrack.Issue {
reporter := "admin"
if user, found := userMap[bb.Reporter.AccountID]; found {
reporter = user.Login
}
assignee := ""
if user, found := userMap[bb.Assignee.AccountID]; found {
assignee = user.Login
}
yt := &youtrack.Issue{
Number: bb.ID,
Summary: bb.Title,
Description: replaceKeywords(userMap, bb.Content),
Created: bb.CreatedOn,
Updated: bb.UpdatedOn,
Reporter: reporter,
Assignee: assignee,
Priority: bb.Priority,
Type: bb.Kind,
State: bb.Status,
Version: bb.Version,
Subsystem: bb.Component,
Markdown: true,
Comments: []*youtrack.Comment{},
}
// TODO: check if state is resovled then set the Resolved field to the
// UpdatedOn timestamp
// map field values from bitbucket to youtrack
if replace, found := priorityMap[yt.Priority]; found {
yt.Priority = replace
}
if replace, found := kindMap[yt.Type]; found {
yt.Type = replace
}
if replace, found := statusMap[yt.State]; found {
yt.State = replace
}
// add the comments and attachments
yt.Comments = a.convertComments(userMap, bb.ID)
yt.Attachments = a.convertAttachments(userMap, bb)
return yt
}
func (a *Archive) convertComments(userMap map[string]*youtrack.User, id int) []*youtrack.Comment {
comments := []*youtrack.Comment{}
for _, comment := range a.Comments {
if comment.Issue != id {
continue
}
var ytComment *youtrack.Comment
if comment.Content == "" {
// if we don't have a content we need to build it from the log
// entries
for _, log := range a.Logs {
if log.Comment == comment.ID {
author := "admin"
if user, found := userMap[log.User.AccountID]; found {
author = user.Login
}
content := ""
if log.Field == "content" {
content = "edited description"
} else {
content = fmt.Sprintf(
"%s: %s ⟶ %s",
log.Field,
log.ChangedFrom,
log.ChangedTo,
)
}
ytComment = &youtrack.Comment{
Author: author,
Created: log.CreatedOn,
Text: content,
Markdown: true,
}
}
}
} else {
author := "admin"
if user, found := userMap[comment.User.AccountID]; found {
author = user.Login
}
ytComment = &youtrack.Comment{
Author: author,
Text: replaceKeywords(userMap, comment.Content),
Created: comment.CreatedOn,
Updated: comment.UpdatedOn,
Markdown: true,
}
}
comments = append(comments, ytComment)
}
return comments
}
func (a *Archive) convertAttachments(userMap map[string]*youtrack.User, issue Issue) []*youtrack.Attachment {
attachments := []*youtrack.Attachment{}
for _, attachment := range a.Attachments {
if attachment.Issue != issue.ID {
continue
}
author := "admin"
if user, found := userMap[attachment.User.AccountID]; found {
author = user.Login
}
reader, err := a.OpenAttachment(attachment.Path)
if err != nil {
fmt.Printf("%v\n", err)
continue
}
yt := youtrack.NewAttachment(attachment.Issue, author, issue.CreatedOn)
yt.AddFile(reader, attachment.Filename)
attachments = append(attachments, yt)
}
return attachments
}
func (a *Archive) convert(usersMap *UsersMap) (*youtrack.Project, error) {
users, err := a.ExtractUsers(usersMap)
if err != nil {
return nil, err
}
// create a slice of youtrack users for import
ytUsers := make([]*youtrack.User, len(users))
i := 0
for _, user := range users {
ytUsers[i] = user
i++
}
// create a string slice of all the components
components := make([]string, len(a.Components))
for i := 0; i < len(a.Components); i++ {
components[i] = a.Components[i].Name
}
// create a string slice of all the versions
versions := make([]string, len(a.Versions))
for i := 0; i < len(a.Versions); i++ {
versions[i] = a.Versions[i].Name
}
// convert all of the issues
issues := make([]*youtrack.Issue, len(a.Issues))
for i := 0; i < len(a.Issues); i++ {
issues[i] = a.convertIssue(a.Issues[i], users)
}
project := &youtrack.Project{
Users: ytUsers,
Subsystems: components,
Versions: versions,
Issues: issues,
}
return project, nil
}