Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 080cfbb

Browse files
ivan-kostkomr00wkanritholtz
authored
Clean flag added with destinations support (#14)
* Implemention of Clean flag --------- Co-authored-by: Rafal Przybyla <[email protected]> Co-authored-by: Nathaniel Ritholtz <[email protected]>
1 parent 60d1a08 commit 080cfbb

31 files changed

+13737
-179
lines changed

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ require (
77
github.com/nritholtz/stdemuxerhook v0.0.0-20181016194454-2c86ca05d211
88
github.com/rendon/testcli v0.0.0-20161027181003-6283090d169f
99
github.com/sirupsen/logrus v1.8.1
10-
github.com/stretchr/testify v1.2.2
10+
github.com/stretchr/testify v1.8.1
1111
gopkg.in/yaml.v2 v2.4.0
1212
)
1313

1414
require (
1515
github.com/davecgh/go-spew v1.1.1 // indirect
1616
github.com/pmezard/go-difflib v1.0.0 // indirect
1717
golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 // indirect
18+
gopkg.in/yaml.v3 v3.0.1 // indirect
1819
)

go.sum

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
12
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
23
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
34
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
@@ -10,8 +11,14 @@ github.com/rendon/testcli v0.0.0-20161027181003-6283090d169f h1:onGP+qmYmjKs7pkm
1011
github.com/rendon/testcli v0.0.0-20161027181003-6283090d169f/go.mod h1:cq57a4l475CeMvE7RRpSui1MEqCmhirIt1E7kl8BC2Q=
1112
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
1213
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
13-
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
14+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
15+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
16+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
1417
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
18+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
19+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
20+
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
21+
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
1522
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1623
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1724
golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 h1:z8Hj/bl9cOV2grsOpEaQFUaly0JWN3i97mo3jXKJNp0=
@@ -20,3 +27,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
2027
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2128
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
2229
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
30+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
31+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
32+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ var opts struct {
3939
ModulePath string `short:"p" long:"module_path" default:"./vendor/modules" description:"File path to install generated terraform modules, if not overridden by 'destinations:' field"`
4040

4141
TerrafilePath string `short:"f" long:"terrafile_file" default:"./Terrafile" description:"File path to the Terrafile file"`
42+
43+
Clean bool `short:"c" long:"clean" description:"Remove everything from destinations and module path upon fetching module(s)\n !!! WARNING !!! Removes all files and folders in the destinations including non-modules."`
4244
}
4345

4446
// To be set by goreleaser on build
@@ -93,6 +95,10 @@ func main() {
9395
log.Fatalf("failed to parse yaml file due to error: %s", err)
9496
}
9597

98+
if opts.Clean {
99+
cleanDestinations(config)
100+
}
101+
96102
// Clone modules
97103
var wg sync.WaitGroup
98104
_ = os.RemoveAll(opts.ModulePath)
@@ -157,3 +163,32 @@ func main() {
157163

158164
wg.Wait()
159165
}
166+
167+
func cleanDestinations(config map[string]module) {
168+
169+
// Map filters duplicate destinations with key being each destination's file path
170+
uniqueDestinations := make(map[string]bool)
171+
172+
// Range over config and gather all unique destinations
173+
for _, m := range config {
174+
if len(m.Destinations) == 0 {
175+
uniqueDestinations[opts.ModulePath] = true
176+
continue
177+
}
178+
179+
// range over Destinations and put them into map
180+
for _, dst := range m.Destinations {
181+
// Destination supposed to be conjunction of destination defined in file with module path
182+
d := filepath.Join(dst, opts.ModulePath)
183+
uniqueDestinations[d] = true
184+
}
185+
}
186+
187+
for dst := range uniqueDestinations {
188+
189+
log.Infof("[*] Removing artifacts from %s", dst)
190+
if err := os.RemoveAll(dst); err != nil {
191+
log.Errorf("Failed to remove artifacts from %s due to error: %s", dst, err)
192+
}
193+
}
194+
}

main_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ func TestTerraformWithTerrafilePath(t *testing.T) {
6363
} {
6464
assert.Contains(t, testcli.Stdout(), output)
6565
}
66+
67+
// Assert output does not contain the following
68+
for _, output := range []string{
69+
"[*] Removing artifacts from ./vendor/modules",
70+
"[*] Removing artifacts from testdata/networking/vendor/modules",
71+
"[*] Removing artifacts from testdata/some-other-stack/vendor/modules",
72+
"[*] Removing artifacts from testdata/iam/vendor/modules",
73+
"[*] Removing artifacts from testdata/onboarding/vendor/modules",
74+
} {
75+
assert.NotContains(t, testcli.Stdout(), output)
76+
}
77+
6678
// Assert folder exist with default destination
6779
for _, moduleName := range []string{
6880
"tf-aws-vpc",
@@ -174,6 +186,81 @@ func TestTerraformWithTerrafilePath(t *testing.T) {
174186
}
175187
}
176188

189+
func TestTerraformWithTerrafileClean(t *testing.T) {
190+
folder, back := setup(t)
191+
defer back()
192+
193+
// Run original Terrafile with path
194+
testcli.Run(terrafileBinaryPath, "-f", fmt.Sprint(folder, "/Terrafile"))
195+
196+
defer println(testcli.Stdout())
197+
defer println(testcli.Stderr())
198+
199+
defer func() {
200+
assert.NoError(t, os.RemoveAll("testdata/"))
201+
}()
202+
203+
// Create Terrafile2.yaml
204+
createTerrafile2(t, folder)
205+
206+
// Run terrafile with path to Terrafile2 and clean flag
207+
testcli.Run(terrafileBinaryPath, "-f", fmt.Sprint(folder, "/Terrafile2"), "-c")
208+
209+
// Print out output of second run
210+
defer println(testcli.Stdout())
211+
defer println(testcli.Stderr())
212+
213+
if !testcli.Success() {
214+
t.Fatalf("Expected to succeed, but failed: %q with message: %q", testcli.Error(), testcli.Stderr())
215+
}
216+
217+
// Assert output
218+
for _, output := range []string{
219+
"[*] Removing artifacts from ./vendor/modules",
220+
"[*] Removing artifacts from testdata/networking/vendor/modules",
221+
"[*] Removing artifacts from testdata/some-other-stack/vendor/modules",
222+
"[*] Removing artifacts from testdata/iam/vendor/modules",
223+
"[*] Removing artifacts from testdata/onboarding/vendor/modules",
224+
} {
225+
assert.Contains(t, testcli.Stdout(), output)
226+
}
227+
228+
// Assert files exist with default destination
229+
for _, moduleName := range []string{
230+
"tf-aws-vpc/main.tf",
231+
} {
232+
assert.FileExists(t, path.Join(workingDirectory, "vendor/modules", moduleName))
233+
}
234+
235+
// Assert files does not exist with default destination
236+
for _, moduleName := range []string{
237+
"tf-aws-vpc-experimental/main.tf",
238+
} {
239+
assert.NoFileExists(t, path.Join(workingDirectory, "vendor/modules", moduleName))
240+
}
241+
242+
// Assert files exist with non-default destinations
243+
for _, moduleName := range []string{
244+
"testdata/networking/vendor/modules/tf-aws-vpn-gateway/main.tf",
245+
246+
// terraform-aws-modules/terraform-aws-iam doesn't have main.tf, as it represents set of modules
247+
// However, some terraform-aws-modules/terraform-aws-iam/modules have, e.g.:
248+
"testdata/iam/vendor/modules/tf-aws-iam/modules/iam-account/main.tf",
249+
"testdata/onboarding/vendor/modules/tf-aws-s3-bucket/main.tf",
250+
"testdata/some-other-stack/vendor/modules/tf-aws-vpn-gateway/main.tf",
251+
} {
252+
assert.FileExists(t, path.Join(workingDirectory, moduleName))
253+
}
254+
255+
// Assert files do not exist with non-default destinations
256+
for _, moduleName := range []string{
257+
"testdata/networking/vendor/modules/tf-aws-s3-bucket/main.tf",
258+
"testdata/some-other-stack/vendor/modules/tf-aws-s3-bucket/main.tf",
259+
} {
260+
assert.NoFileExists(t, path.Join(workingDirectory, moduleName))
261+
}
262+
}
263+
177264
func setup(t *testing.T) (current string, back func()) {
178265
folder, err := os.MkdirTemp("", "")
179266
assert.NoError(t, err)
@@ -214,3 +301,27 @@ tf-aws-s3-bucket:
214301
`
215302
createFile(t, path.Join(folder, "Terrafile"), yaml)
216303
}
304+
305+
func createTerrafile2(t *testing.T, folder string) {
306+
var yaml = `tf-aws-vpc:
307+
source: "[email protected]:terraform-aws-modules/terraform-aws-vpc"
308+
version: "v1.46.0"
309+
tf-aws-vpn-gateway:
310+
source: "[email protected]:terraform-aws-modules/terraform-aws-vpn-gateway"
311+
version: "v3.2.0"
312+
destinations:
313+
- testdata/networking
314+
- testdata/some-other-stack
315+
tf-aws-iam:
316+
source: "[email protected]:terraform-aws-modules/terraform-aws-iam"
317+
version: "v5.11.1"
318+
destinations:
319+
- testdata/iam
320+
tf-aws-s3-bucket:
321+
source: "[email protected]:terraform-aws-modules/terraform-aws-s3-bucket"
322+
version: "v3.6.1"
323+
destinations:
324+
- testdata/onboarding
325+
`
326+
createFile(t, path.Join(folder, "Terrafile2"), yaml)
327+
}

vendor/github.com/stretchr/testify/LICENSE

Lines changed: 17 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)