grim/youtrack-import

Parents a515c4b3d465
Children 0ce6488c1f5f
handle users better and map status, type, and priorities and load subsystems as well
--- a/trac/cmd.go Fri Jul 03 20:12:12 2020 -0500
+++ b/trac/cmd.go Fri Jul 03 22:56:34 2020 -0500
@@ -7,7 +7,9 @@
)
type Cmd struct {
- EnvPath string `kong:"arg,name='tracenv',help='The path to the trac environment'"`
+ EnvPath string `kong:"arg,name='tracenv',help='The path to the trac environment'"`
+ ImportUsers string `kong:"flag,name='import-users',help='The json file of users to import',required='true',type='existingfile'"`
+ UnknownUser string `kong:"flag,name='unknown-user',help='The login name to use for unknown users',default='ghost'"`
}
func (c *Cmd) Run(g *globals.Globals) error {
@@ -18,7 +20,7 @@
return err
}
- project, err := createProject(env)
+ project, err := createProject(env, c.ImportUsers, c.UnknownUser)
mem.PrintMemUsage()
if err != nil {
return err
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/trac/components.go Fri Jul 03 22:56:34 2020 -0500
@@ -0,0 +1,13 @@
+package trac
+
+import ()
+
+func (e *environment) loadComponents() ([]string, error) {
+ components := []string{}
+ err := e.db.Select(
+ &components,
+ "SELECT distinct(component) from ticket ORDER BY component ASC",
+ )
+
+ return components, err
+}
--- a/trac/project.go Fri Jul 03 20:12:12 2020 -0500
+++ b/trac/project.go Fri Jul 03 22:56:34 2020 -0500
@@ -6,14 +6,19 @@
"keep.imfreedom.org/grim/youtrack-import/youtrack"
)
-func createProject(e *environment) (*youtrack.Project, error) {
- users, err := e.loadUsers()
+func createProject(e *environment, importUsersFile, defaultUser string) (*youtrack.Project, error) {
+ users, err := e.loadUsers(importUsersFile)
if err != nil {
return nil, err
}
fmt.Printf("loaded %d users\n", len(users))
+ components, err := e.loadComponents()
+ if err != nil {
+ return nil, err
+ }
+
tracTickets, err := e.loadTickets()
if err != nil {
return nil, err
@@ -21,7 +26,7 @@
issues := make([]*youtrack.Issue, len(tracTickets))
for idx, ticket := range tracTickets {
- issue, err := ticket.toYoutrack()
+ issue, err := ticket.toYoutrack(defaultUser, users)
if err != nil {
return nil, err
}
@@ -29,8 +34,17 @@
issues[idx] = issue
}
+ sliceUsers := make([]*youtrack.User, len(users))
+ idx := 0
+ for _, user := range users {
+ sliceUsers[idx] = user
+ idx++
+ }
+
project := &youtrack.Project{
- Issues: issues,
+ Issues: issues,
+ Users: sliceUsers,
+ Subsystems: components,
}
fmt.Printf("Project: has %d issues\n", len(issues))
--- a/trac/tickets.go Fri Jul 03 20:12:12 2020 -0500
+++ b/trac/tickets.go Fri Jul 03 22:56:34 2020 -0500
@@ -45,29 +45,68 @@
Value sql.NullString `db`
}
-func (t *ticket) toYoutrack() (*youtrack.Issue, error) {
+var (
+ typeMap = map[string]string{
+ "defect": "Bug",
+ "enhancement": "Feature",
+ "patch": "Feature",
+ "plugin request": "Feature",
+ "rejected_patch": "Feature",
+ "task": "Task",
+ "translation": "Feature",
+ }
+
+ stateMap = map[string]string{
+ "closed": "Fixed",
+ "new": "Submitted",
+ "pending": "To be discussed",
+ }
+
+ priorityMap = map[string]string{
+ "": "Normal",
+ "blocker": "Show-stopper",
+ "critical": "Critical",
+ "major": "Major",
+ "minor": "Normal",
+ "trivial": "Minor",
+ }
+)
+
+func (t *ticket) toYoutrack(defaultUser string, users map[string]*youtrack.User) (*youtrack.Issue, error) {
+ convertUsername := func(sqluser sql.NullString) string {
+ username := convertString(sqluser)
+ if user, found := users[username]; found {
+ return user.Login
+ }
+
+ return defaultUser
+ }
+
issue := &youtrack.Issue{
Number: t.ID,
Summary: t.Summary,
Description: t.Description,
Created: convertTime(t.Time),
Updated: convertTime(t.ChangeTime),
- Reporter: convertString(t.Reporter),
- Assignee: convertString(t.Owner),
+ Reporter: convertUsername(t.Reporter),
+ Assignee: convertUsername(t.Owner),
Markdown: false,
Version: convertString(t.Version),
Subsystem: convertString(t.Component),
- Priority: convertString(t.Priority),
- Type: t.Type,
- State: t.Status,
+ Priority: priorityMap[convertString(t.Priority)],
+ Type: typeMap[t.Type],
+ State: stateMap[t.Status],
}
- // convert the trac cc to a string slice
+ // convert the trac cc to a string slice of known youtrack users
watchers := strings.Split(convertString(t.CarbonCopy), ",")
- for idx, watcher := range watchers {
- watchers[idx] = strings.TrimSpace(watcher)
+ ytWatchers := []string{}
+ for _, watcher := range watchers {
+ if ytUser, found := users[watcher]; found {
+ ytWatchers = append(ytWatchers, ytUser.Login)
+ }
}
- issue.Watchers = watchers
+ issue.Watchers = ytWatchers
// walk through the changes and update fields as necessary
for _, change := range t.Changes {
--- a/trac/users.go Fri Jul 03 20:12:12 2020 -0500
+++ b/trac/users.go Fri Jul 03 22:56:34 2020 -0500
@@ -1,6 +1,10 @@
package trac
import (
+ "encoding/json"
+ "io/ioutil"
+ "strings"
+
"keep.imfreedom.org/grim/youtrack-import/youtrack"
)
@@ -11,30 +15,43 @@
Value string `db:"value"`
}
-func (e *environment) loadUsers() (map[string]*youtrack.User, error) {
- var err error
+type importUsers struct {
+ Users map[string]importUser `json:"users"`
+}
- users := map[string]*youtrack.User{}
+type importUser struct {
+ Login string `json:"login"`
+ FullName string `json:"fullname"`
+ Email string `json:"email"`
+}
- sessionAttributes := []sessionAttribute{}
- err = e.db.Select(&sessionAttributes, "SELECT * FROM session_attribute WHERE name = 'name' or name = 'email'")
+func loadImportUsers(importUsersFile string) (*importUsers, error) {
+ data, err := ioutil.ReadFile(importUsersFile)
if err != nil {
return nil, err
}
- for _, sessionAttribute := range sessionAttributes {
- user, found := users[sessionAttribute.Sid]
- if !found {
- sid := sessionAttribute.Sid
- user = &youtrack.User{Login: sid}
- users[sid] = user
- }
+ importUsers := &importUsers{}
+ err = json.Unmarshal(data, importUsers)
+
+ return importUsers, err
+}
+
+func (e *environment) loadUsers(importUsersFile string) (map[string]*youtrack.User, error) {
+ var err error
- switch sessionAttribute.Name {
- case "name":
- user.FullName = sessionAttribute.Value
- case "email":
- user.Email = sessionAttribute.Value
+ importUsers, err := loadImportUsers(importUsersFile)
+ if err != nil {
+ return nil, err
+ }
+
+ users := map[string]*youtrack.User{}
+
+ for tracId, user := range importUsers.Users {
+ users[tracId] = &youtrack.User{
+ Login: strings.TrimSpace(user.Login),
+ FullName: strings.TrimSpace(user.FullName),
+ Email: strings.TrimSpace(user.Email),
}
}