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  }