From 151b1a9508d9a407163edbf3d726b4785afef5ce Mon Sep 17 00:00:00 2001 From: Sybren <122987084+drsybren@users.noreply.github.com> Date: Thu, 19 Jan 2023 03:14:56 +0100 Subject: [PATCH] Support importing comment types (#22510) This commit adds support for specifying comment types when importing with `gitea restore-repo`. It makes it possible to import issue changes, such as "title changed" or "assigned user changed". An earlier version of this pull request was made by Matti Ranta, in https://future.projects.blender.org/blender-migration/gitea-bf/pulls/3 There are two changes with regard to Matti's original code: 1. The comment type was an `int64` in Matti's code, and is now using a string. This makes it possible to use `comment_type: title`, which is more reliable and future-proof than an index into an internal list in the Gitea Go code. 2. Matti's code also had support for including labels, but in a way that would require knowing the database ID of the labels before the import even starts, which is impossible. This can be solved by using label names instead of IDs; for simplicity I I left that out of this PR. --- models/issues/comment.go | 9 +++++++++ models/issues/comment_test.go | 7 +++++++ modules/migration/comment.go | 2 ++ services/migrations/gitea_uploader.go | 23 +++++++++++++++++++++-- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/models/issues/comment.go b/models/issues/comment.go index 87e6b0a229..91dc128277 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -175,6 +175,15 @@ func (t CommentType) String() string { return commentStrings[t] } +func AsCommentType(typeName string) CommentType { + for index, name := range commentStrings { + if typeName == name { + return CommentType(index) + } + } + return CommentTypeUnknown +} + // RoleDescriptor defines comment tag type type RoleDescriptor int diff --git a/models/issues/comment_test.go b/models/issues/comment_test.go index 0d0570ae34..f1232729f1 100644 --- a/models/issues/comment_test.go +++ b/models/issues/comment_test.go @@ -62,3 +62,10 @@ func TestFetchCodeComments(t *testing.T) { assert.NoError(t, err) assert.Len(t, res, 1) } + +func TestAsCommentType(t *testing.T) { + assert.Equal(t, issues_model.CommentTypeUnknown, issues_model.AsCommentType("")) + assert.Equal(t, issues_model.CommentTypeUnknown, issues_model.AsCommentType("nonsense")) + assert.Equal(t, issues_model.CommentTypeComment, issues_model.AsCommentType("comment")) + assert.Equal(t, issues_model.CommentTypePRUnScheduledToAutoMerge, issues_model.AsCommentType("pull_cancel_scheduled_merge")) +} diff --git a/modules/migration/comment.go b/modules/migration/comment.go index 27ecaa830a..f994e972ed 100644 --- a/modules/migration/comment.go +++ b/modules/migration/comment.go @@ -17,6 +17,7 @@ type Commentable interface { type Comment struct { IssueIndex int64 `yaml:"issue_index"` Index int64 + CommentType string `yaml:"comment_type"` // see `commentStrings` in models/issues/comment.go PosterID int64 `yaml:"poster_id"` PosterName string `yaml:"poster_name"` PosterEmail string `yaml:"poster_email"` @@ -24,6 +25,7 @@ type Comment struct { Updated time.Time Content string Reactions []*Reaction + Meta map[string]interface{} `yaml:"meta,omitempty"` // see models/issues/comment.go for fields in Comment struct } // GetExternalName ExternalUserMigrated interface diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 23aa4ac2ca..f43c7378b8 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -454,15 +454,34 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { if comment.Updated.IsZero() { comment.Updated = comment.Created } - + if comment.CommentType == "" { + // if type field is missing, then assume a normal comment + comment.CommentType = issues_model.CommentTypeComment.String() + } cm := issues_model.Comment{ IssueID: issue.ID, - Type: issues_model.CommentTypeComment, + Type: issues_model.AsCommentType(comment.CommentType), Content: comment.Content, CreatedUnix: timeutil.TimeStamp(comment.Created.Unix()), UpdatedUnix: timeutil.TimeStamp(comment.Updated.Unix()), } + switch cm.Type { + case issues_model.CommentTypeAssignees: + cm.AssigneeID = comment.Meta["AssigneeID"].(int64) + if comment.Meta["RemovedAssigneeID"] != nil { + cm.RemovedAssignee = true + } + case issues_model.CommentTypeChangeTitle: + if comment.Meta["OldTitle"] != nil { + cm.OldTitle = fmt.Sprintf("%s", comment.Meta["OldTitle"]) + } + if comment.Meta["NewTitle"] != nil { + cm.NewTitle = fmt.Sprintf("%s", comment.Meta["NewTitle"]) + } + default: + } + if err := g.remapUser(comment, &cm); err != nil { return err }