refactor: extract shared helpers for issue ref resolution and type lookup
Address code review findings: - Extract resolveIssueRef into shared.ResolveIssueRef (was duplicated between create.go and edit.go) - Extract issue type name→ID resolution into shared.ResolveIssueTypeName (was duplicated between create applyIssueTypes and edit applyEditIssueType) - Fix double import of issue/shared in view.go Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
4c12393b88
commit
ddb2fce07b
4 changed files with 57 additions and 68 deletions
|
|
@ -4,7 +4,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
|
|
@ -452,24 +451,11 @@ func applyIssueTypes(client *api.Client, baseRepo ghrepo.Interface, issue *api.I
|
|||
return nil
|
||||
}
|
||||
|
||||
issueTypes, err := api.RepoIssueTypes(client, baseRepo)
|
||||
issueTypeID, err := issueShared.ResolveIssueTypeName(client, baseRepo, opts.IssueType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
issueTypeID := ""
|
||||
typeNames := make([]string, len(issueTypes))
|
||||
for i, t := range issueTypes {
|
||||
typeNames[i] = t.Name
|
||||
if strings.EqualFold(t.Name, opts.IssueType) {
|
||||
issueTypeID = t.ID
|
||||
}
|
||||
}
|
||||
|
||||
if issueTypeID == "" {
|
||||
return fmt.Errorf("type %q not found; available types: %s", opts.IssueType, strings.Join(typeNames, ", "))
|
||||
}
|
||||
|
||||
return api.UpdateIssueIssueType(client, baseRepo.RepoHost(), issue.ID, issueTypeID)
|
||||
}
|
||||
|
||||
|
|
@ -479,7 +465,7 @@ func applyParent(client *api.Client, baseRepo ghrepo.Interface, issue *api.Issue
|
|||
return nil
|
||||
}
|
||||
|
||||
parentID, err := resolveIssueRef(client, baseRepo, opts.Parent)
|
||||
parentID, err := issueShared.ResolveIssueRef(client, baseRepo, opts.Parent)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving parent: %w", err)
|
||||
}
|
||||
|
|
@ -492,7 +478,7 @@ func applyRelationships(client *api.Client, baseRepo ghrepo.Interface, issue *ap
|
|||
hostname := baseRepo.RepoHost()
|
||||
|
||||
for _, ref := range opts.BlockedBy {
|
||||
blockingID, err := resolveIssueRef(client, baseRepo, ref)
|
||||
blockingID, err := issueShared.ResolveIssueRef(client, baseRepo, ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving --blocked-by reference %q: %w", ref, err)
|
||||
}
|
||||
|
|
@ -503,7 +489,7 @@ func applyRelationships(client *api.Client, baseRepo ghrepo.Interface, issue *ap
|
|||
|
||||
for _, ref := range opts.Blocking {
|
||||
// --blocking swaps the args: the OTHER issue is blocked by THIS issue
|
||||
blockedID, err := resolveIssueRef(client, baseRepo, ref)
|
||||
blockedID, err := issueShared.ResolveIssueRef(client, baseRepo, ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving --blocking reference %q: %w", ref, err)
|
||||
}
|
||||
|
|
@ -514,18 +500,3 @@ func applyRelationships(client *api.Client, baseRepo ghrepo.Interface, issue *ap
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// resolveIssueRef parses an issue reference (number or URL) and returns its node ID.
|
||||
func resolveIssueRef(client *api.Client, baseRepo ghrepo.Interface, ref string) (string, error) {
|
||||
number, repo, err := issueShared.ParseIssueFromArg(ref)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
targetRepo := baseRepo
|
||||
if r, ok := repo.Value(); ok {
|
||||
targetRepo = r
|
||||
}
|
||||
|
||||
return api.IssueNodeID(client, targetRepo, number)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -448,20 +447,11 @@ func editRun(opts *EditOptions) error {
|
|||
}
|
||||
|
||||
func applyEditIssueType(client *api.Client, baseRepo ghrepo.Interface, issue *api.Issue, typeName string) error {
|
||||
issueTypes, err := api.RepoIssueTypes(client, baseRepo)
|
||||
issueTypeID, err := issueShared.ResolveIssueTypeName(client, baseRepo, typeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
typeNames := make([]string, len(issueTypes))
|
||||
for i, t := range issueTypes {
|
||||
typeNames[i] = t.Name
|
||||
if strings.EqualFold(t.Name, typeName) {
|
||||
return api.UpdateIssueIssueType(client, baseRepo.RepoHost(), issue.ID, t.ID)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("type %q not found; available types: %s", typeName, strings.Join(typeNames, ", "))
|
||||
return api.UpdateIssueIssueType(client, baseRepo.RepoHost(), issue.ID, issueTypeID)
|
||||
}
|
||||
|
||||
func applyEditParent(client *api.Client, baseRepo ghrepo.Interface, issue *api.Issue, parentRef string) error {
|
||||
|
|
@ -488,7 +478,7 @@ func applyEditParent(client *api.Client, baseRepo ghrepo.Interface, issue *api.I
|
|||
}
|
||||
|
||||
// Set parent with replaceParent=true
|
||||
parentID, err := resolveIssueRef(client, baseRepo, parentRef)
|
||||
parentID, err := issueShared.ResolveIssueRef(client, baseRepo, parentRef)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving parent: %w", err)
|
||||
}
|
||||
|
|
@ -499,7 +489,7 @@ func applyEditSubIssues(client *api.Client, baseRepo ghrepo.Interface, issue *ap
|
|||
hostname := baseRepo.RepoHost()
|
||||
|
||||
for _, ref := range opts.AddSubIssues {
|
||||
subID, err := resolveIssueRef(client, baseRepo, ref)
|
||||
subID, err := issueShared.ResolveIssueRef(client, baseRepo, ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving --add-sub-issue reference %q: %w", ref, err)
|
||||
}
|
||||
|
|
@ -509,7 +499,7 @@ func applyEditSubIssues(client *api.Client, baseRepo ghrepo.Interface, issue *ap
|
|||
}
|
||||
|
||||
for _, ref := range opts.RemoveSubIssues {
|
||||
subID, err := resolveIssueRef(client, baseRepo, ref)
|
||||
subID, err := issueShared.ResolveIssueRef(client, baseRepo, ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving --remove-sub-issue reference %q: %w", ref, err)
|
||||
}
|
||||
|
|
@ -535,7 +525,7 @@ func applyEditRelationships(client *api.Client, baseRepo ghrepo.Interface, issue
|
|||
hostname := baseRepo.RepoHost()
|
||||
|
||||
for _, ref := range opts.AddBlockedBy {
|
||||
blockingID, err := resolveIssueRef(client, baseRepo, ref)
|
||||
blockingID, err := issueShared.ResolveIssueRef(client, baseRepo, ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving --add-blocked-by reference %q: %w", ref, err)
|
||||
}
|
||||
|
|
@ -545,7 +535,7 @@ func applyEditRelationships(client *api.Client, baseRepo ghrepo.Interface, issue
|
|||
}
|
||||
|
||||
for _, ref := range opts.RemoveBlockedBy {
|
||||
blockingID, err := resolveIssueRef(client, baseRepo, ref)
|
||||
blockingID, err := issueShared.ResolveIssueRef(client, baseRepo, ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving --remove-blocked-by reference %q: %w", ref, err)
|
||||
}
|
||||
|
|
@ -556,7 +546,7 @@ func applyEditRelationships(client *api.Client, baseRepo ghrepo.Interface, issue
|
|||
|
||||
for _, ref := range opts.AddBlocking {
|
||||
// --add-blocking swaps args: the OTHER issue is blocked by THIS issue
|
||||
blockedID, err := resolveIssueRef(client, baseRepo, ref)
|
||||
blockedID, err := issueShared.ResolveIssueRef(client, baseRepo, ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving --add-blocking reference %q: %w", ref, err)
|
||||
}
|
||||
|
|
@ -567,18 +557,3 @@ func applyEditRelationships(client *api.Client, baseRepo ghrepo.Interface, issue
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// resolveIssueRef parses an issue reference (number or URL) and returns its node ID.
|
||||
func resolveIssueRef(client *api.Client, baseRepo ghrepo.Interface, ref string) (string, error) {
|
||||
number, repo, err := issueShared.ParseIssueFromArg(ref)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
targetRepo := baseRepo
|
||||
if r, ok := repo.Value(); ok {
|
||||
targetRepo = r
|
||||
}
|
||||
|
||||
return api.IssueNodeID(client, targetRepo, number)
|
||||
}
|
||||
|
|
|
|||
44
pkg/cmd/issue/shared/resolve.go
Normal file
44
pkg/cmd/issue/shared/resolve.go
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package shared
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
)
|
||||
|
||||
// ResolveIssueRef parses an issue reference (number or URL) and returns its node ID.
|
||||
func ResolveIssueRef(client *api.Client, baseRepo ghrepo.Interface, ref string) (string, error) {
|
||||
number, repo, err := ParseIssueFromArg(ref)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
targetRepo := baseRepo
|
||||
if r, ok := repo.Value(); ok {
|
||||
targetRepo = r
|
||||
}
|
||||
|
||||
return api.IssueNodeID(client, targetRepo, number)
|
||||
}
|
||||
|
||||
// ResolveIssueTypeName resolves an issue type name to its ID by fetching
|
||||
// available types from the repository. Returns an error listing available
|
||||
// types if the name is not found.
|
||||
func ResolveIssueTypeName(client *api.Client, repo ghrepo.Interface, typeName string) (string, error) {
|
||||
issueTypes, err := api.RepoIssueTypes(client, repo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
typeNames := make([]string, len(issueTypes))
|
||||
for i, t := range issueTypes {
|
||||
typeNames[i] = t.Name
|
||||
if strings.EqualFold(t.Name, typeName) {
|
||||
return t.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("type %q not found; available types: %s", typeName, strings.Join(typeNames, ", "))
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/cli/cli/v2/internal/gh"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/internal/text"
|
||||
"github.com/cli/cli/v2/pkg/cmd/issue/shared"
|
||||
issueShared "github.com/cli/cli/v2/pkg/cmd/issue/shared"
|
||||
prShared "github.com/cli/cli/v2/pkg/cmd/pr/shared"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
|
|
@ -58,7 +57,7 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
|
|||
`, "`"),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
issueNumber, baseRepo, err := shared.ParseIssueFromArg(args[0])
|
||||
issueNumber, baseRepo, err := issueShared.ParseIssueFromArg(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue