github.com/searchspring/haus@v0.1.8-0.20200414161854-a7ca8bb9ea93/app/config.go (about)

     1  package haus
     2  
     3  import(
     4  	"os"
     5  	"fmt"
     6  	"strings"
     7  	"path/filepath"
     8  	"io/ioutil"
     9  
    10  	"gopkg.in/yaml.v2"
    11  	"github.com/searchspring/repo-tsar/gitutils"
    12  )
    13  
    14  // Config represents the configurations in haus config file.
    15  type Config struct {
    16  	Name string
    17  	Email string
    18  	Path string
    19  	Pwd string
    20  	Hausrepo string
    21  	Environments map[string]Environment
    22  	Variables map[string]string
    23  }
    24  
    25  // ReadConfig reads the config file from the supplied full path and
    26  // returns a Config and error.
    27  func ReadConfig(filename string, usrcfgfile string, branch string, path string, variables map[string]string )(*Config, error) {
    28  	config := &Config{}
    29  
    30  	// Check for current directory config
    31  	curdir,err := filepath.Abs("./")
    32  	if err != nil {
    33  		return config, err
    34  	}
    35  	curdircfg := fmt.Sprintf("%s/.hauscfg.yaml", curdir)
    36  	_,err = os.Stat(curdircfg)
    37  	has_curdircfg :=  false
    38  	if err == nil {
    39  		has_curdircfg = true
    40  	} 
    41  
    42  	// If the configfile is missing, try to check it out from git repo
    43  	_,err = os.Stat(filename)
    44  	if err != nil {
    45  		// Get the url for the git repo from user config
    46  		err = readCfg(usrcfgfile,config)
    47  		if err != nil {
    48  			return config,err
    49  		}
    50  
    51  		// If there's a .hauscfg.yaml in the current directory, let it supercede the usrcfgfile 
    52  		if has_curdircfg {
    53  			err = readCfg(curdircfg, config)
    54  			if err != nil {
    55  				return config,err
    56  			}
    57  		}
    58  
    59  		// If the url is defined, clone the repo
    60  		if config.Hausrepo != "" {
    61  			cloneinfo := &gitutils.CloneInfo{
    62  				Reponame: "hauscfg",
    63  				Path: ".",
    64  				URL: config.Hausrepo,
    65  				Branch: branch,
    66  			}
    67  			fmt.Printf("Cloning repo hauscfg from %s\n", config.Hausrepo)
    68  			_,err = cloneinfo.CloneRepo()
    69  			if err != nil {
    70  				return config, err
    71  			}
    72  		} else {
    73  			// There's no haus yaml, and hausrepo isn't defined in the user config
    74  			err = fmt.Errorf("No %s file and %s missing 'hausrepo'.", filename,usrcfgfile)
    75  			return config, err
    76  		}
    77  	} 
    78  
    79  	// Read haus yaml file
    80  	err = readCfg(filename, config)
    81  	if err != nil {
    82  		return config, err
    83  	}	
    84  
    85  	// Read user config haus yaml
    86  	err = readCfg(usrcfgfile, config)
    87  	if err != nil {
    88  		return config, err
    89  	}
    90  
    91  	// If there's a .hauscfg.yaml in the current directory, let it supercede the usrcfgfile
    92  	if has_curdircfg {
    93  		err = readCfg(curdircfg, config)
    94  		if err != nil {
    95  			return config,err
    96  		}
    97  	}
    98  
    99  	// Process default variables
   100  	for k, v := range config.Variables {
   101  		for name, env := range config.Environments {
   102  			if _, ok := env.Variables[k]; ok {
   103  			} else {
   104  				if env.Variables == nil {
   105  					env.Variables = make(map[string]string)
   106  				}
   107  				env.Variables[k] = v
   108  				config.Environments[name] = env
   109  			}
   110  		}
   111  	}
   112  
   113  	// Pass variables from command line into config
   114  	for k, v := range variables {
   115  		for name, env := range config.Environments {
   116  			if _,ok := env.Variables[k]; ok {
   117  				config.Environments[name].Variables[k] = v
   118  			} 
   119  		} 
   120  	}
   121  
   122  	// Set path	
   123  	config.Path = path
   124  
   125  	// Store the current path
   126  	config.Pwd,err = os.Getwd()
   127  	if err != nil {
   128  		return config,err
   129  	}
   130  	return config, nil
   131  }
   132  
   133  // readCfg reads a file and parses it for yaml and unmarshals it into config.
   134  func readCfg(cfgfile string, config *Config) (error) {
   135  	// Read config from user home a overrite anything
   136  
   137  
   138  	_,err := os.Stat(expandTilde(cfgfile))
   139  	if err != nil {
   140  		fmt.Printf("Config file %#v missing\n", cfgfile)
   141  	} else {
   142  		cfg,err := ioutil.ReadFile(expandTilde(cfgfile))
   143  		if err != nil {
   144  			return err
   145  		}
   146  		err = yaml.Unmarshal(cfg, config)
   147  		if err != nil {
   148  			return err
   149  		}
   150  	}
   151  	return nil
   152  }
   153  
   154  // expandTilde expands ~ to value of ENV HOME
   155  func expandTilde(f string) string {
   156  	if strings.HasPrefix(f, "~"+string(filepath.Separator)) {
   157  		return os.Getenv("HOME") + f[1:]
   158  	}
   159  	return f
   160  }