Skip to content

Commit

Permalink
Prevent overwriting already existing files
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiught committed Aug 10, 2023
1 parent 0117602 commit f268d9b
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
58 changes: 58 additions & 0 deletions internal/cli/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/spf13/cobra"

"github.com/auth0/auth0-cli/internal/auth0"
"github.com/auth0/auth0-cli/internal/prompt"
)

var tfFlags = terraformFlags{
Expand Down Expand Up @@ -76,6 +77,7 @@ func generateTerraformCmd(cli *cli) *cobra.Command {
RunE: generateTerraformCmdRun(cli, &inputs),
}

cmd.Flags().BoolVar(&cli.force, "force", false, "Skip confirmation.")
tfFlags.OutputDIR.RegisterString(cmd, &inputs.OutputDIR, "./")

return cmd
Expand All @@ -88,6 +90,16 @@ func generateTerraformCmdRun(cli *cli, inputs *terraformInputs) func(cmd *cobra.
return err
}

cli.renderer.JSONResult(data)

if !checkOutputDirectoryIsEmpty(cli, inputs.OutputDIR) {
return nil
}

if err := cleanOutputDirectory(inputs.OutputDIR); err != nil {
return err
}

if err := generateTerraformImportConfig(inputs.OutputDIR, data); err != nil {
return err
}
Expand Down Expand Up @@ -260,3 +272,49 @@ func terraformProviderCredentialsAreAvailable() bool {

return (domain != "" && clientID != "" && clientSecret != "") || (domain != "" && apiToken != "")
}

func checkOutputDirectoryIsEmpty(cli *cli, outputDIR string) bool {
_, err := os.Stat(outputDIR)
if os.IsNotExist(err) {
return true
}

_, mainFileErr := os.Stat(path.Join(outputDIR, "main.tf"))
_, importFileErr := os.Stat(path.Join(outputDIR, "auth0_import.tf"))
_, generatedFileErr := os.Stat(path.Join(outputDIR, "generated.tf"))
if os.IsNotExist(mainFileErr) && os.IsNotExist(importFileErr) && os.IsNotExist(generatedFileErr) {
return true
}

cli.renderer.Warnf(
"Output directory %q is not empty. "+
"Proceeding will overwrite the main.tf, auth0_import.tf and generated.tf files.",
outputDIR,
)

if !cli.force && !cli.noInput {
if confirmed := prompt.Confirm("Are you sure you want to proceed?"); !confirmed {
return false
}
}

return true
}

func cleanOutputDirectory(outputDIR string) error {
var joinedErrors error

if err := os.Remove(path.Join(outputDIR, "main.tf")); err != nil && !os.IsNotExist(err) {
joinedErrors = errors.Join(err)
}

if err := os.Remove(path.Join(outputDIR, "auth0_import.tf")); err != nil && !os.IsNotExist(err) {
joinedErrors = errors.Join(err)
}

if err := os.Remove(path.Join(outputDIR, "generated.tf")); err != nil && !os.IsNotExist(err) {
joinedErrors = errors.Join(err)
}

return joinedErrors
}
88 changes: 88 additions & 0 deletions internal/cli/terraform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/auth0/auth0-cli/internal/display"
)

type mockFetcher struct {
Expand Down Expand Up @@ -259,3 +261,89 @@ func TestTerraformProviderCredentialsAreAvailable(t *testing.T) {
})
}
}

func TestCheckOutputDirectoryIsEmpty(t *testing.T) {
t.Run("it returns true if the directory is empty", func(t *testing.T) {
tempDIR := t.TempDir()

isEmpty := checkOutputDirectoryIsEmpty(&cli{}, tempDIR)
assert.True(t, isEmpty)
})

t.Run("it returns true if the directory doesn't exist", func(t *testing.T) {
isEmpty := checkOutputDirectoryIsEmpty(&cli{}, "")
assert.True(t, isEmpty)
})

t.Run("it returns true if the directory is not empty but we're forcing the command", func(t *testing.T) {
tempDIR := t.TempDir()
files := []string{"main.tf", "auth0_import.tf", "generated.tf"}

for _, file := range files {
filePath := path.Join(tempDIR, file)
_, err := os.Create(filePath)
require.NoError(t, err)
}

stdout := &bytes.Buffer{}
cli := &cli{
renderer: &display.Renderer{
MessageWriter: stdout,
ResultWriter: stdout,
},
force: true,
noInput: true,
}

isEmpty := checkOutputDirectoryIsEmpty(cli, tempDIR)
assert.True(t, isEmpty)
assert.Contains(t, stdout.String(), "Proceeding will overwrite the main.tf, auth0_import.tf and generated.tf files.")
})
}

func TestCleanOutputDirectory(t *testing.T) {
t.Run("it can successfully clean the output directory from all generated files", func(t *testing.T) {
tempDIR := t.TempDir()
files := []string{"main.tf", "auth0_import.tf", "generated.tf"}

for _, file := range files {
filePath := path.Join(tempDIR, file)
_, err := os.Create(filePath)
require.NoError(t, err)
}

err := cleanOutputDirectory(tempDIR)
assert.NoError(t, err)

for _, file := range files {
filePath := path.Join(tempDIR, file)
_, err := os.Stat(filePath)
assert.ErrorContains(t, err, "no such file or directory")
}
})

t.Run("it returns an error if it can't remove a file", func(t *testing.T) {
files := []string{"main.tf", "auth0_import.tf", "generated.tf"}

for _, file := range files {
t.Run(file, func(t *testing.T) {
tempDIR := t.TempDir()

filePath := path.Join(tempDIR, file)
_, err := os.Create(filePath)
require.NoError(t, err)

err = os.Chmod(tempDIR, 0444)
require.NoError(t, err)

t.Cleanup(func() {
err = os.Chmod(tempDIR, 0755)
require.NoError(t, err)
})

err = cleanOutputDirectory(tempDIR)
assert.ErrorContains(t, err, "permission denied")
})
}
})
}

0 comments on commit f268d9b

Please sign in to comment.