github.com/gavinw2006/hashicorp-terraform@v0.11.12-beta1/configs/configload/loader.go (about) 1 package configload 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/terraform/configs" 7 "github.com/hashicorp/terraform/registry" 8 "github.com/hashicorp/terraform/svchost/disco" 9 "github.com/spf13/afero" 10 ) 11 12 // A Loader instance is the main entry-point for loading configurations via 13 // this package. 14 // 15 // It extends the general config-loading functionality in the parent package 16 // "configs" to support installation of modules from remote sources and 17 // loading full configurations using modules that were previously installed. 18 type Loader struct { 19 // parser is used to read configuration 20 parser *configs.Parser 21 22 // modules is used to install and locate descendent modules that are 23 // referenced (directly or indirectly) from the root module. 24 modules moduleMgr 25 } 26 27 // Config is used with NewLoader to specify configuration arguments for the 28 // loader. 29 type Config struct { 30 // ModulesDir is a path to a directory where descendent modules are 31 // (or should be) installed. (This is usually the 32 // .terraform/modules directory, in the common case where this package 33 // is being loaded from the main Terraform CLI package.) 34 ModulesDir string 35 36 // Services is the service discovery client to use when locating remote 37 // module registry endpoints. If this is nil then registry sources are 38 // not supported, which should be true only in specialized circumstances 39 // such as in tests. 40 Services *disco.Disco 41 } 42 43 // NewLoader creates and returns a loader that reads configuration from the 44 // real OS filesystem. 45 // 46 // The loader has some internal state about the modules that are currently 47 // installed, which is read from disk as part of this function. If that 48 // manifest cannot be read then an error will be returned. 49 func NewLoader(config *Config) (*Loader, error) { 50 fs := afero.NewOsFs() 51 parser := configs.NewParser(fs) 52 reg := registry.NewClient(config.Services, nil) 53 54 ret := &Loader{ 55 parser: parser, 56 modules: moduleMgr{ 57 FS: afero.Afero{Fs: fs}, 58 CanInstall: true, 59 Dir: config.ModulesDir, 60 Services: config.Services, 61 Registry: reg, 62 }, 63 } 64 65 err := ret.modules.readModuleManifestSnapshot() 66 if err != nil { 67 return nil, fmt.Errorf("failed to read module manifest: %s", err) 68 } 69 70 return ret, nil 71 } 72 73 // Parser returns the underlying parser for this loader. 74 // 75 // This is useful for loading other sorts of files than the module directories 76 // that a loader deals with, since then they will share the source code cache 77 // for this loader and can thus be shown as snippets in diagnostic messages. 78 func (l *Loader) Parser() *configs.Parser { 79 return l.parser 80 } 81 82 // Sources returns the source code cache for the underlying parser of this 83 // loader. This is a shorthand for l.Parser().Sources(). 84 func (l *Loader) Sources() map[string][]byte { 85 return l.parser.Sources() 86 }