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 }