github.com/Tri-stone/burrow@v0.25.0/deploy/loader/load_package.go (about)

     1  package loader
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/hyperledger/burrow/deploy/def"
     9  	"github.com/hyperledger/burrow/logging"
    10  	"github.com/spf13/viper"
    11  )
    12  
    13  func LoadPlaybook(fileName string, args *def.DeployArgs, logger *logging.Logger) (*def.Playbook, error) {
    14  	return loadPlaybook(fileName, args, nil, logger)
    15  }
    16  
    17  func loadPlaybook(fileName string, args *def.DeployArgs, parent *def.Playbook, logger *logging.Logger) (*def.Playbook, error) {
    18  	logger.InfoMsg("Loading Playbook File.")
    19  	playbook := new(def.Playbook)
    20  	deployJobs := viper.New()
    21  
    22  	if parent != nil {
    23  		// if subYAMLPath does not exist, try YAMLPath relative to paremt.Path
    24  		if _, err := os.Stat(fileName); os.IsNotExist(err) {
    25  			fileName = filepath.Join(parent.Path, fileName)
    26  			logger.InfoMsg("Trying Playbook relative to Path", "filename", fileName, "path", parent.Path)
    27  		}
    28  	}
    29  
    30  	playbook.Filename = fileName
    31  	playbook.Path = filepath.Dir(fileName)
    32  
    33  	if args.BinPath == "[dir]/bin" {
    34  		playbook.BinPath = filepath.Join(playbook.Path, "bin")
    35  	} else {
    36  		playbook.BinPath = args.BinPath
    37  	}
    38  
    39  	if _, err := os.Stat(playbook.BinPath); os.IsNotExist(err) {
    40  		if err := os.Mkdir(playbook.BinPath, 0775); err != nil {
    41  			return nil, err
    42  		}
    43  	}
    44  
    45  	// setup file
    46  	abs, err := filepath.Abs(fileName)
    47  	if err != nil {
    48  		return nil, fmt.Errorf("sorry, the marmots were unable to find the absolute path to the playbook file")
    49  	}
    50  
    51  	base := filepath.Base(abs)
    52  	extName := filepath.Ext(base)
    53  	bName := base[:len(base)-len(extName)]
    54  	logger.InfoMsg("Loading playbook file",
    55  		"path", playbook.Path,
    56  		"filename", playbook.Filename,
    57  	)
    58  
    59  	deployJobs.SetConfigType("yaml")
    60  	deployJobs.SetConfigName(bName)
    61  
    62  	r, err := os.Open(fileName)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	// load file
    67  	if err := deployJobs.ReadConfig(r); err != nil {
    68  		return nil, fmt.Errorf("Sorry, the marmots were unable to load the playbook file. Please check your path: %v", err)
    69  	}
    70  
    71  	// marshall file
    72  	if err := deployJobs.UnmarshalExact(playbook); err != nil {
    73  		return nil, fmt.Errorf(`Sorry, the marmots could not figure that playbook file out.
    74  			Please check that your deploy.yaml is properly formatted: %v`, err)
    75  	}
    76  
    77  	// TODO more file sanity check (fail before running)
    78  	err = playbook.Validate()
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	for _, job := range playbook.Jobs {
    84  		if job.Meta != nil {
    85  			metaPlaybook, err := loadPlaybook(job.Meta.File, args, playbook, logger)
    86  			if err != nil {
    87  				return nil, err
    88  			}
    89  
    90  			// set the deploy contract jobs relative to the newDo's root directory
    91  			for _, job := range metaPlaybook.Jobs {
    92  				if job.Deploy != nil {
    93  					job.Deploy.Contract = filepath.Join(metaPlaybook.Path, job.Deploy.Contract)
    94  				}
    95  			}
    96  
    97  			// We do not set the parent for this playbook; the parent is used for
    98  			// backreferencing variables
    99  			job.Meta.Playbook = metaPlaybook
   100  		}
   101  
   102  		if job.Proposal != nil {
   103  			for _, job := range job.Proposal.Jobs {
   104  				if job.Meta != nil {
   105  					metaPlaybook, err := loadPlaybook(job.Meta.File, args, playbook, logger)
   106  					if err != nil {
   107  						return nil, err
   108  					}
   109  
   110  					// set the deploy contract jobs relative to the newDo's root directory
   111  					for _, job := range metaPlaybook.Jobs {
   112  						if job.Deploy != nil {
   113  							job.Deploy.Contract = filepath.Join(metaPlaybook.Path, job.Deploy.Contract)
   114  						}
   115  					}
   116  
   117  					// Set the parent for the playbook so that the proposal can backreference e.g.
   118  					// deployed contracts addresses
   119  					metaPlaybook.Parent = playbook
   120  					job.Meta.Playbook = metaPlaybook
   121  				}
   122  			}
   123  		}
   124  	}
   125  
   126  	return playbook, nil
   127  }