github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/cf/manifest/manifest_disk_repository.go (about)

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