diff --git a/shortcuts/issue/issue.go b/shortcuts/issue/issue.go index 902fda8..a5b6b0d 100644 --- a/shortcuts/issue/issue.go +++ b/shortcuts/issue/issue.go @@ -93,13 +93,14 @@ func Shortcuts() []*common.Shortcut { Name: "view", Description: "View issue details", Flags: []common.Flag{ - {Name: "number", Short: "n", Usage: "Issue number (as shown in the web URL)", Required: true}, + {Name: "number", Short: "n", Usage: "Issue number (as shown in the web URL)"}, + {Name: "id", Usage: "Alias for --number; uses the issue number from the web URL"}, }, Run: func(ctx *common.RuntimeContext) error { if err := ctx.ResolveOwnerRepo(); err != nil { return err } - number, err := ctx.RequireArg("number") + number, err := issueNumberArg(ctx) if err != nil { return err } @@ -226,6 +227,16 @@ func Shortcuts() []*common.Shortcut { } } +func issueNumberArg(ctx *common.RuntimeContext) (string, error) { + if number := strings.TrimSpace(ctx.Arg("number")); number != "" { + return number, nil + } + if id := strings.TrimSpace(ctx.Arg("id")); id != "" { + return id, nil + } + return "", fmt.Errorf("required flag --number (or --id alias) not set") +} + // normalizeIssueListIDs adds "number" (project_issues_index) and renames // "id" to "database_id" so the user-facing output uses the project-level // issue number, not the global database primary key. diff --git a/shortcuts/issue/issue_test.go b/shortcuts/issue/issue_test.go index 088f82c..ebd1901 100644 --- a/shortcuts/issue/issue_test.go +++ b/shortcuts/issue/issue_test.go @@ -100,6 +100,28 @@ func TestIssueUpdatePreservesCurrentSubjectWhenChangingDescription(t *testing.T) assertEqual(t, updatePayload["description"], "New description") } +func TestIssueViewAcceptsIDAsNumberAlias(t *testing.T) { + var requestedPath string + server := newIssueTestServer(t, func(w http.ResponseWriter, r *http.Request) { + requestedPath = r.URL.Path + if r.Method != "GET" || r.URL.Path != "/v1/owner/repo/issues/29.json" { + t.Fatalf("unexpected request: %s %s", r.Method, r.URL.Path) + } + writeJSON(t, w, map[string]interface{}{ + "project_issues_index": 29, + "subject": "Issue from web URL", + }) + }) + defer server.Close() + + err := runIssueShortcut(t, server, "view", map[string]string{"id": "29"}) + if err != nil { + t.Fatalf("view shortcut failed: %v", err) + } + + assertEqual(t, requestedPath, "/v1/owner/repo/issues/29.json") +} + func TestBatchClosePreservesCurrentDescription(t *testing.T) { var updatePayload map[string]interface{} server := newIssueTestServer(t, func(w http.ResponseWriter, r *http.Request) {