github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/manifest/manifest_disk_repository.go (about)

     1  package manifest
     2  
     3  import (
     4  	"io"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"github.com/cloudfoundry/cli/cf/errors"
    10  	. "github.com/cloudfoundry/cli/cf/i18n"
    11  	"github.com/cloudfoundry/cli/generic"
    12  	"gopkg.in/yaml.v2"
    13  )
    14  
    15  type ManifestRepository interface {
    16  	ReadManifest(string) (*Manifest, error)
    17  }
    18  
    19  type ManifestDiskRepository struct{}
    20  
    21  func NewManifestDiskRepository() (repo ManifestRepository) {
    22  	return ManifestDiskRepository{}
    23  }
    24  
    25  func (repo ManifestDiskRepository) ReadManifest(inputPath string) (*Manifest, error) {
    26  	m := NewEmptyManifest()
    27  	manifestPath, err := repo.manifestPath(inputPath)
    28  
    29  	if err != nil {
    30  		return m, errors.NewWithError(T("Error finding manifest"), err)
    31  	}
    32  
    33  	m.Path = manifestPath
    34  
    35  	mapp, err := repo.readAllYAMLFiles(manifestPath)
    36  	if err != nil {
    37  		return m, err
    38  	}
    39  
    40  	m.Data = mapp
    41  
    42  	return m, nil
    43  }
    44  
    45  func (repo ManifestDiskRepository) readAllYAMLFiles(path string) (mergedMap generic.Map, err error) {
    46  	file, err := os.Open(filepath.Clean(path))
    47  	if err != nil {
    48  		return
    49  	}
    50  	defer file.Close()
    51  
    52  	mapp, err := parseManifest(file)
    53  	if err != nil {
    54  		return
    55  	}
    56  
    57  	if !mapp.Has("inherit") {
    58  		mergedMap = mapp
    59  		return
    60  	}
    61  
    62  	inheritedPath, ok := mapp.Get("inherit").(string)
    63  	if !ok {
    64  		err = errors.New(T("invalid inherit path in manifest"))
    65  		return
    66  	}
    67  
    68  	if !filepath.IsAbs(inheritedPath) {
    69  		inheritedPath = filepath.Join(filepath.Dir(path), inheritedPath)
    70  	}
    71  
    72  	inheritedMap, err := repo.readAllYAMLFiles(inheritedPath)
    73  	if err != nil {
    74  		return
    75  	}
    76  
    77  	mergedMap = generic.DeepMerge(inheritedMap, mapp)
    78  	return
    79  }
    80  
    81  func parseManifest(file io.Reader) (yamlMap generic.Map, err error) {
    82  	manifest, err := ioutil.ReadAll(file)
    83  	if err != nil {
    84  		return
    85  	}
    86  
    87  	mmap := make(map[interface{}]interface{})
    88  	err = yaml.Unmarshal(manifest, &mmap)
    89  	if err != nil {
    90  		return
    91  	}
    92  
    93  	if !generic.IsMappable(mmap) || len(mmap) == 0 {
    94  		err = errors.New(T("Invalid manifest. Expected a map"))
    95  		return
    96  	}
    97  
    98  	yamlMap = generic.NewMap(mmap)
    99  
   100  	return
   101  }
   102  
   103  func (repo ManifestDiskRepository) manifestPath(userSpecifiedPath string) (string, error) {
   104  	fileInfo, err := os.Stat(userSpecifiedPath)
   105  	if err != nil {
   106  		return "", err
   107  	}
   108  
   109  	if fileInfo.IsDir() {
   110  		manifestPaths := []string{
   111  			filepath.Join(userSpecifiedPath, "manifest.yml"),
   112  			filepath.Join(userSpecifiedPath, "manifest.yaml"),
   113  		}
   114  		var err error
   115  		for _, manifestPath := range manifestPaths {
   116  			if _, err = os.Stat(manifestPath); err == nil {
   117  				return manifestPath, err
   118  			}
   119  		}
   120  		return "", err
   121  	} else {
   122  		return userSpecifiedPath, nil
   123  	}
   124  }