mirror of
https://gitea.com/gitea/tea.git
synced 2025-09-02 09:58:29 +02:00
Add tea issue edit
(#506)
fixes #229 fixes #502 interactive mode will be in a follow up Co-authored-by: Norwin <git@nroo.de> Co-authored-by: 6543 <6543@obermui.de> Reviewed-on: https://gitea.com/gitea/tea/pulls/506 Reviewed-by: 6543 <6543@obermui.de> Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Norwin <noerw@noreply.gitea.io> Co-committed-by: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
135
modules/task/issue_edit.go
Normal file
135
modules/task/issue_edit.go
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package task
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/context"
|
||||
)
|
||||
|
||||
// EditIssueOption wraps around gitea.EditIssueOption which has bad & incosistent semantics.
|
||||
type EditIssueOption struct {
|
||||
Index int64
|
||||
Title *string
|
||||
Body *string
|
||||
Ref *string
|
||||
Milestone *string
|
||||
Deadline *time.Time
|
||||
AddLabels []string
|
||||
RemoveLabels []string
|
||||
AddAssignees []string
|
||||
// RemoveAssignees []string // NOTE: with the current go-sdk, clearing assignees is not possible.
|
||||
}
|
||||
|
||||
// Normalizes the options into parameters that can be passed to the sdk.
|
||||
// the returned value will be nil, when no change to this part of the issue is requested.
|
||||
func (o EditIssueOption) toSdkOptions(ctx *context.TeaContext, client *gitea.Client) (*gitea.EditIssueOption, *gitea.IssueLabelsOption, *gitea.IssueLabelsOption, error) {
|
||||
// labels have a separate API call, so they get their own options.
|
||||
var addLabelOpts, rmLabelOpts *gitea.IssueLabelsOption
|
||||
if o.AddLabels != nil && len(o.AddLabels) != 0 {
|
||||
ids, err := ResolveLabelNames(client, ctx.Owner, ctx.Repo, o.AddLabels)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
addLabelOpts = &gitea.IssueLabelsOption{Labels: ids}
|
||||
}
|
||||
|
||||
if o.RemoveLabels != nil && len(o.RemoveLabels) != 0 {
|
||||
ids, err := ResolveLabelNames(client, ctx.Owner, ctx.Repo, o.RemoveLabels)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
rmLabelOpts = &gitea.IssueLabelsOption{Labels: ids}
|
||||
}
|
||||
|
||||
issueOpts := gitea.EditIssueOption{}
|
||||
var issueOptsDirty bool
|
||||
if o.Title != nil {
|
||||
issueOpts.Title = *o.Title
|
||||
issueOptsDirty = true
|
||||
}
|
||||
if o.Body != nil {
|
||||
issueOpts.Body = o.Body
|
||||
issueOptsDirty = true
|
||||
}
|
||||
if o.Ref != nil {
|
||||
issueOpts.Ref = o.Ref
|
||||
issueOptsDirty = true
|
||||
}
|
||||
if o.Milestone != nil {
|
||||
if *o.Milestone == "" {
|
||||
issueOpts.Milestone = gitea.OptionalInt64(0)
|
||||
} else {
|
||||
ms, _, err := client.GetMilestoneByName(ctx.Owner, ctx.Repo, *o.Milestone)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("Milestone '%s' not found", *o.Milestone)
|
||||
}
|
||||
issueOpts.Milestone = &ms.ID
|
||||
}
|
||||
issueOptsDirty = true
|
||||
}
|
||||
if o.Deadline != nil {
|
||||
issueOpts.Deadline = o.Deadline
|
||||
issueOptsDirty = true
|
||||
if o.Deadline.IsZero() {
|
||||
issueOpts.RemoveDeadline = gitea.OptionalBool(true)
|
||||
}
|
||||
}
|
||||
if o.AddAssignees != nil && len(o.AddAssignees) != 0 {
|
||||
issueOpts.Assignees = o.AddAssignees
|
||||
issueOptsDirty = true
|
||||
}
|
||||
|
||||
if issueOptsDirty {
|
||||
return &issueOpts, addLabelOpts, rmLabelOpts, nil
|
||||
}
|
||||
return nil, addLabelOpts, rmLabelOpts, nil
|
||||
}
|
||||
|
||||
// EditIssue edits an issue and returns the updated issue.
|
||||
func EditIssue(ctx *context.TeaContext, client *gitea.Client, opts EditIssueOption) (*gitea.Issue, error) {
|
||||
if client == nil {
|
||||
client = ctx.Login.Client()
|
||||
}
|
||||
|
||||
issueOpts, addLabelOpts, rmLabelOpts, err := opts.toSdkOptions(ctx, client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if rmLabelOpts != nil {
|
||||
// NOTE: as of 1.17, there is no API to remove multiple labels at once.
|
||||
for _, id := range rmLabelOpts.Labels {
|
||||
_, err := client.DeleteIssueLabel(ctx.Owner, ctx.Repo, opts.Index, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not remove labels: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if addLabelOpts != nil {
|
||||
_, _, err := client.AddIssueLabels(ctx.Owner, ctx.Repo, opts.Index, *addLabelOpts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not add labels: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
var issue *gitea.Issue
|
||||
if issueOpts != nil {
|
||||
issue, _, err = client.EditIssue(ctx.Owner, ctx.Repo, opts.Index, *issueOpts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not edit issue: %s", err)
|
||||
}
|
||||
} else {
|
||||
issue, _, err = client.GetIssue(ctx.Owner, ctx.Repo, opts.Index)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get issue: %s", err)
|
||||
}
|
||||
}
|
||||
return issue, nil
|
||||
}
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
// ResolveLabelNames returns a list of label IDs for a given list of label names
|
||||
func ResolveLabelNames(client *gitea.Client, owner, repo string, labelNames []string) ([]int64, error) {
|
||||
labelIDs := make([]int64, len(labelNames))
|
||||
labelIDs := make([]int64, 0, len(labelNames))
|
||||
labels, _, err := client.ListRepoLabels(owner, repo, gitea.ListLabelsOptions{
|
||||
ListOptions: gitea.ListOptions{Page: -1},
|
||||
})
|
||||
|
Reference in New Issue
Block a user