From 95396115025726d3514df76d63cf1c35f5881d36 Mon Sep 17 00:00:00 2001 From: Benoit Donneaux Date: Tue, 5 Nov 2024 12:00:05 +0100 Subject: [PATCH 1/4] Migrate keywords from Trac tickets to labels Signed-off-by: Benoit Donneaux --- README.md | 4 +-- accessor/trac/accessor.go | 7 +++++ accessor/trac/keywords.go | 47 +++++++++++++++++++++++++++++++ importer/label.go | 14 +++++++++ importer/setup_ticket_test.go | 1 + importer/ticket.go | 9 ++++-- importer/ticketAttachment_test.go | 8 +++--- importer/ticketChange.go | 2 +- importer/ticketComment_test.go | 8 +++--- importer/ticketLabel_test.go | 36 +++++++++++------------ importer/ticketMilestone_test.go | 2 +- importer/ticketOwnership_test.go | 4 +-- importer/ticketStatus_test.go | 4 +-- importer/ticketSummary_test.go | 2 +- importer/ticket_compound_test.go | 4 +-- importer/ticket_test.go | 10 +++---- labelMap.go | 38 ++++++++++++++++--------- main.go | 17 ++++++----- 18 files changed, 152 insertions(+), 65 deletions(-) create mode 100644 accessor/trac/keywords.go diff --git a/README.md b/README.md index b1b07b1..075bef9 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ At present the following Trac data is converted: * Trac users mapped onto Gitea usernames (can be customised by providing an explicit mapping) -* Trac components, priorities, resolutions, severities, types and versions to Gitea labels (can be customised by providing an explicit mapping) +* Trac components, priorities, resolutions, severities, types, keywords and versions to Gitea labels (can be customised by providing an explicit mapping) * Trac milestones to Gitea milestones * Trac tickets to Gitea issues * Trac ticket attachments to Gitea issue attachments * Trac ticket comments to Gitea issue comments with markdown text conversion - * Trac ticket component, priority, resolution, severity, type and version changes to Gitea issue label changes + * Trac ticket component, priority, resolution, severity, type, keywords and version changes to Gitea issue label changes * Trac ticket milestone changes to Gitea issue milestone changes * Trac ticket owner changes to Gitea issue assignee changes * Trac ticket "close" and "reopen" status changes to Gitea issue equivalents diff --git a/accessor/trac/accessor.go b/accessor/trac/accessor.go index 282eab1..846e26e 100644 --- a/accessor/trac/accessor.go +++ b/accessor/trac/accessor.go @@ -39,6 +39,7 @@ type Ticket struct { ResolutionName string SeverityName string TypeName string + KeywordName string VersionName string Status string Created int64 @@ -214,6 +215,12 @@ type Accessor interface { // GetVersions retrieves all versions used in Trac, passing each one to the provided "handler" function. GetVersions(handlerFn func(version *Label) error) error + /* + * Keywords + */ + // GetKeywords retrieves all keywords used in Trac tickets, passing each one to the provided "handler" function. + GetKeywords(handlerFn func(tracKeyword *Label) error) error + /* * Wiki */ diff --git a/accessor/trac/keywords.go b/accessor/trac/keywords.go new file mode 100644 index 0000000..315fe1a --- /dev/null +++ b/accessor/trac/keywords.go @@ -0,0 +1,47 @@ +// Copyright 2020 Steve Jefferson. All rights reserved. +// Use of this source code is governed by a GPL-style +// license that can be found in the LICENSE file. + +package trac + +import ( + "slices" + "strings" + + "github.com/pkg/errors" +) + +// GetKeywords retrieves all keywords used in Trac tickets, passing each one to the provided "handler" function. +func (accessor *DefaultAccessor) GetKeywords(handlerFn func(tracKeyword *Label) error) error { + rows, err := accessor.db.Query(`SELECT DISTINCT keywords FROM ticket`) + if err != nil { + err = errors.Wrapf(err, "retrieving Trac keywords") + return err + } + // Parse each row for multiple keywords separates by coma or spaces + var keywords []string + for rows.Next() { + var rawKeywords string + if err := rows.Scan(&rawKeywords); err != nil { + err = errors.Wrapf(err, "retrieving Trac keywords") + return err + } + rowKeywords := strings.Fields(strings.ReplaceAll(rawKeywords, ",", " ")) + // fmt.Println("Keywords:", rowKeywords) + for j := 0; j < len(rowKeywords); j++ { + if !slices.Contains(keywords, rowKeywords[j]) { + keywords = append(keywords, rowKeywords[j]) + } + } + } + + for i := 0; i < len(keywords); i++ { + keywordName := keywords[i] + tracKeyword := Label{Name: keywordName, Description: ""} + if err = handlerFn(&tracKeyword); err != nil { + return err + } + } + + return nil +} diff --git a/importer/label.go b/importer/label.go index 9ab3e70..4330a3f 100644 --- a/importer/label.go +++ b/importer/label.go @@ -17,6 +17,7 @@ const ( resolutionLabelColor = "#9e9e9e" severityLabelColor = "#eb6420" typeLabelColor = "#e11d21" + keywordLabelColor = "#ff00ff" versionLabelColor = "#009800" ) @@ -64,6 +65,11 @@ func (importer *Importer) DefaultTypeLabelMap() (map[string]string, error) { return importer.defaultLabelMap(trac.Accessor.GetTypes) } +// DefaultKeywordLabelMap retrieves the default mapping between Trac keywords and Gitea labels +func (importer *Importer) DefaultKeywordLabelMap() (map[string]string, error) { + return importer.defaultLabelMap(trac.Accessor.GetKeywords) +} + // DefaultVersionLabelMap retrieves the default mapping between Trac versions and Gitea labels func (importer *Importer) DefaultVersionLabelMap() (map[string]string, error) { return importer.defaultLabelMap(trac.Accessor.GetVersions) @@ -152,6 +158,14 @@ func (importer *Importer) ImportTypes(typeNameMap map[string]string) error { }) } +// ImportKeywords imports Trac keywords as Gitea labels. +func (importer *Importer) ImportKeywords(keywordNameMap map[string]string) error { + return importer.tracAccessor.GetKeywords(func(keyword *trac.Label) error { + _, err := importer.importLabel(keyword, keywordNameMap, keywordLabelColor) + return err + }) +} + // ImportVersions imports Trac versions as Gitea labels. func (importer *Importer) ImportVersions(versionNameMap map[string]string) error { return importer.tracAccessor.GetVersions(func(version *trac.Label) error { diff --git a/importer/setup_ticket_test.go b/importer/setup_ticket_test.go index 004d92a..c18dda7 100644 --- a/importer/setup_ticket_test.go +++ b/importer/setup_ticket_test.go @@ -56,6 +56,7 @@ var ( resolutionMap map[string]string severityMap map[string]string typeMap map[string]string + keywordMap map[string]string versionMap map[string]string revisionMap map[string]string ) diff --git a/importer/ticket.go b/importer/ticket.go index 3bb3908..4566908 100644 --- a/importer/ticket.go +++ b/importer/ticket.go @@ -64,7 +64,7 @@ func (importer *Importer) importTicket(ticket *trac.Ticket, closed bool, userMap // ImportTickets imports Trac tickets as Gitea issues. func (importer *Importer) ImportTickets( - userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap map[string]string) error { + userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap map[string]string) error { err := importer.tracAccessor.GetTickets(func(ticket *trac.Ticket) error { closed := (ticket.Status == string(trac.TicketStatusClosed)) issueID, err := importer.importTicket(ticket, closed, userMap, revisionMap) @@ -100,6 +100,11 @@ func (importer *Importer) ImportTickets( return err } + _, err = importer.importTicketLabel(issueID, ticket.KeywordName, keywordMap) + if err != nil { + return err + } + _, err = importer.importTicketLabel(issueID, ticket.VersionName, versionMap) if err != nil { return err @@ -110,7 +115,7 @@ func (importer *Importer) ImportTickets( return err } lastUpdate, err = importer.importTicketChanges(ticket.TicketID, issueID, lastUpdate, - userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, + userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) if err != nil { return err diff --git a/importer/ticketAttachment_test.go b/importer/ticketAttachment_test.go index a4d0458..58819dd 100644 --- a/importer/ticketAttachment_test.go +++ b/importer/ticketAttachment_test.go @@ -41,7 +41,7 @@ func TestImportTicketWithAttachments(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, closedTicket.issueID, closedTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportMultipleTicketsWithAttachments(t *testing.T) { @@ -88,7 +88,7 @@ func TestImportMultipleTicketsWithAttachments(t *testing.T) { expectIssueDescriptionUpdates(t, closedTicket.issueID, closedTicket.descriptionMarkdown) expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketWithAttachmentButNoTracUser(t *testing.T) { @@ -125,7 +125,7 @@ func TestImportTicketWithAttachmentButNoTracUser(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, noTracUserTicket.issueID, noTracUserTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketWithAttachmentButUnmappedTracUser(t *testing.T) { @@ -162,5 +162,5 @@ func TestImportTicketWithAttachmentButUnmappedTracUser(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, unmappedTracUserTicket.issueID, unmappedTracUserTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/importer/ticketChange.go b/importer/ticketChange.go index 4e53699..694a257 100644 --- a/importer/ticketChange.go +++ b/importer/ticketChange.go @@ -90,7 +90,7 @@ func (importer *Importer) importTicketChanges( ticketID int64, issueID int64, lastUpdate int64, - userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap map[string]string) (int64, error) { + userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap map[string]string) (int64, error) { commentLastUpdate := lastUpdate err := importer.tracAccessor.GetTicketChanges(ticketID, func(change *trac.TicketChange) error { commentID, err := importer.importTicketChange(issueID, change, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) diff --git a/importer/ticketComment_test.go b/importer/ticketComment_test.go index b046b41..9a79d96 100644 --- a/importer/ticketComment_test.go +++ b/importer/ticketComment_test.go @@ -41,7 +41,7 @@ func TestImportTicketWithComments(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, closedTicket.issueID, closedTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportMultipleTicketsWithComments(t *testing.T) { @@ -88,7 +88,7 @@ func TestImportMultipleTicketsWithComments(t *testing.T) { expectIssueDescriptionUpdates(t, closedTicket.issueID, closedTicket.descriptionMarkdown) expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketWithCommentButNoTracUser(t *testing.T) { @@ -125,7 +125,7 @@ func TestImportTicketWithCommentButNoTracUser(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, noTracUserTicket.issueID, noTracUserTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketWithCommentButUnmappedTracUser(t *testing.T) { @@ -162,5 +162,5 @@ func TestImportTicketWithCommentButUnmappedTracUser(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, unmappedTracUserTicket.issueID, unmappedTracUserTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/importer/ticketLabel_test.go b/importer/ticketLabel_test.go index 4d61a4e..3071b26 100644 --- a/importer/ticketLabel_test.go +++ b/importer/ticketLabel_test.go @@ -40,7 +40,7 @@ func TestImportTicketComponentAddition(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketComponentAmend(t *testing.T) { @@ -77,7 +77,7 @@ func TestImportTicketComponentAmend(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketComponentRemoval(t *testing.T) { @@ -114,7 +114,7 @@ func TestImportTicketComponentRemoval(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketPriorityAddition(t *testing.T) { @@ -151,7 +151,7 @@ func TestImportTicketPriorityAddition(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketPriorityAmend(t *testing.T) { @@ -188,7 +188,7 @@ func TestImportTicketPriorityAmend(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketPriorityRemoval(t *testing.T) { @@ -225,7 +225,7 @@ func TestImportTicketPriorityRemoval(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketResolutionAddition(t *testing.T) { @@ -262,7 +262,7 @@ func TestImportTicketResolutionAddition(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketResolutionAmend(t *testing.T) { @@ -299,7 +299,7 @@ func TestImportTicketResolutionAmend(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketResolutionRemoval(t *testing.T) { @@ -336,7 +336,7 @@ func TestImportTicketResolutionRemoval(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketSeverityAddition(t *testing.T) { @@ -373,7 +373,7 @@ func TestImportTicketSeverityAddition(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketSeverityAmend(t *testing.T) { @@ -410,7 +410,7 @@ func TestImportTicketSeverityAmend(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketSeverityRemoval(t *testing.T) { @@ -447,7 +447,7 @@ func TestImportTicketSeverityRemoval(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketTypeAddition(t *testing.T) { @@ -484,7 +484,7 @@ func TestImportTicketTypeAddition(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketTypeAmend(t *testing.T) { @@ -521,7 +521,7 @@ func TestImportTicketTypeAmend(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketTypeRemoval(t *testing.T) { @@ -558,7 +558,7 @@ func TestImportTicketTypeRemoval(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketVersionAddition(t *testing.T) { @@ -595,7 +595,7 @@ func TestImportTicketVersionAddition(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketVersionAmend(t *testing.T) { @@ -632,7 +632,7 @@ func TestImportTicketVersionAmend(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketVersionRemoval(t *testing.T) { @@ -669,5 +669,5 @@ func TestImportTicketVersionRemoval(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/importer/ticketMilestone_test.go b/importer/ticketMilestone_test.go index 6ad0be2..d94280e 100644 --- a/importer/ticketMilestone_test.go +++ b/importer/ticketMilestone_test.go @@ -40,5 +40,5 @@ func TestImportTicketMilestone(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/importer/ticketOwnership_test.go b/importer/ticketOwnership_test.go index 5cb30cf..ac419fe 100644 --- a/importer/ticketOwnership_test.go +++ b/importer/ticketOwnership_test.go @@ -40,7 +40,7 @@ func TestImportTicketOwnershipChange(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketOwnershipRemoval(t *testing.T) { @@ -77,5 +77,5 @@ func TestImportTicketOwnershipRemoval(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/importer/ticketStatus_test.go b/importer/ticketStatus_test.go index 705a62c..f717892 100644 --- a/importer/ticketStatus_test.go +++ b/importer/ticketStatus_test.go @@ -40,7 +40,7 @@ func TestImportTicketClose(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketReopen(t *testing.T) { @@ -77,5 +77,5 @@ func TestImportTicketReopen(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/importer/ticketSummary_test.go b/importer/ticketSummary_test.go index 3801fd3..3d5fb2a 100644 --- a/importer/ticketSummary_test.go +++ b/importer/ticketSummary_test.go @@ -40,5 +40,5 @@ func TestImportTicketSummary(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, nil) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, nil) } diff --git a/importer/ticket_compound_test.go b/importer/ticket_compound_test.go index 9871751..4354f81 100644 --- a/importer/ticket_compound_test.go +++ b/importer/ticket_compound_test.go @@ -51,7 +51,7 @@ func TestImportTicketWithAttachmentsAndComments(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportMultipleTicketsWithAttachmentsAndComments(t *testing.T) { @@ -106,5 +106,5 @@ func TestImportMultipleTicketsWithAttachmentsAndComments(t *testing.T) { expectIssueDescriptionUpdates(t, closedTicket.issueID, closedTicket.descriptionMarkdown) expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/importer/ticket_test.go b/importer/ticket_test.go index 6ffc120..ec2f7a2 100644 --- a/importer/ticket_test.go +++ b/importer/ticket_test.go @@ -39,7 +39,7 @@ func TestImportClosedTicketOnly(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, closedTicket.issueID, closedTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportOpenTicketOnly(t *testing.T) { @@ -73,7 +73,7 @@ func TestImportOpenTicketOnly(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportMultipleTicketsOnly(t *testing.T) { @@ -114,7 +114,7 @@ func TestImportMultipleTicketsOnly(t *testing.T) { expectIssueDescriptionUpdates(t, closedTicket.issueID, closedTicket.descriptionMarkdown) expectIssueDescriptionUpdates(t, openTicket.issueID, openTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketWithNoTracUser(t *testing.T) { @@ -148,7 +148,7 @@ func TestImportTicketWithNoTracUser(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, noTracUserTicket.issueID, noTracUserTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } func TestImportTicketWithUnmappedTracUser(t *testing.T) { @@ -182,5 +182,5 @@ func TestImportTicketWithUnmappedTracUser(t *testing.T) { // expect to update Gitea issue description expectIssueDescriptionUpdates(t, unmappedTracUserTicket.issueID, unmappedTracUserTicket.descriptionMarkdown) - dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) } diff --git a/labelMap.go b/labelMap.go index 3fc58b2..1986bdd 100644 --- a/labelMap.go +++ b/labelMap.go @@ -20,51 +20,57 @@ const ( severityTypeName = "severity" typeTypeName = "type" versionTypeName = "version" + keywordTypeName = "keyword" ) -func readDefaultLabelMaps(dataImporter *importer.Importer) (componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap map[string]string, err error) { +func readDefaultLabelMaps(dataImporter *importer.Importer) (componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap map[string]string, err error) { componentMap, err = dataImporter.DefaultComponentLabelMap() if err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err } priorityMap, err = dataImporter.DefaultPriorityLabelMap() if err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err } resolutionMap, err = dataImporter.DefaultResolutionLabelMap() if err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err } severityMap, err = dataImporter.DefaultSeverityLabelMap() if err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err } typeMap, err = dataImporter.DefaultTypeLabelMap() if err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err + } + + keywordMap, err = dataImporter.DefaultKeywordLabelMap() + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, err } versionMap, err = dataImporter.DefaultVersionLabelMap() if err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err } return } // readLabelMaps reads the label maps from the provided file, if no file provided, import default maps using the provided importer -func readLabelMaps(mapFile string, dataImporter *importer.Importer) (componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap map[string]string, err error) { +func readLabelMaps(mapFile string, dataImporter *importer.Importer) (componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap map[string]string, err error) { if mapFile == "" { return readDefaultLabelMaps(dataImporter) } fd, err := os.Open(mapFile) if err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err } defer fd.Close() @@ -73,6 +79,7 @@ func readLabelMaps(mapFile string, dataImporter *importer.Importer) (componentMa resolutionMap = make(map[string]string) severityMap = make(map[string]string) typeMap = make(map[string]string) + keywordMap = make(map[string]string) versionMap = make(map[string]string) scanner := bufio.NewScanner(fd) @@ -80,13 +87,13 @@ func readLabelMaps(mapFile string, dataImporter *importer.Importer) (componentMa mapLine := scanner.Text() equalsPos := strings.LastIndex(mapLine, "=") if equalsPos == -1 { - return nil, nil, nil, nil, nil, nil, fmt.Errorf("badly formatted label map file %s: expecting '=', found %s", mapFile, mapLine) + return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("badly formatted label map file %s: expecting '=', found %s", mapFile, mapLine) } tracLabelAndType := strings.Trim(mapLine[0:equalsPos], " ") colonPos := strings.LastIndex(tracLabelAndType, ":") if equalsPos == -1 { - return nil, nil, nil, nil, nil, nil, fmt.Errorf("badly formatted label map file %s: expecting ':', found %s", mapFile, mapLine) + return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("badly formatted label map file %s: expecting ':', found %s", mapFile, mapLine) } labelType := strings.Trim(tracLabelAndType[0:colonPos], " ") tracLabel := strings.Trim(tracLabelAndType[colonPos+1:], " ") @@ -103,15 +110,17 @@ func readLabelMaps(mapFile string, dataImporter *importer.Importer) (componentMa severityMap[tracLabel] = giteaLabel case typeTypeName: typeMap[tracLabel] = giteaLabel + case keywordTypeName: + keywordMap[tracLabel] = giteaLabel case versionTypeName: versionMap[tracLabel] = giteaLabel default: - return nil, nil, nil, nil, nil, nil, fmt.Errorf("badly formatted label map file %s: expecting Trac label type before ':', found %s", mapFile, mapLine) + return nil, nil, nil, nil, nil, nil, nil, fmt.Errorf("badly formatted label map file %s: expecting Trac label type before ':', found %s", mapFile, mapLine) } } if err := scanner.Err(); err != nil { - return nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, err } return @@ -127,7 +136,7 @@ func writeLabelMapToFile(fd *os.File, labelType string, labelMap map[string]stri return nil } -func writeLabelMapsToFile(mapFile string, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap map[string]string) error { +func writeLabelMapsToFile(mapFile string, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap map[string]string) error { fd, err := os.Create(mapFile) if err != nil { return err @@ -139,6 +148,7 @@ func writeLabelMapsToFile(mapFile string, componentMap, priorityMap, resolutionM writeLabelMapToFile(fd, resolutionTypeName, resolutionMap) writeLabelMapToFile(fd, severityTypeName, severityMap) writeLabelMapToFile(fd, typeTypeName, typeMap) + writeLabelMapToFile(fd, keywordTypeName, keywordMap) writeLabelMapToFile(fd, versionTypeName, versionMap) return nil diff --git a/main.go b/main.go index e6c5340..9256416 100644 --- a/main.go +++ b/main.go @@ -131,7 +131,7 @@ func parseArgs() { } // importData imports the non-wiki Trac data. -func importData(dataImporter *importer.Importer, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap map[string]string) error { +func importData(dataImporter *importer.Importer, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap map[string]string) error { var err error if err = dataImporter.ImportFullNames(); err != nil { return err @@ -151,13 +151,16 @@ func importData(dataImporter *importer.Importer, userMap, componentMap, priority if err = dataImporter.ImportTypes(typeMap); err != nil { return err } + if err = dataImporter.ImportKeywords(keywordMap); err != nil { + return err + } if err = dataImporter.ImportVersions(versionMap); err != nil { return err } if err = dataImporter.ImportMilestones(); err != nil { return err } - if err = dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap); err != nil { + if err = dataImporter.ImportTickets(userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap); err != nil { return err } @@ -165,9 +168,9 @@ func importData(dataImporter *importer.Importer, userMap, componentMap, priority } // performImport performs the actual import -func performImport(dataImporter *importer.Importer, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap map[string]string) error { +func performImport(dataImporter *importer.Importer, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap map[string]string) error { if !wikiOnly { - if err := importData(dataImporter, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap); err != nil { + if err := importData(dataImporter, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap); err != nil { dataImporter.RollbackImport() return err } @@ -225,7 +228,7 @@ func main() { return } - componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, err := readLabelMaps(labelMapInputFile, dataImporter) + componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, err := readLabelMaps(labelMapInputFile, dataImporter) if err != nil { log.Fatal("%+v", err) return @@ -241,7 +244,7 @@ func main() { log.Info("wrote user map to %s", userMapOutputFile) } if labelMapOutputFile != "" { - if err = writeLabelMapsToFile(labelMapOutputFile, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap); err != nil { + if err = writeLabelMapsToFile(labelMapOutputFile, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap); err != nil { log.Fatal("%+v", err) return } @@ -257,7 +260,7 @@ func main() { return } - err = performImport(dataImporter, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, versionMap, revisionMap) + err = performImport(dataImporter, userMap, componentMap, priorityMap, resolutionMap, severityMap, typeMap, keywordMap, versionMap, revisionMap) if err != nil { log.Fatal("%+v", err) return From 213c54fe59cb6fac9fb2c6bd7836011dd4f8809e Mon Sep 17 00:00:00 2001 From: Benoit Donneaux Date: Wed, 6 Nov 2024 14:29:44 +0100 Subject: [PATCH 2/4] Handle empty keywords in Trac ticket Signed-off-by: Benoit Donneaux --- accessor/trac/keywords.go | 2 +- accessor/trac/ticket.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/accessor/trac/keywords.go b/accessor/trac/keywords.go index 315fe1a..9cbf51c 100644 --- a/accessor/trac/keywords.go +++ b/accessor/trac/keywords.go @@ -13,7 +13,7 @@ import ( // GetKeywords retrieves all keywords used in Trac tickets, passing each one to the provided "handler" function. func (accessor *DefaultAccessor) GetKeywords(handlerFn func(tracKeyword *Label) error) error { - rows, err := accessor.db.Query(`SELECT DISTINCT keywords FROM ticket`) + rows, err := accessor.db.Query(`SELECT DISTINCT COALESCE(keywords,'') keywords FROM ticket`) if err != nil { err = errors.Wrapf(err, "retrieving Trac keywords") return err diff --git a/accessor/trac/ticket.go b/accessor/trac/ticket.go index c5ed9b2..b45b5b4 100644 --- a/accessor/trac/ticket.go +++ b/accessor/trac/ticket.go @@ -19,6 +19,7 @@ func (accessor *DefaultAccessor) GetTickets(handlerFn func(ticket *Ticket) error COALESCE(t.priority,''), COALESCE(t.owner,''), t.reporter, + COALESCE(t.keywords,''), COALESCE(t.version,''), COALESCE(t.milestone,''), lower(COALESCE(t.status, '')), From 82ed196a3ee4792b8d4e3e8796cdbcd570889f87 Mon Sep 17 00:00:00 2001 From: Benoit Donneaux Date: Wed, 6 Nov 2024 14:38:30 +0100 Subject: [PATCH 3/4] Parse keywords in Trac ticket and migrate them as issue label Signed-off-by: Benoit Donneaux --- accessor/trac/accessor.go | 4 +++- accessor/trac/keywords.go | 7 ++++++- accessor/trac/ticket.go | 6 +++--- importer/ticket.go | 8 +++++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/accessor/trac/accessor.go b/accessor/trac/accessor.go index 846e26e..bfbc9fc 100644 --- a/accessor/trac/accessor.go +++ b/accessor/trac/accessor.go @@ -39,7 +39,7 @@ type Ticket struct { ResolutionName string SeverityName string TypeName string - KeywordName string + Keywords string VersionName string Status string Created int64 @@ -218,6 +218,8 @@ type Accessor interface { /* * Keywords */ + // ParseKeywords + ParseKeywords(keywords string) []string // GetKeywords retrieves all keywords used in Trac tickets, passing each one to the provided "handler" function. GetKeywords(handlerFn func(tracKeyword *Label) error) error diff --git a/accessor/trac/keywords.go b/accessor/trac/keywords.go index 9cbf51c..298b743 100644 --- a/accessor/trac/keywords.go +++ b/accessor/trac/keywords.go @@ -11,6 +11,11 @@ import ( "github.com/pkg/errors" ) +// ParseKeywords splits the Trac "keywords" string in a slice of separated keywords +func (accessor *DefaultAccessor) ParseKeywords(keywords string) []string { + return strings.Fields(strings.ReplaceAll(keywords, ",", " ")) +} + // GetKeywords retrieves all keywords used in Trac tickets, passing each one to the provided "handler" function. func (accessor *DefaultAccessor) GetKeywords(handlerFn func(tracKeyword *Label) error) error { rows, err := accessor.db.Query(`SELECT DISTINCT COALESCE(keywords,'') keywords FROM ticket`) @@ -26,7 +31,7 @@ func (accessor *DefaultAccessor) GetKeywords(handlerFn func(tracKeyword *Label) err = errors.Wrapf(err, "retrieving Trac keywords") return err } - rowKeywords := strings.Fields(strings.ReplaceAll(rawKeywords, ",", " ")) + rowKeywords := accessor.ParseKeywords(rawKeywords) // fmt.Println("Keywords:", rowKeywords) for j := 0; j < len(rowKeywords); j++ { if !slices.Contains(keywords, rowKeywords[j]) { diff --git a/accessor/trac/ticket.go b/accessor/trac/ticket.go index b45b5b4..6a5d8a5 100644 --- a/accessor/trac/ticket.go +++ b/accessor/trac/ticket.go @@ -34,16 +34,16 @@ func (accessor *DefaultAccessor) GetTickets(handlerFn func(ticket *Ticket) error for rows.Next() { var ticketID, created, updated int64 - var summary, description, owner, reporter, milestoneName, componentName, priorityName, resolutionName, severityName, typeName, versionName, status string + var summary, description, owner, reporter, milestoneName, componentName, priorityName, resolutionName, severityName, typeName, keywords, versionName, status string if err := rows.Scan(&ticketID, &typeName, &created, &updated, &componentName, &severityName, &priorityName, &owner, &reporter, - &versionName, &milestoneName, &status, &resolutionName, &summary, &description); err != nil { + &keywords, &versionName, &milestoneName, &status, &resolutionName, &summary, &description); err != nil { err = errors.Wrapf(err, "retrieving Trac ticket") return err } ticket := Ticket{TicketID: ticketID, Summary: summary, Description: description, Owner: owner, Reporter: reporter, MilestoneName: milestoneName, ComponentName: componentName, PriorityName: priorityName, ResolutionName: resolutionName, - SeverityName: severityName, TypeName: typeName, VersionName: versionName, Status: status, Created: created, Updated: updated} + SeverityName: severityName, TypeName: typeName, Keywords: keywords, VersionName: versionName, Status: status, Created: created, Updated: updated} if err = handlerFn(&ticket); err != nil { return err diff --git a/importer/ticket.go b/importer/ticket.go index 4566908..bf6be0f 100644 --- a/importer/ticket.go +++ b/importer/ticket.go @@ -100,9 +100,11 @@ func (importer *Importer) ImportTickets( return err } - _, err = importer.importTicketLabel(issueID, ticket.KeywordName, keywordMap) - if err != nil { - return err + for _, keywordName := range importer.tracAccessor.ParseKeywords(ticket.Keywords) { + _, err = importer.importTicketLabel(issueID, keywordName, keywordMap) + if err != nil { + return err + } } _, err = importer.importTicketLabel(issueID, ticket.VersionName, versionMap) From 73e27b5c0633641781c1078df1f83928a76c14cc Mon Sep 17 00:00:00 2001 From: Benoit Donneaux Date: Wed, 6 Nov 2024 14:40:05 +0100 Subject: [PATCH 4/4] Test keywords migration with GoMock Signed-off-by: Benoit Donneaux --- importer/setup_ticket_test.go | 64 ++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/importer/setup_ticket_test.go b/importer/setup_ticket_test.go index c18dda7..75ab07d 100644 --- a/importer/setup_ticket_test.go +++ b/importer/setup_ticket_test.go @@ -67,6 +67,7 @@ func initMaps() { resolutionMap = make(map[string]string) severityMap = make(map[string]string) typeMap = make(map[string]string) + keywordMap = make(map[string]string) versionMap = make(map[string]string) } @@ -103,6 +104,20 @@ var ( severityLabel2 *TicketLabelImport typeLabel1 *TicketLabelImport typeLabel2 *TicketLabelImport + keyword1 string + keyword2 string + keyword3 string + keywordLst1 string + keywordLst2 string + keywordLst3 string + keywordLst4 string + keywordLabel1 *TicketLabelImport + keywordLabel2 *TicketLabelImport + keywordLabel3 *TicketLabelImport + keywordLabelLst1 []*TicketLabelImport + keywordLabelLst2 []*TicketLabelImport + keywordLabelLst3 []*TicketLabelImport + keywordLabelLst4 []*TicketLabelImport versionLabel1 *TicketLabelImport versionLabel2 *TicketLabelImport ) @@ -118,6 +133,20 @@ func setUpTicketLabels(t *testing.T) { severityLabel2 = createTicketLabelImport("severity2", severityMap) typeLabel1 = createTicketLabelImport("type1", typeMap) typeLabel2 = createTicketLabelImport("type2", typeMap) + keyword1 = "keyword1" + keyword2 = "keyword2" + keyword3 = "keyword3" + keywordLst1 = keyword1 + keywordLst2 = keyword1 + " " + keyword2 + keywordLst3 = keyword1 + ", " + keyword2 + "," + keyword3 + keywordLst4 = "" + keywordLabel1 = createTicketLabelImport(keyword1, keywordMap) + keywordLabel2 = createTicketLabelImport(keyword2, keywordMap) + keywordLabel3 = createTicketLabelImport(keyword3, keywordMap) + keywordLabelLst1 = []*TicketLabelImport{keywordLabel1} + keywordLabelLst2 = []*TicketLabelImport{keywordLabel1, keywordLabel2} + keywordLabelLst3 = []*TicketLabelImport{keywordLabel1, keywordLabel2, keywordLabel3} + keywordLabelLst4 = nil versionLabel1 = createTicketLabelImport("version1", versionMap) versionLabel2 = createTicketLabelImport("version2", versionMap) } @@ -137,6 +166,8 @@ type TicketImport struct { resolutionLabel *TicketLabelImport severityLabel *TicketLabelImport typeLabel *TicketLabelImport + keywords string + keywordLabels []*TicketLabelImport versionLabel *TicketLabelImport closed bool status string @@ -154,6 +185,8 @@ func createTicketImport( resolutionLabel *TicketLabelImport, severityLabel *TicketLabelImport, typeLabel *TicketLabelImport, + keywords string, + keywordLabels []*TicketLabelImport, versionLabel *TicketLabelImport) *TicketImport { status := "open" if closed { @@ -174,6 +207,8 @@ func createTicketImport( resolutionLabel: resolutionLabel, severityLabel: severityLabel, typeLabel: typeLabel, + keywords: keywords, + keywordLabels: keywordLabels, versionLabel: versionLabel, closed: closed, status: status, @@ -195,6 +230,7 @@ func createTracTicket(ticket *TicketImport) *trac.Ticket { ResolutionName: ticket.resolutionLabel.tracName, SeverityName: ticket.severityLabel.tracName, TypeName: ticket.typeLabel.tracName, + Keywords: ticket.keywords, VersionName: ticket.versionLabel.tracName, Status: ticket.status, Created: ticket.created, @@ -228,19 +264,19 @@ func setUpTickets(t *testing.T) { closedTicket = createTicketImport( "closed", true, closedTicketOwner, closedTicketReporter, - componentLabel1, priorityLabel1, resolutionLabel1, severityLabel1, typeLabel1, versionLabel1) + componentLabel1, priorityLabel1, resolutionLabel1, severityLabel1, typeLabel1, keywordLst1, keywordLabelLst1, versionLabel1) openTicket = createTicketImport( "open", false, openTicketOwner, openTicketReporter, - componentLabel2, priorityLabel2, resolutionLabel2, severityLabel2, typeLabel2, versionLabel2) + componentLabel2, priorityLabel2, resolutionLabel2, severityLabel2, typeLabel2, keywordLst2, keywordLabelLst2, versionLabel2) noTracUserTicket = createTicketImport( "noTracUser", false, noTracUserTicketOwner, noTracUserTicketReporter, - componentLabel1, priorityLabel1, resolutionLabel1, severityLabel1, typeLabel1, versionLabel1) + componentLabel1, priorityLabel1, resolutionLabel1, severityLabel1, typeLabel1, keywordLst3, keywordLabelLst3, versionLabel1) unmappedTracUserTicket = createTicketImport( "unmappedTracUser", false, unmappedTracUserTicketOwner, unmappedTracUserTicketReporter, - componentLabel1, priorityLabel1, resolutionLabel1, severityLabel1, typeLabel1, versionLabel1) + componentLabel1, priorityLabel1, resolutionLabel1, severityLabel1, typeLabel1, keywordLst4, keywordLabelLst4, versionLabel1) } func expectTracTicketRetrievals(t *testing.T, tickets ...*TicketImport) { @@ -257,6 +293,22 @@ func expectTracTicketRetrievals(t *testing.T, tickets ...*TicketImport) { }) } +func expectTracKeywordsParsing(t *testing.T, ticket *TicketImport, keywordLabels []*TicketLabelImport) { + // expect trac accessor to parse keywords in trac ticket + mockTracAccessor. + EXPECT(). + ParseKeywords(gomock.Any()). + DoAndReturn(func(keywords string) []string { + assertEquals(t, keywords, ticket.keywords) + // Build the expected list of keywords from the labels + var keywordLst []string + for _, keywordLabel := range ticket.keywordLabels { + keywordLst = append(keywordLst, keywordLabel.tracName) + } + return keywordLst + }) +} + func expectDescriptionMarkdownConversion(t *testing.T, ticket *TicketImport) { mockMarkdownConverter. EXPECT(). @@ -369,6 +421,10 @@ func expectAllTicketActions(t *testing.T, ticket *TicketImport) { expectIssueLabelCreation(t, ticket, ticket.resolutionLabel) expectIssueLabelCreation(t, ticket, ticket.severityLabel) expectIssueLabelCreation(t, ticket, ticket.typeLabel) + expectTracKeywordsParsing(t, ticket, ticket.keywordLabels) + for _, keywordLabel := range ticket.keywordLabels { + expectIssueLabelCreation(t, ticket, keywordLabel) + } expectIssueLabelCreation(t, ticket, ticket.versionLabel) // expect the repo issue index to be updated