github.com/Azure/draft@v0.16.0/pkg/draft/pack/repo/repo.go (about)

     1  package repo
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  )
    11  
    12  // ErrPackNotFoundInRepo is the error returned when a pack is not found in a pack repo
    13  var ErrPackNotFoundInRepo = errors.New("pack not found in pack repo")
    14  
    15  // PackDirName is name for the packs directory
    16  const PackDirName = "packs"
    17  
    18  // Repository represents a pack repository.
    19  type Repository struct {
    20  	Name string
    21  	Dir  string
    22  }
    23  
    24  // FindRepositories takes a given path and returns a list of repositories.
    25  //
    26  // Repositories are defined as directories with a "packs" directory present.
    27  func FindRepositories(path string) []Repository {
    28  	var repos []Repository
    29  	// fail fast if directory does not exist
    30  	if _, err := os.Stat(path); os.IsNotExist(err) {
    31  		return repos
    32  	}
    33  	filepath.Walk(path, func(walkPath string, f os.FileInfo, err error) error {
    34  		// find all directories in walkPath that have a child directory called "packs"
    35  		fileInfo, err := os.Stat(filepath.Join(walkPath, PackDirName))
    36  		if err != nil {
    37  			return nil
    38  		}
    39  		if fileInfo.IsDir() {
    40  			repos = append(repos, Repository{
    41  				Name: filepath.ToSlash(strings.TrimPrefix(walkPath, path+string(os.PathSeparator))),
    42  				Dir:  walkPath,
    43  			})
    44  		}
    45  		return nil
    46  	})
    47  	return repos
    48  }
    49  
    50  // Pack finds a packs with the given name in a repository and returns path
    51  func (r *Repository) Pack(name string) (string, error) {
    52  
    53  	//confirm repo exists
    54  	if _, err := os.Stat(r.Dir); os.IsNotExist(err) {
    55  		return "", fmt.Errorf("pack repo %s not found", r.Name)
    56  	}
    57  
    58  	targetDir := filepath.Join(r.Dir, "packs", name)
    59  	if _, err := os.Stat(targetDir); os.IsNotExist(err) {
    60  		return "", ErrPackNotFoundInRepo
    61  	}
    62  
    63  	return targetDir, nil
    64  }
    65  
    66  // List returns a slice of pack names in the repository or error.
    67  //
    68  // The returned pack names are prefixed by the repository name, e.g. "draft/go"
    69  func (r *Repository) List() ([]string, error) {
    70  	packsDir := filepath.Join(r.Dir, PackDirName)
    71  	switch fi, err := os.Stat(packsDir); {
    72  	case err != nil:
    73  		if os.IsNotExist(err) {
    74  			return nil, fmt.Errorf("pack repo %s packs directory not found", r.Name)
    75  		}
    76  	case !fi.IsDir():
    77  		return nil, fmt.Errorf("%s is not a directory", packsDir)
    78  	}
    79  	var packs []string
    80  	files, err := ioutil.ReadDir(packsDir)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	for _, file := range files {
    85  		if file.IsDir() {
    86  			repoPack := filepath.ToSlash(filepath.Join(r.Name, file.Name()))
    87  			packs = append(packs, repoPack)
    88  		}
    89  	}
    90  	return packs, nil
    91  }