github.com/craigmonson/colonize@v0.1.1-alpha.0.20170808202020-04bf903fb1ea/initialize/init.go (about)

     1  package initialize
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"errors"
     7  	"fmt"
     8  	"os"
     9  	"reflect"
    10  	"strings"
    11  
    12  	"github.com/fatih/color"
    13  
    14  	"github.com/craigmonson/colonize/config"
    15  	"github.com/craigmonson/colonize/log"
    16  	"github.com/craigmonson/colonize/util"
    17  )
    18  
    19  type RunArgs struct {
    20  	AcceptDefaults   bool
    21  	InitEnvironments string
    22  	ConfigBuffer     bytes.Buffer
    23  }
    24  
    25  func Run(c *config.Config, l log.Logger, args interface{}) error {
    26  	runArgs := args.(RunArgs)
    27  
    28  	err := initTask("Config File", configFileTask, c, l, &runArgs)
    29  	if err != nil {
    30  		return err
    31  	}
    32  
    33  	err = initTask("Environments", environmentsTask, c, l, &runArgs)
    34  	if err != nil {
    35  		return err
    36  	}
    37  
    38  	err = initTask("Summary", summaryTask, c, l, &runArgs)
    39  	if err != nil {
    40  		return err
    41  	}
    42  
    43  	return initTask("Create Artifacts", createArtifactsTask, c, l, &runArgs)
    44  }
    45  
    46  func initTask(name string, f func(*config.Config, log.Logger, *RunArgs) error, c *config.Config, l log.Logger, args *RunArgs) error {
    47  	l.LogPretty(util.PadRight(fmt.Sprintf("\nINIT [%s] ", name), "*", 79), color.Bold)
    48  	err := f(c, l, args)
    49  	return err
    50  }
    51  
    52  func configFileTask(c *config.Config, l log.Logger, args *RunArgs) error {
    53  	if !args.AcceptDefaults {
    54  		l.Log("Starting interactive setup...\n")
    55  	} else {
    56  		l.LogPretty("Skipping interactive setup...", color.FgBlue)
    57  	}
    58  
    59  	scan := bufio.NewScanner(os.Stdin)
    60  	defaults := reflect.ValueOf(&config.ConfigFileDefaults).Elem()
    61  	actuals := reflect.ValueOf(&c.ConfigFile).Elem()
    62  	typeof := defaults.Type()
    63  
    64  	// Iterate through each field in the config file struct
    65  	// asking for user inout or setting to a default
    66  	for i := 0; i < defaults.NumField(); i++ {
    67  
    68  		fieldName := strings.ToLower(typeof.Field(i).Name)
    69  		defaultField := defaults.Field(i)
    70  		actualField := actuals.Field(i)
    71  
    72  		if args.AcceptDefaults || strings.HasPrefix(fieldName, "autogenerate_") {
    73  			actualField.Set(reflect.Value(defaultField))
    74  		} else {
    75  			l.PrintPretty(fmt.Sprintf("Enter '%s' [%v]: ", fieldName, defaultField.Interface()), color.Bold)
    76  			scan.Scan()
    77  			val := scan.Text()
    78  
    79  			if val == "" {
    80  				actualField.Set(reflect.Value(defaultField))
    81  			} else {
    82  				actualField.SetString(val)
    83  			}
    84  		}
    85  
    86  		args.ConfigBuffer.WriteString(fmt.Sprintf("%-30s => %v\n", fieldName, actualField.Interface()))
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  func environmentsTask(c *config.Config, l log.Logger, args *RunArgs) error {
    93  
    94  	scan := bufio.NewScanner(os.Stdin)
    95  
    96  	if args.InitEnvironments != "" {
    97  		l.LogPretty("Skipping interactive environments setup...", color.FgBlue)
    98  		l.Log("Environments configured from command line: " + args.InitEnvironments)
    99  	} else {
   100  
   101  		if !args.AcceptDefaults {
   102  			l.LogPretty(util.PadRight("\nInitialize [Environments] ", "*", 79), color.Bold)
   103  			l.Log("Starting environment setup\n")
   104  			l.PrintPretty("Provide a comma-separated list of environment names to initialize []: ", color.Bold)
   105  			scan.Scan()
   106  			args.InitEnvironments = scan.Text()
   107  		}
   108  
   109  		if args.InitEnvironments == "" {
   110  			l.LogPretty("No environments will be setup...", color.FgBlue)
   111  		}
   112  	}
   113  
   114  	args.ConfigBuffer.WriteString(fmt.Sprintf("%-30s => %s\n", "Environments", args.InitEnvironments))
   115  
   116  	return nil
   117  }
   118  
   119  func summaryTask(c *config.Config, l log.Logger, args *RunArgs) error {
   120  
   121  	scan := bufio.NewScanner(os.Stdin)
   122  
   123  	// print configuration details
   124  	l.Log(fmt.Sprintf("\nInitializing Colonize using the following configuration:\n%s", args.ConfigBuffer.String()))
   125  
   126  	if !args.AcceptDefaults {
   127  		// Confirm initialization
   128  		accept := ""
   129  		for accept == "" {
   130  			l.PrintPretty("Enter 'yes' to accept this configuration: ", color.Bold)
   131  			scan.Scan()
   132  			accept = scan.Text()
   133  		}
   134  
   135  		if accept != "yes" {
   136  			return errors.New("Colonize initialization cancelled by user")
   137  		}
   138  	}
   139  
   140  	return nil
   141  }
   142  
   143  func createArtifactsTask(c *config.Config, l log.Logger, args *RunArgs) error {
   144  
   145  	l.Log("Creating configuration file...")
   146  	err := c.ConfigFile.WriteToFile(".colonize.yaml")
   147  	if err != nil {
   148  		return errors.New("Failed to create .colonize.yaml file: " + err.Error())
   149  	}
   150  
   151  	l.Log("Creating environments directory...")
   152  	err = os.Mkdir(c.ConfigFile.Environments_Dir, 0755)
   153  	if err != nil {
   154  		os.Remove(".colonize.yaml")
   155  		return errors.New("Failed to create environments directory: " + err.Error())
   156  	}
   157  
   158  	l.Log("Creating branch order file...")
   159  	util.Touch(c.ConfigFile.Branch_Order_File)
   160  
   161  	if len(args.InitEnvironments) > 0 {
   162  		envs := strings.Split(args.InitEnvironments, ",")
   163  		for _, env := range envs {
   164  			fn := env + ".tfvars"
   165  			l.Log(fmt.Sprintf("Creating %s environment variable file...", env))
   166  			util.Touch(c.ConfigFile.Environments_Dir, fn)
   167  		}
   168  	}
   169  
   170  	return nil
   171  }