Files
gitea-tea/internal/app/milestone_state.go
T
bircni 6b204a34c0 refactor(output): share the JSON, created-resource and batch tails
Mutations end with a.jsonResult or a.created instead of hand-rolled
--json branches, the two identical jsonResult/writeMutationJSON helpers
become one, and writeBatchJSON checks --json itself so batch commands
share one tail.

Signed-off-by: bircni <bircni@icloud.com>
2026-10-12 10:43:46 +02:00

60 lines
2.4 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package app
import (
"errors"
"fmt"
"slices"
"strings"
"gitea.dev/tea/internal/clierr"
"gitea.dev/tea/internal/services"
"github.com/spf13/cobra"
)
// milestoneStateCommand closes or reopens milestones, reporting those already in that state instead
// of changing them.
func (a *application) milestoneStateCommand(verb string, service milestoneService) *cobra.Command {
var byName bool
state, past, short := "closed", "Closed", "Close milestones"
if verb == "reopen" {
state, past, short = "open", "Reopened", "Reopen milestones"
}
cmd := &cobra.Command{Use: verb + " <milestone>...", Short: short, Example: fmt.Sprintf(`$ tea milestone %[1]s v1.0
$ tea milestone %[1]s v1.0 v1.1`, verb), Annotations: map[string]string{"tea.arguments": milestoneArguments}, Args: usageArgs(cobra.MinimumNArgs(1)), RunE: func(cmd *cobra.Command, args []string) error {
if slices.ContainsFunc(args, func(arg string) bool { return strings.TrimSpace(arg) == "" }) {
return clierr.Wrap(clierr.Usage, errors.New("milestone title or ID cannot be empty"))
}
milestones, t, err := service(cmd)
if err != nil {
return err
}
selected, err := milestones.Find(cmd.Context(), args, byName)
if err != nil {
return err
}
for i, milestone := range selected {
if slices.ContainsFunc(selected[:i], func(other services.Milestone) bool { return other.ID == milestone.ID }) {
return clierr.Wrap(clierr.Usage, errors.New("milestone "+args[i]+" is selected more than once"))
}
}
results, failures := applyBatch(cmd, selected, func(milestone services.Milestone) string { return "milestone " + milestone.Title }, func(milestone services.Milestone) (services.Milestone, error) {
if milestone.State == state {
a.warn(cmd, "%s is already %s", titleCase(milestoneName(t, milestone)), state)
return milestone, nil
}
item, err := milestones.Edit(cmd.Context(), milestone.ID, services.MilestoneOptions{State: &state})
if err == nil {
a.done(cmd, "%s %s", past, milestoneName(t, item))
}
return item, err
}, nil)
return errors.Join(append(failures, writeBatchJSON(a, cmd, len(selected), results))...)
}}
cmd.Flags().BoolVar(&byName, "by-name", false, "Match numeric arguments as milestone titles rather than IDs")
cmd.ValidArgsFunction = a.completeMilestoneArgs(true)
return cmd
}