github.com/YousefHaggyHeroku/pack@v1.5.5/internal/registry/index.go (about) 1 package registry 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "regexp" 7 8 "github.com/pkg/errors" 9 10 "github.com/YousefHaggyHeroku/pack/internal/style" 11 ) 12 13 var ( 14 validCharsPattern = "[a-z0-9\\-.]+" 15 validCharsRegexp = regexp.MustCompile(fmt.Sprintf("^%s$", validCharsPattern)) 16 ) 17 18 // IndexPath resolves the path for a specific namespace and name of buildpack 19 func IndexPath(rootDir, ns, name string) (string, error) { 20 if err := validateField("namespace", ns); err != nil { 21 return "", err 22 } 23 24 if err := validateField("name", name); err != nil { 25 return "", err 26 } 27 28 var indexDir string 29 switch { 30 case len(name) == 1: 31 indexDir = "1" 32 case len(name) == 2: 33 indexDir = "2" 34 case len(name) == 3: 35 indexDir = filepath.Join("3", name[:2]) 36 default: 37 indexDir = filepath.Join(name[:2], name[2:4]) 38 } 39 40 return filepath.Join(rootDir, indexDir, fmt.Sprintf("%s_%s", ns, name)), nil 41 } 42 43 func validateField(field, value string) error { 44 length := len(value) 45 switch { 46 case length == 0: 47 return errors.Errorf("%s cannot be empty", style.Symbol(field)) 48 case length > 253: 49 return errors.Errorf("%s too long (max 253 chars)", style.Symbol(field)) 50 } 51 52 if !validCharsRegexp.MatchString(value) { 53 return errors.Errorf("%s contains illegal characters (must match %s)", style.Symbol(field), style.Symbol(validCharsPattern)) 54 } 55 56 return nil 57 }