terraform/command/meta_new.go

153 lines
3.7 KiB
Go

package command
import (
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"github.com/hashicorp/terraform/plans/planfile"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/config/module"
"github.com/hashicorp/terraform/tfdiags"
)
// NOTE: Temporary file until this branch is cleaned up.
// Input returns whether or not input asking is enabled.
func (m *Meta) Input() bool {
if test || !m.input {
return false
}
if envVar := os.Getenv(InputModeEnvVar); envVar != "" {
if v, err := strconv.ParseBool(envVar); err == nil && !v {
return false
}
}
return true
}
// Module loads the module tree for the given root path using the legacy
// configuration loader.
//
// It expects the modules to already be downloaded. This will never
// download any modules.
//
// The configuration is validated before returning, so the returned diagnostics
// may contain warnings and/or errors. If the diagnostics contains only
// warnings, the caller may treat the returned module.Tree as valid after
// presenting the warnings to the user.
func (m *Meta) Module(path string) (*module.Tree, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
mod, err := module.NewTreeModule("", path)
if err != nil {
// Check for the error where we have no config files
if errwrap.ContainsType(err, new(config.ErrNoConfigsFound)) {
return nil, nil
}
diags = diags.Append(err)
return nil, diags
}
err = mod.Load(m.moduleStorage(m.DataDir(), module.GetModeNone))
if err != nil {
diags = diags.Append(errwrap.Wrapf("Error loading modules: {{err}}", err))
return nil, diags
}
diags = diags.Append(mod.Validate())
return mod, diags
}
// Config loads the root config for the path specified, using the legacy
// configuration loader.
//
// Path may be a directory or file. The absence of configuration is not an
// error and returns a nil Config.
func (m *Meta) Config(path string) (*config.Config, error) {
// If no explicit path was given then it is okay for there to be
// no backend configuration found.
emptyOk := path == ""
// If we had no path set, it is an error. We can't initialize unset
if path == "" {
path = "."
}
// Expand the path
if !filepath.IsAbs(path) {
var err error
path, err = filepath.Abs(path)
if err != nil {
return nil, fmt.Errorf(
"Error expanding path to backend config %q: %s", path, err)
}
}
log.Printf("[DEBUG] command: loading backend config file: %s", path)
// We first need to determine if we're loading a file or a directory.
fi, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) && emptyOk {
log.Printf(
"[INFO] command: backend config not found, returning nil: %s",
path)
return nil, nil
}
return nil, err
}
var f func(string) (*config.Config, error) = config.LoadFile
if fi.IsDir() {
f = config.LoadDir
}
// Load the configuration
c, err := f(path)
if err != nil {
// Check for the error where we have no config files and return nil
// as the configuration type.
if errwrap.ContainsType(err, new(config.ErrNoConfigsFound)) {
log.Printf(
"[INFO] command: backend config not found, returning nil: %s",
path)
return nil, nil
}
return nil, err
}
return c, nil
}
// PlanFile returns a reader for the plan file at the given path.
//
// If the return value and error are both nil, the given path exists but seems
// to be a configuration directory instead.
//
// Error will be non-nil if path refers to something which looks like a plan
// file and loading the file fails.
func (m *Meta) PlanFile(path string) (*planfile.Reader, error) {
fi, err := os.Stat(path)
if err != nil {
return nil, err
}
if fi.IsDir() {
// Looks like a configuration directory.
return nil, nil
}
return planfile.Open(path)
}