Skip to content

Commit 6565a8f

Browse files
author
Matt Cadorette
authored
fix: create passed output location for generate commands (#1470)
Prior to this commit, if you supplied your own output location it needed to already exist. This change makes it so the path will be created. We still validate that the path, if it does exist, is a directory
1 parent efba629 commit 6565a8f

File tree

2 files changed

+106
-4
lines changed

2 files changed

+106
-4
lines changed

cli/cmd/generate.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,14 @@ func writeHclOutput(hcl string, location string, cloud string) (string, error) {
179179
return "", err
180180
}
181181

182+
// check if output location exists and if it's a file
183+
outputDirLocation, err := os.Stat(dirname)
184+
if !os.IsNotExist(err) && !outputDirLocation.IsDir() {
185+
return "", fmt.Errorf("output location %s already exists and is a file", dirname)
186+
}
187+
182188
// Create directory, if needed
183-
if location == "" {
189+
if os.IsNotExist(err) {
184190
directory := filepath.FromSlash(dirname)
185191
if _, err := os.Stat(directory); os.IsNotExist(err) {
186192
err = os.MkdirAll(directory, 0700)
@@ -210,12 +216,12 @@ func validateOutputLocation(dirname string) error {
210216
// If output location was supplied, validate it exists
211217
if dirname != "" {
212218
outputLocation, err := os.Stat(dirname)
213-
if err != nil {
219+
if err != nil && !os.IsNotExist(err) {
214220
return errors.Wrap(err, "could not access specified output location")
215221
}
216222

217-
if !outputLocation.IsDir() {
218-
return errors.New("output location must be a directory")
223+
if err == nil && !outputLocation.IsDir() {
224+
return errors.New("output location already exists and is a file")
219225
}
220226
}
221227

cli/cmd/generate_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestWriteHCLOutputLocation(t *testing.T) {
12+
t.Run("should write output with existing directory", func(*testing.T) {
13+
d, err := os.MkdirTemp("", "locationTest")
14+
if err != nil {
15+
panic(err)
16+
}
17+
defer os.RemoveAll(d)
18+
19+
_, err = writeHclOutput("", d, "")
20+
assert.NoError(t, err)
21+
})
22+
t.Run("should create missing location directory", func(*testing.T) {
23+
d, err := os.MkdirTemp("", "locationTest")
24+
if err != nil {
25+
panic(err)
26+
}
27+
defer os.RemoveAll(d)
28+
29+
location := fmt.Sprintf("%s/newplace", d)
30+
_, err = writeHclOutput("", location, "")
31+
assert.NoError(t, err)
32+
33+
statOut, err := os.Stat(location)
34+
assert.NoError(t, err)
35+
assert.True(t, statOut.IsDir())
36+
})
37+
t.Run("should fail on existing location of type file", func(*testing.T) {
38+
d, err := os.MkdirTemp("", "locationTest")
39+
if err != nil {
40+
panic(err)
41+
}
42+
defer os.RemoveAll(d)
43+
44+
fileName := fmt.Sprintf("%s/testfile", d)
45+
if err := os.WriteFile(fileName, []byte("test"), os.FileMode(0744)); err != nil {
46+
panic(err)
47+
}
48+
_, err = writeHclOutput("", fileName, "")
49+
assert.Error(t, err)
50+
})
51+
t.Run("should write to homedir location when not supplied", func(*testing.T) {
52+
d, err := os.MkdirTemp("", "locationTest")
53+
if err != nil {
54+
panic(err)
55+
}
56+
h := os.Getenv("HOME")
57+
os.Setenv("HOME", d)
58+
defer func() {
59+
os.Setenv("HOME", h)
60+
os.RemoveAll(d)
61+
}()
62+
63+
_, err = writeHclOutput("", "", "")
64+
assert.NoError(t, err)
65+
statOut, err := os.Stat(fmt.Sprintf("%s/lacework/main.tf", d))
66+
assert.NoError(t, err)
67+
assert.True(t, !statOut.IsDir())
68+
})
69+
}
70+
71+
func TestValidateOutputLocation(t *testing.T) {
72+
t.Run("should validate existing dir location", func(t *testing.T) {
73+
d, err := os.MkdirTemp("", "locationTest")
74+
if err != nil {
75+
panic(err)
76+
}
77+
defer os.RemoveAll(d)
78+
assert.NoError(t, validateOutputLocation(d))
79+
})
80+
t.Run("should validate non-existent location", func(t *testing.T) {
81+
assert.NoError(t, validateOutputLocation("/i/dont/exist"))
82+
})
83+
t.Run("should not validate existing file location", func(t *testing.T) {
84+
d, err := os.MkdirTemp("", "locationTest")
85+
if err != nil {
86+
panic(err)
87+
}
88+
defer os.RemoveAll(d)
89+
90+
fileName := fmt.Sprintf("%s/testfile", d)
91+
if err := os.WriteFile(fileName, []byte("test"), os.FileMode(0744)); err != nil {
92+
panic(err)
93+
}
94+
assert.Error(t, validateOutputLocation(fileName))
95+
})
96+
}

0 commit comments

Comments
 (0)