github.com/remind101/go-getter@v0.0.0-20180809191950-4bda8fa99001/detect_github.go (about)

     1  package getter
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strings"
     7  )
     8  
     9  // GitHubDetector implements Detector to detect GitHub URLs and turn
    10  // them into URLs that the Git Getter can understand.
    11  type GitHubDetector struct{}
    12  
    13  func (d *GitHubDetector) Detect(src, _ string) (string, bool, error) {
    14  	if len(src) == 0 {
    15  		return "", false, nil
    16  	}
    17  
    18  	if strings.HasPrefix(src, "github.com/") {
    19  		return d.detectHTTP(src)
    20  	} else if strings.HasPrefix(src, "git@github.com:") {
    21  		return d.detectSSH(src)
    22  	}
    23  
    24  	return "", false, nil
    25  }
    26  
    27  func (d *GitHubDetector) detectHTTP(src string) (string, bool, error) {
    28  	parts := strings.Split(src, "/")
    29  	if len(parts) < 3 {
    30  		return "", false, fmt.Errorf(
    31  			"GitHub URLs should be github.com/username/repo")
    32  	}
    33  
    34  	urlStr := fmt.Sprintf("https://%s", strings.Join(parts[:3], "/"))
    35  	url, err := url.Parse(urlStr)
    36  	if err != nil {
    37  		return "", true, fmt.Errorf("error parsing GitHub URL: %s", err)
    38  	}
    39  
    40  	if !strings.HasSuffix(url.Path, ".git") {
    41  		url.Path += ".git"
    42  	}
    43  
    44  	if len(parts) > 3 {
    45  		url.Path += "//" + strings.Join(parts[3:], "/")
    46  	}
    47  
    48  	return "git::" + url.String(), true, nil
    49  }
    50  
    51  func (d *GitHubDetector) detectSSH(src string) (string, bool, error) {
    52  	idx := strings.Index(src, ":")
    53  	qidx := strings.Index(src, "?")
    54  	if qidx == -1 {
    55  		qidx = len(src)
    56  	}
    57  
    58  	var u url.URL
    59  	u.Scheme = "ssh"
    60  	u.User = url.User("git")
    61  	u.Host = "github.com"
    62  	u.Path = src[idx+1 : qidx]
    63  	if qidx < len(src) {
    64  		q, err := url.ParseQuery(src[qidx+1:])
    65  		if err != nil {
    66  			return "", true, fmt.Errorf("error parsing GitHub SSH URL: %s", err)
    67  		}
    68  
    69  		u.RawQuery = q.Encode()
    70  	}
    71  
    72  	return "git::" + u.String(), true, nil
    73  }