feat(milestone): milestone tables, views, forms and one selection model

milestone view printed the list row, and milestone list hid the due date
and progress. milestone list now shows ID TITLE [STATE] DUE PROGRESS, open
milestones first and by due date; milestone view shows the state, due
date, progress, description and the milestone's web page (also --web).

Every milestone command addresses milestones by title or ID. Mutations
report ✓ lines: milestone create also prints the new milestone's URL and
takes the title as an argument; close and reopen skip milestones already
in that state; delete names the milestone in its confirmation; milestone
issue add and remove report one line such as "✓ Added #1, #2 to
milestone "v1.0" in alice/x". milestone issue list uses the issue table.
milestone edit without flags on a terminal opens the milestone form with
the current values, and every milestone command completes milestone
titles and has help text with examples.

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-12 00:17:02 +02:00
1 parent 2ba02cf915
commit c161a63eb6
14 files changed
+606 -257

No files matched your search

+13 -1
View File
@@ -5,14 +5,26 @@ package terminal
import (
"context"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestMilestoneFormMarksTitleRequired(t *testing.T) {
p, rendered := accessiblePrompter(t, "v1\n\n\n")
_, err := p.CreateMilestone(context.Background())
_, err := p.EditMilestone(context.Background(), "", MilestoneFormValues{})
require.NoError(t, err)
require.Contains(t, rendered.String(), "Milestone title (required):")
}
func TestMilestoneFormStartsFromCurrentValues(t *testing.T) {
due := time.Date(2026, 12, 31, 0, 0, 0, 0, time.UTC)
p, _ := testPrompter(strings.NewReader("\r\r\r"))
values, err := p.EditMilestone(context.Background(), "Editing milestone v1.0", MilestoneFormValues{Title: "v1.0", Description: "First", Deadline: &due})
require.NoError(t, err)
require.Equal(t, "v1.0", values.Title)
require.Equal(t, "First", values.Description)
require.Equal(t, due, *values.Deadline)
}