Skip to content

Commit

Permalink
Merge pull request #16487 from hashicorp/jbardin/from-module
Browse files Browse the repository at this point in the history
init -from-module
  • Loading branch information
jbardin committed Oct 30, 2017
2 parents 35553c9 f648512 commit 90a7c7a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 16 deletions.
18 changes: 2 additions & 16 deletions command/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 9,6 @@ import (

"github.com/posener/complete"

"github.com/hashicorp/go-getter"

multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
Expand Down Expand Up @@ -131,7 129,8 @@ func (c *InitCommand) Run(args []string) int {
)))
header = true

if err := c.copyConfigFromModule(path, src, pwd); err != nil {
s := module.NewStorage("", c.Services, c.Credentials)
if err := s.GetModule(path, src); err != nil {
c.Ui.Error(fmt.Sprintf("Error copying source module: %s", err))
return 1
}
Expand Down Expand Up @@ -272,19 271,6 @@ func (c *InitCommand) Run(args []string) int {
return 0
}

func (c *InitCommand) copyConfigFromModule(dst, src, pwd string) error {
// errors from this function will be prefixed with "Error copying source module: "
// when returned to the user.
var err error

src, err = getter.Detect(src, pwd, getter.Detectors)
if err != nil {
return fmt.Errorf("invalid module source: %s", err)
}

return module.GetCopy(dst, src)
}

// Load the complete module tree, and fetch any missing providers.
// This method outputs its own Ui.
func (c *InitCommand) getProviders(path string, state *terraform.State, upgrade bool) error {
Expand Down
35 changes: 35 additions & 0 deletions config/module/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 243,41 @@ func (s Storage) findModule(key string) (string, error) {
return s.moduleDir(key)
}

// GetModule fetches a module source into the specified directory. This is used
// as a convenience function by the CLI to initialize a configuration.
func (s Storage) GetModule(dst, src string) error {
// reset this in case the caller was going to re-use it
mode := s.Mode
s.Mode = GetModeUpdate
defer func() {
s.Mode = mode
}()

rec, err := s.findRegistryModule(src, anyVersion)
if err != nil {
return err
}

pwd, err := os.Getwd()
if err != nil {
return err
}

source := rec.url
if source == "" {
source, err = getter.Detect(src, pwd, getter.Detectors)
if err != nil {
return fmt.Errorf("module %s: %s", src, err)
}
}

if source == "" {
return fmt.Errorf("module %q not found", src)
}

return GetCopy(dst, source)
}

// find a registry module
func (s Storage) findRegistryModule(mSource, constraint string) (moduleRecord, error) {
rec := moduleRecord{
Expand Down
49 changes: 49 additions & 0 deletions config/module/storage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 1,49 @@
package module

import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)

func TestGetModule(t *testing.T) {
server := mockRegistry()
defer server.Close()
disco := testDisco(server)

td, err := ioutil.TempDir("", "tf")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(td)
storage := NewStorage(td, disco, nil)

// this module exists in a test fixture, and is known by the mockRegistry
// relative to our cwd.
err = storage.GetModule(filepath.Join(td, "foo"), "registry/local/sub")
if err != nil {
t.Fatal(err)
}

// list everything to make sure nothing else got unpacked in here
ls, err := ioutil.ReadDir(td)
if err != nil {
t.Fatal(err)
}

var names []string
for _, info := range ls {
names = append(names, info.Name())
}

if !(len(names) == 1 && names[0] == "foo") {
t.Fatalf("expected only directory 'foo', found entries %q", names)
}

_, err = os.Stat(filepath.Join(td, "foo", "main.tf"))
if err != nil {
t.Fatal(err)
}

}

0 comments on commit 90a7c7a

Please sign in to comment.