| package tfexec | 
 |  | 
 | import ( | 
 | 	"context" | 
 | 	"fmt" | 
 | 	"os/exec" | 
 | ) | 
 |  | 
 | type initConfig struct { | 
 | 	backend       bool | 
 | 	backendConfig []string | 
 | 	dir           string | 
 | 	forceCopy     bool | 
 | 	fromModule    string | 
 | 	get           bool | 
 | 	getPlugins    bool | 
 | 	lock          bool | 
 | 	lockTimeout   string | 
 | 	pluginDir     []string | 
 | 	reattachInfo  ReattachInfo | 
 | 	reconfigure   bool | 
 | 	upgrade       bool | 
 | 	verifyPlugins bool | 
 | } | 
 |  | 
 | var defaultInitOptions = initConfig{ | 
 | 	backend:       true, | 
 | 	forceCopy:     false, | 
 | 	get:           true, | 
 | 	getPlugins:    true, | 
 | 	lock:          true, | 
 | 	lockTimeout:   "0s", | 
 | 	reconfigure:   false, | 
 | 	upgrade:       false, | 
 | 	verifyPlugins: true, | 
 | } | 
 |  | 
 | // InitOption represents options used in the Init method. | 
 | type InitOption interface { | 
 | 	configureInit(*initConfig) | 
 | } | 
 |  | 
 | func (opt *BackendOption) configureInit(conf *initConfig) { | 
 | 	conf.backend = opt.backend | 
 | } | 
 |  | 
 | func (opt *BackendConfigOption) configureInit(conf *initConfig) { | 
 | 	conf.backendConfig = append(conf.backendConfig, opt.path) | 
 | } | 
 |  | 
 | func (opt *DirOption) configureInit(conf *initConfig) { | 
 | 	conf.dir = opt.path | 
 | } | 
 |  | 
 | func (opt *ForceCopyOption) configureInit(conf *initConfig) { | 
 | 	conf.forceCopy = opt.forceCopy | 
 | } | 
 |  | 
 | func (opt *FromModuleOption) configureInit(conf *initConfig) { | 
 | 	conf.fromModule = opt.source | 
 | } | 
 |  | 
 | func (opt *GetOption) configureInit(conf *initConfig) { | 
 | 	conf.get = opt.get | 
 | } | 
 |  | 
 | func (opt *GetPluginsOption) configureInit(conf *initConfig) { | 
 | 	conf.getPlugins = opt.getPlugins | 
 | } | 
 |  | 
 | func (opt *LockOption) configureInit(conf *initConfig) { | 
 | 	conf.lock = opt.lock | 
 | } | 
 |  | 
 | func (opt *LockTimeoutOption) configureInit(conf *initConfig) { | 
 | 	conf.lockTimeout = opt.timeout | 
 | } | 
 |  | 
 | func (opt *PluginDirOption) configureInit(conf *initConfig) { | 
 | 	conf.pluginDir = append(conf.pluginDir, opt.pluginDir) | 
 | } | 
 |  | 
 | func (opt *ReattachOption) configureInit(conf *initConfig) { | 
 | 	conf.reattachInfo = opt.info | 
 | } | 
 |  | 
 | func (opt *ReconfigureOption) configureInit(conf *initConfig) { | 
 | 	conf.reconfigure = opt.reconfigure | 
 | } | 
 |  | 
 | func (opt *UpgradeOption) configureInit(conf *initConfig) { | 
 | 	conf.upgrade = opt.upgrade | 
 | } | 
 |  | 
 | func (opt *VerifyPluginsOption) configureInit(conf *initConfig) { | 
 | 	conf.verifyPlugins = opt.verifyPlugins | 
 | } | 
 |  | 
 | // Init represents the terraform init subcommand. | 
 | func (tf *Terraform) Init(ctx context.Context, opts ...InitOption) error { | 
 | 	cmd, err := tf.initCmd(ctx, opts...) | 
 | 	if err != nil { | 
 | 		return err | 
 | 	} | 
 | 	return tf.runTerraformCmd(ctx, cmd) | 
 | } | 
 |  | 
 | func (tf *Terraform) initCmd(ctx context.Context, opts ...InitOption) (*exec.Cmd, error) { | 
 | 	c := defaultInitOptions | 
 |  | 
 | 	for _, o := range opts { | 
 | 		switch o.(type) { | 
 | 		case *LockOption, *LockTimeoutOption, *VerifyPluginsOption, *GetPluginsOption: | 
 | 			err := tf.compatible(ctx, nil, tf0_15_0) | 
 | 			if err != nil { | 
 | 				return nil, fmt.Errorf("-lock, -lock-timeout, -verify-plugins, and -get-plugins options are no longer available as of Terraform 0.15: %w", err) | 
 | 			} | 
 | 		} | 
 |  | 
 | 		o.configureInit(&c) | 
 | 	} | 
 |  | 
 | 	args := []string{"init", "-no-color", "-input=false"} | 
 |  | 
 | 	// string opts: only pass if set | 
 | 	if c.fromModule != "" { | 
 | 		args = append(args, "-from-module="+c.fromModule) | 
 | 	} | 
 |  | 
 | 	// string opts removed in 0.15: pass if set and <0.15 | 
 | 	err := tf.compatible(ctx, nil, tf0_15_0) | 
 | 	if err == nil { | 
 | 		if c.lockTimeout != "" { | 
 | 			args = append(args, "-lock-timeout="+c.lockTimeout) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// boolean opts: always pass | 
 | 	args = append(args, "-backend="+fmt.Sprint(c.backend)) | 
 | 	args = append(args, "-get="+fmt.Sprint(c.get)) | 
 | 	args = append(args, "-upgrade="+fmt.Sprint(c.upgrade)) | 
 |  | 
 | 	// boolean opts removed in 0.15: pass if <0.15 | 
 | 	err = tf.compatible(ctx, nil, tf0_15_0) | 
 | 	if err == nil { | 
 | 		args = append(args, "-lock="+fmt.Sprint(c.lock)) | 
 | 		args = append(args, "-get-plugins="+fmt.Sprint(c.getPlugins)) | 
 | 		args = append(args, "-verify-plugins="+fmt.Sprint(c.verifyPlugins)) | 
 | 	} | 
 |  | 
 | 	if c.forceCopy { | 
 | 		args = append(args, "-force-copy") | 
 | 	} | 
 |  | 
 | 	// unary flags: pass if true | 
 | 	if c.reconfigure { | 
 | 		args = append(args, "-reconfigure") | 
 | 	} | 
 |  | 
 | 	// string slice opts: split into separate args | 
 | 	if c.backendConfig != nil { | 
 | 		for _, bc := range c.backendConfig { | 
 | 			args = append(args, "-backend-config="+bc) | 
 | 		} | 
 | 	} | 
 | 	if c.pluginDir != nil { | 
 | 		for _, pd := range c.pluginDir { | 
 | 			args = append(args, "-plugin-dir="+pd) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// optional positional argument | 
 | 	if c.dir != "" { | 
 | 		args = append(args, c.dir) | 
 | 	} | 
 |  | 
 | 	mergeEnv := map[string]string{} | 
 | 	if c.reattachInfo != nil { | 
 | 		reattachStr, err := c.reattachInfo.marshalString() | 
 | 		if err != nil { | 
 | 			return nil, err | 
 | 		} | 
 | 		mergeEnv[reattachEnvVar] = reattachStr | 
 | 	} | 
 |  | 
 | 	return tf.buildTerraformCmd(ctx, mergeEnv, args...), nil | 
 | } |