mirror of
				https://gitea.com/gitea/tea.git
				synced 2025-10-31 09:15:26 +01:00 
			
		
		
		
	 b868d30434
			
		
	
	b868d30434
	
	
	
		
			
			Co-authored-by: techknowlogick <hello@techknowlogick.com> Co-committed-by: techknowlogick <hello@techknowlogick.com>
		
			
				
	
	
		
			135 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2022 The Gitea Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| 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
 | |
| }
 |