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  }