github.com/andrewhsu/cli/v2@v2.0.1-0.20210910131313-d4b4061f5b89/pkg/cmd/issue/shared/lookup.go (about) 1 package shared 2 3 import ( 4 "fmt" 5 "net/url" 6 "regexp" 7 "strconv" 8 "strings" 9 10 "github.com/andrewhsu/cli/v2/api" 11 "github.com/andrewhsu/cli/v2/internal/ghrepo" 12 ) 13 14 func IssueFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.Interface, error), arg string) (*api.Issue, ghrepo.Interface, error) { 15 issueNumber, baseRepo := issueMetadataFromURL(arg) 16 17 if issueNumber == 0 { 18 var err error 19 issueNumber, err = strconv.Atoi(strings.TrimPrefix(arg, "#")) 20 if err != nil { 21 return nil, nil, fmt.Errorf("invalid issue format: %q", arg) 22 } 23 } 24 25 if baseRepo == nil { 26 var err error 27 baseRepo, err = baseRepoFn() 28 if err != nil { 29 return nil, nil, fmt.Errorf("could not determine base repo: %w", err) 30 } 31 } 32 33 issue, err := issueFromNumber(apiClient, baseRepo, issueNumber) 34 return issue, baseRepo, err 35 } 36 37 var issueURLRE = regexp.MustCompile(`^/([^/]+)/([^/]+)/issues/(\d+)`) 38 39 func issueMetadataFromURL(s string) (int, ghrepo.Interface) { 40 u, err := url.Parse(s) 41 if err != nil { 42 return 0, nil 43 } 44 45 if u.Scheme != "https" && u.Scheme != "http" { 46 return 0, nil 47 } 48 49 m := issueURLRE.FindStringSubmatch(u.Path) 50 if m == nil { 51 return 0, nil 52 } 53 54 repo := ghrepo.NewWithHost(m[1], m[2], u.Hostname()) 55 issueNumber, _ := strconv.Atoi(m[3]) 56 return issueNumber, repo 57 } 58 59 func issueFromNumber(apiClient *api.Client, repo ghrepo.Interface, issueNumber int) (*api.Issue, error) { 60 return api.IssueByNumber(apiClient, repo, issueNumber) 61 }