github.com/echohead/hub@v2.2.1+incompatible/github/project.go (about)

     1  package github
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/github/hub/git"
    10  	"github.com/github/hub/utils"
    11  )
    12  
    13  type Project struct {
    14  	Name     string
    15  	Owner    string
    16  	Host     string
    17  	Protocol string
    18  }
    19  
    20  func (p Project) String() string {
    21  	return fmt.Sprintf("%s/%s", p.Owner, p.Name)
    22  }
    23  
    24  func (p *Project) SameAs(other *Project) bool {
    25  	return p.Owner == other.Owner && p.Name == other.Name && p.Host == other.Host
    26  }
    27  
    28  func (p *Project) WebURL(name, owner, path string) string {
    29  	if owner == "" {
    30  		owner = p.Owner
    31  	}
    32  	if name == "" {
    33  		name = p.Name
    34  	}
    35  
    36  	ownerWithName := fmt.Sprintf("%s/%s", owner, name)
    37  	if strings.Contains(ownerWithName, ".wiki") {
    38  		ownerWithName = strings.TrimSuffix(ownerWithName, ".wiki")
    39  		if path != "wiki" {
    40  			if strings.HasPrefix(path, "commits") {
    41  				path = "_history"
    42  			} else if path != "" {
    43  				path = fmt.Sprintf("_%s", path)
    44  			}
    45  
    46  			if path != "" {
    47  				path = utils.ConcatPaths("wiki", path)
    48  			} else {
    49  				path = "wiki"
    50  			}
    51  		}
    52  	}
    53  
    54  	url := fmt.Sprintf("%s://%s", p.Protocol, utils.ConcatPaths(p.Host, ownerWithName))
    55  	if path != "" {
    56  		url = utils.ConcatPaths(url, path)
    57  	}
    58  
    59  	return url
    60  }
    61  
    62  func (p *Project) GitURL(name, owner string, isSSH bool) (url string) {
    63  	if name == "" {
    64  		name = p.Name
    65  	}
    66  	if owner == "" {
    67  		owner = p.Owner
    68  	}
    69  
    70  	host := rawHost(p.Host)
    71  
    72  	if useHttpProtocol() {
    73  		url = fmt.Sprintf("https://%s/%s/%s.git", host, owner, name)
    74  	} else if isSSH {
    75  		url = fmt.Sprintf("git@%s:%s/%s.git", host, owner, name)
    76  	} else {
    77  		url = fmt.Sprintf("git://%s/%s/%s.git", host, owner, name)
    78  	}
    79  
    80  	return url
    81  }
    82  
    83  // Remove the scheme from host when the host url is absolute.
    84  func rawHost(host string) string {
    85  	u, err := url.Parse(host)
    86  	utils.Check(err)
    87  
    88  	if u.IsAbs() {
    89  		return u.Host
    90  	} else {
    91  		return u.Path
    92  	}
    93  }
    94  
    95  func useHttpProtocol() bool {
    96  	https := os.Getenv("HUB_PROTOCOL")
    97  	if https == "" {
    98  		https, _ = git.Config("hub.protocol")
    99  	}
   100  
   101  	return https == "https"
   102  }
   103  
   104  func NewProjectFromURL(url *url.URL) (p *Project, err error) {
   105  	if !knownGitHubHosts().Include(url.Host) {
   106  		err = fmt.Errorf("Invalid GitHub URL: %s", url)
   107  		return
   108  	}
   109  
   110  	parts := strings.SplitN(url.Path, "/", 4)
   111  	if len(parts) <= 2 {
   112  		err = fmt.Errorf("Invalid GitHub URL: %s", url)
   113  		return
   114  	}
   115  
   116  	name := strings.TrimSuffix(parts[2], ".git")
   117  	p = newProject(parts[1], name, url.Host, url.Scheme)
   118  
   119  	return
   120  }
   121  
   122  func NewProject(owner, name, host string) *Project {
   123  	return newProject(owner, name, host, "")
   124  }
   125  
   126  func newProject(owner, name, host, protocol string) *Project {
   127  	if strings.Contains(owner, "/") {
   128  		result := strings.SplitN(owner, "/", 2)
   129  		owner = result[0]
   130  		if name == "" {
   131  			name = result[1]
   132  		}
   133  	} else if strings.Contains(name, "/") {
   134  		result := strings.SplitN(name, "/", 2)
   135  		if owner == "" {
   136  			owner = result[0]
   137  		}
   138  		name = result[1]
   139  	}
   140  
   141  	if host == "" {
   142  		host = DefaultGitHubHost()
   143  	}
   144  	if host == "ssh.github.com" {
   145  		host = "github.com"
   146  	}
   147  
   148  	if protocol != "http" && protocol != "https" {
   149  		protocol = ""
   150  	}
   151  	if protocol == "" {
   152  		h := CurrentConfig().Find(host)
   153  		if h != nil {
   154  			protocol = h.Protocol
   155  		}
   156  	}
   157  	if protocol == "" {
   158  		protocol = "https"
   159  	}
   160  
   161  	if owner == "" {
   162  		h := CurrentConfig().Find(host)
   163  		if h != nil {
   164  			owner = h.User
   165  		}
   166  	}
   167  
   168  	if name == "" {
   169  		name, _ = utils.DirName()
   170  	}
   171  
   172  	return &Project{
   173  		Name:     name,
   174  		Owner:    owner,
   175  		Host:     host,
   176  		Protocol: protocol,
   177  	}
   178  }