diff --git a/command/init.go b/command/init.go new file mode 100644 index 000000000..dc7afda3a --- /dev/null +++ b/command/init.go @@ -0,0 +1,102 @@ +package command + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/hashicorp/terraform/config" + "github.com/hashicorp/terraform/config/module" +) + +// InitCommand is a Command implementation that takes a Terraform +// module and clones it to the working directory. +type InitCommand struct { + Meta +} + +func (c *InitCommand) Run(args []string) int { + args = c.Meta.process(args, false) + + cmdFlags := flag.NewFlagSet("init", flag.ContinueOnError) + cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } + if err := cmdFlags.Parse(args); err != nil { + return 1 + } + + var path string + args = cmdFlags.Args() + if len(args) > 2 { + c.Ui.Error("The init command expects at most two arguments.\n") + cmdFlags.Usage() + return 1 + } else if len(args) < 1 { + c.Ui.Error("The init command expects at least one arguments.\n") + cmdFlags.Usage() + return 1 + } + + if len(args) == 2 { + path = args[1] + } else { + var err error + path, err = os.Getwd() + if err != nil { + c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err)) + } + } + + source := args[0] + + // Verify the directory is empty + if empty, err := config.IsEmptyDir(path); err != nil { + c.Ui.Error(fmt.Sprintf( + "Error checking on destination path: %s", err)) + return 1 + } else if !empty { + c.Ui.Error( + "The destination path has Terraform configuration files. The\n" + + "init command can only be used on a directory without existing Terraform\n" + + "files.") + return 1 + } + + // Create a temporary directory to store our module + td, err := ioutil.TempDir("", "tf") + if err != nil { + c.Ui.Error(fmt.Sprintf( + "Error creating temporary directory: %s", err)) + return 1 + } + defer os.RemoveAll(td) + + // Get it! + if err := module.Get(td, source); err != nil { + c.Ui.Error(err.Error()) + return 1 + } + + return 0 +} + +func (c *InitCommand) Help() string { + helpText := ` +Usage: terraform init [options] SOURCE [PATH] + + Downloads the module given by SOURCE into the PATH. The PATH defaults + to the working directory. PATH must be empty of any Terraform files. + Any conflicting non-Terraform files will be overwritten. + + The module downloaded is a copy. If you're downloading a module from + Git, it will not preserve the Git history, it will only copy the + latest files. + +` + return strings.TrimSpace(helpText) +} + +func (c *InitCommand) Synopsis() string { + return "Initializes Terraform configuration from a module" +} diff --git a/command/init_test.go b/command/init_test.go new file mode 100644 index 000000000..7238bc6ce --- /dev/null +++ b/command/init_test.go @@ -0,0 +1,67 @@ +package command + +import ( + "testing" + + "github.com/mitchellh/cli" +) + +/* +func TestGet(t *testing.T) { + ui := new(cli.MockUi) + c := &GetCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(testProvider()), + Ui: ui, + }, + } + + args := []string{ + testFixturePath("get"), + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) + } + + output := ui.OutputWriter.String() + if !strings.Contains(output, "Get: file://") { + t.Fatalf("doesn't look like get: %s", output) + } + if strings.Contains(output, "(update)") { + t.Fatalf("doesn't look like get: %s", output) + } +} +*/ + +func TestInit_multipleArgs(t *testing.T) { + ui := new(cli.MockUi) + c := &InitCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(testProvider()), + Ui: ui, + }, + } + + args := []string{ + "bad", + "bad", + } + if code := c.Run(args); code != 1 { + t.Fatalf("bad: \n%s", ui.OutputWriter.String()) + } +} + +func TestInit_noArgs(t *testing.T) { + ui := new(cli.MockUi) + c := &InitCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(testProvider()), + Ui: ui, + }, + } + + args := []string{} + if code := c.Run(args); code != 1 { + t.Fatalf("bad: \n%s", ui.OutputWriter.String()) + } +}