165 lines
4.2 KiB
Go
165 lines
4.2 KiB
Go
|
|
package cmd
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"code.gitea.io/sdk/gitea"
|
||
|
|
"forgejo.zerova.net/public/fgj-sid/internal/api"
|
||
|
|
"forgejo.zerova.net/public/fgj-sid/internal/config"
|
||
|
|
"github.com/spf13/cobra"
|
||
|
|
)
|
||
|
|
|
||
|
|
var milestoneIssuesCmd = &cobra.Command{
|
||
|
|
Use: "issues",
|
||
|
|
Aliases: []string{"i"},
|
||
|
|
Short: "Manage issues associated with a milestone",
|
||
|
|
Long: "Associate or disassociate issues with a milestone.",
|
||
|
|
}
|
||
|
|
|
||
|
|
var milestoneIssuesAddCmd = &cobra.Command{
|
||
|
|
Use: "add <title-or-id> <issue-number>...",
|
||
|
|
Short: "Add issues to a milestone",
|
||
|
|
Long: "Associate one or more issues with a milestone.",
|
||
|
|
Example: ` # Add issues #5 and #7 to milestone "v1.0"
|
||
|
|
fgj milestone issues add "v1.0" 5 7
|
||
|
|
|
||
|
|
# Add issue #12 to milestone with ID 3 in a specific repo
|
||
|
|
fgj milestone issues add 3 12 -R owner/repo`,
|
||
|
|
Args: cobra.MinimumNArgs(2),
|
||
|
|
RunE: runMilestoneIssuesAdd,
|
||
|
|
}
|
||
|
|
|
||
|
|
var milestoneIssuesRemoveCmd = &cobra.Command{
|
||
|
|
Use: "remove <title-or-id> <issue-number>...",
|
||
|
|
Short: "Remove issues from a milestone",
|
||
|
|
Long: "Disassociate one or more issues from a milestone.",
|
||
|
|
Example: ` # Remove issues #5 and #7 from milestone "v1.0"
|
||
|
|
fgj milestone issues remove "v1.0" 5 7
|
||
|
|
|
||
|
|
# Remove issue #12 from milestone with ID 3 in a specific repo
|
||
|
|
fgj milestone issues remove 3 12 -R owner/repo`,
|
||
|
|
Args: cobra.MinimumNArgs(2),
|
||
|
|
RunE: runMilestoneIssuesRemove,
|
||
|
|
}
|
||
|
|
|
||
|
|
func init() {
|
||
|
|
milestoneCmd.AddCommand(milestoneIssuesCmd)
|
||
|
|
milestoneIssuesCmd.AddCommand(milestoneIssuesAddCmd)
|
||
|
|
milestoneIssuesCmd.AddCommand(milestoneIssuesRemoveCmd)
|
||
|
|
|
||
|
|
addRepoFlags(milestoneIssuesAddCmd)
|
||
|
|
addRepoFlags(milestoneIssuesRemoveCmd)
|
||
|
|
}
|
||
|
|
|
||
|
|
func runMilestoneIssuesAdd(cmd *cobra.Command, args []string) error {
|
||
|
|
repo, _ := cmd.Flags().GetString("repo")
|
||
|
|
|
||
|
|
owner, name, err := parseRepo(repo)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
cfg, err := config.Load()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
ios.StartSpinner("Fetching milestone...")
|
||
|
|
ms, err := resolveMilestone(client, owner, name, args[0])
|
||
|
|
ios.StopSpinner()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
milestoneID := ms.ID
|
||
|
|
cs := ios.ColorScheme()
|
||
|
|
hadError := false
|
||
|
|
|
||
|
|
for _, arg := range args[1:] {
|
||
|
|
issueNum, parseErr := parseIssueArg(arg)
|
||
|
|
if parseErr != nil {
|
||
|
|
fmt.Fprintf(ios.ErrOut, "invalid issue number %q: %v\n", arg, parseErr)
|
||
|
|
hadError = true
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
_, _, editErr := client.EditIssue(owner, name, issueNum, gitea.EditIssueOption{
|
||
|
|
Milestone: &milestoneID,
|
||
|
|
})
|
||
|
|
if editErr != nil {
|
||
|
|
fmt.Fprintf(ios.ErrOut, "failed to add issue #%d to milestone %q: %v\n", issueNum, ms.Title, editErr)
|
||
|
|
hadError = true
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
fmt.Fprintf(ios.Out, "%s Added issue #%d to milestone %q\n", cs.SuccessIcon(), issueNum, ms.Title)
|
||
|
|
}
|
||
|
|
|
||
|
|
if hadError {
|
||
|
|
return fmt.Errorf("one or more issues could not be added to milestone %q", ms.Title)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func runMilestoneIssuesRemove(cmd *cobra.Command, args []string) error {
|
||
|
|
repo, _ := cmd.Flags().GetString("repo")
|
||
|
|
|
||
|
|
owner, name, err := parseRepo(repo)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
cfg, err := config.Load()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
ios.StartSpinner("Fetching milestone...")
|
||
|
|
ms, err := resolveMilestone(client, owner, name, args[0])
|
||
|
|
ios.StopSpinner()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
cs := ios.ColorScheme()
|
||
|
|
hadError := false
|
||
|
|
var zero int64 = 0
|
||
|
|
|
||
|
|
for _, arg := range args[1:] {
|
||
|
|
issueNum, parseErr := parseIssueArg(arg)
|
||
|
|
if parseErr != nil {
|
||
|
|
fmt.Fprintf(ios.ErrOut, "invalid issue number %q: %v\n", arg, parseErr)
|
||
|
|
hadError = true
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
// Setting Milestone to a pointer-to-zero clears the milestone association
|
||
|
|
// in Gitea's API (PATCH /repos/{owner}/{repo}/issues/{num} with {"milestone": 0}).
|
||
|
|
_, _, editErr := client.EditIssue(owner, name, issueNum, gitea.EditIssueOption{
|
||
|
|
Milestone: &zero,
|
||
|
|
})
|
||
|
|
if editErr != nil {
|
||
|
|
fmt.Fprintf(ios.ErrOut, "failed to remove issue #%d from milestone %q: %v\n", issueNum, ms.Title, editErr)
|
||
|
|
hadError = true
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
fmt.Fprintf(ios.Out, "%s Removed issue #%d from milestone %q\n", cs.SuccessIcon(), issueNum, ms.Title)
|
||
|
|
}
|
||
|
|
|
||
|
|
if hadError {
|
||
|
|
return fmt.Errorf("one or more issues could not be removed from milestone %q", ms.Title)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|