github.com/posener/gitfs@v1.2.2-0.20200410105819-ea4e48d73ab9/internal/githubfs/project.go (about)

     1  package githubfs
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"regexp"
     7  	"strings"
     8  )
     9  
    10  var (
    11  	reGithubProject = regexp.MustCompile(`^github\.com/([^@/]+)/([^@/]+)(/([^@]*))?(@([^#]+))?$`)
    12  	reSemver        = regexp.MustCompile(`^v?\d+(\.\d+){0,2}$`)
    13  )
    14  
    15  type project struct {
    16  	owner string
    17  	repo  string
    18  	ref   string
    19  	path  string
    20  }
    21  
    22  // newProject parses project name into the different components
    23  // it is composed of.
    24  func newProject(projectName string) (p *project, err error) {
    25  	matches := reGithubProject.FindStringSubmatch(projectName)
    26  	if len(matches) < 2 {
    27  		err = fmt.Errorf("bad project name: %s", projectName)
    28  		return
    29  	}
    30  
    31  	p = &project{
    32  		owner: matches[1],
    33  		repo:  matches[2],
    34  		path:  matches[4],
    35  		ref:   matches[6],
    36  	}
    37  
    38  	// Add "/" suffix to path.
    39  	if len(p.path) > 0 && p.path[len(p.path)-1] != '/' {
    40  		p.path = p.path + "/"
    41  	}
    42  
    43  	// If ref is Semver, add 'tags/' prefix to make it a valid ref.
    44  	if reSemver.MatchString(p.ref) {
    45  		p.ref = "tags/" + p.ref
    46  	}
    47  
    48  	err = verifyRef(p.ref)
    49  	return
    50  }
    51  
    52  func verifyRef(ref string) error {
    53  	if ref != "" && !strings.HasPrefix(ref, "heads/") && !strings.HasPrefix(ref, "tags/") {
    54  		return errors.New("ref must have a 'heads/' or 'tags/' prefix")
    55  	}
    56  	return nil
    57  }