fix(milestone): address milestones by title or ID everywhere

milestone view v2.0 failed with "invalid resource number" although its
usage promised <id-or-name>, and issue create --milestone v1.0 failed
with a strconv error. Every milestone argument (view, edit, delete,
close, reopen, milestone issue add|remove|list) and issue create|edit
-m/--milestone now accept a title or an ID: a number is an ID first,
then a title; --by-name matches numeric titles only. --milestone-name
stays as a hidden name of --milestone, and issue edit gains
--remove-milestone (as does --milestone 0).

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-12 00:14:30 +02:00
1 parent 0d013746b5
commit 1035ff551b
12 files changed
+220 -147

No files matched your search

+16 -31
View File
@@ -205,8 +205,8 @@ func (a *application) milestoneCommand() *cobra.Command {
if verb == "create" {
command.Args = argsExact(0)
} else {
command.Use += " <id-or-name>"
command.Flags().BoolVar(&byName, "by-name", false, "Select by exact milestone title instead of ID")
command.Use += " <milestone>"
command.Flags().BoolVar(&byName, "by-name", false, "Match a numeric argument as a milestone title rather than an ID")
command.Args = argsExact(1)
}
if verb == "create" || verb == "edit" {
@@ -228,12 +228,8 @@ func (a *application) milestoneCommand() *cobra.Command {
}
}
opts := services.MilestoneOptions{}
var id int64
if verb != "create" {
var err error
if id, err = milestoneSelector(args[0], byName); err != nil {
return err
}
if verb != "create" && strings.TrimSpace(args[0]) == "" {
return clierr.Wrap(clierr.Usage, errors.New("milestone title or ID cannot be empty"))
}
var interactiveDeadline *time.Time
descriptionChanged := false
@@ -297,38 +293,27 @@ func (a *application) milestoneCommand() *cobra.Command {
if err != nil {
return err
}
if byName {
id, err = s.ResolveName(cmd.Context(), args[0])
if err != nil {
var current services.Milestone
if verb != "create" {
if current, err = s.FindOne(cmd.Context(), args[0], byName); err != nil {
return err
}
}
id := current.ID
if verb == "delete" {
if err := a.confirm(cmd, "Delete milestone "+args[0]); err != nil {
return err
}
if a.options.json != "" {
item, err := s.View(cmd.Context(), id)
if err != nil {
return err
}
if err := s.Delete(cmd.Context(), id); err != nil {
return err
}
return writeItem(a, cmd, item, milestoneRow)
if err := s.Delete(cmd.Context(), id); err != nil {
return err
}
return s.Delete(cmd.Context(), id)
if a.options.json != "" {
return writeItem(a, cmd, current, milestoneRow)
}
return nil
}
if useEditor {
initial := ""
if verb == "edit" {
current, viewErr := s.View(cmd.Context(), id)
if viewErr != nil {
return viewErr
}
initial = current.Description
}
editorDraft, err = a.editDraft(cmd, initial)
editorDraft, err = a.editDraft(cmd, current.Description)
if err != nil {
return err
}
@@ -340,7 +325,7 @@ func (a *application) milestoneCommand() *cobra.Command {
}
var item services.Milestone
if verb == "view" {
item, err = s.View(cmd.Context(), id)
item = current
} else if verb == "create" {
item, err = s.Create(cmd.Context(), opts)
} else {