@@ -205,6 +205,7 @@ func generateUnits(ctx context.Context, opts *options.TerragruntOptions, pool *u
205
205
source : unitCopy .Source ,
206
206
values : unitCopy .Values ,
207
207
noStack : unitCopy .NoStack != nil && * unitCopy .NoStack ,
208
+ kind : unitKind ,
208
209
}
209
210
210
211
opts .Logger .Infof ("Processing unit %s" , unitCopy .Name )
@@ -235,6 +236,7 @@ func generateStacks(ctx context.Context, opts *options.TerragruntOptions, pool *
235
236
source : stackCopy .Source ,
236
237
noStack : stackCopy .NoStack != nil && * stackCopy .NoStack ,
237
238
values : stackCopy .Values ,
239
+ kind : stackKind ,
238
240
}
239
241
240
242
opts .Logger .Infof ("Processing stack %s" , stackCopy .Name )
@@ -250,6 +252,13 @@ func generateStacks(ctx context.Context, opts *options.TerragruntOptions, pool *
250
252
return nil
251
253
}
252
254
255
+ type componentKind int
256
+
257
+ const (
258
+ unitKind componentKind = iota
259
+ stackKind
260
+ )
261
+
253
262
// componentToProcess represents an item of work for processing a stack or unit.
254
263
// It contains information about the source and target directories, the name and path of the item, the source URL or path,
255
264
// and any associated values that need to be processed.
@@ -261,6 +270,7 @@ type componentToProcess struct {
261
270
path string
262
271
source string
263
272
noStack bool
273
+ kind componentKind
264
274
}
265
275
266
276
// processComponent copies files from the source directory to the target destination and generates a corresponding values file.
@@ -309,6 +319,21 @@ func processComponent(ctx context.Context, opts *options.TerragruntOptions, cmp
309
319
return errors .Errorf ("Failed to copy %s to %s %w" , source , dest , err )
310
320
}
311
321
322
+ if ! cmp .noStack {
323
+ // validate what was copied to the destination, don't do validation for special noStack components
324
+ expectedFile := DefaultTerragruntConfigPath
325
+ kindStr := "unit"
326
+
327
+ if cmp .kind == stackKind {
328
+ expectedFile = defaultStackFile
329
+ kindStr = "stack"
330
+ }
331
+
332
+ if err := validateTargetDir (kindStr , cmp .name , dest , expectedFile ); err != nil {
333
+ return errors .Errorf ("validation failed for %v %v" , cmp .name , err )
334
+ }
335
+ }
336
+
312
337
// generate values file
313
338
if err := writeValues (opts , cmp .values , dest ); err != nil {
314
339
return errors .Errorf ("failed to write values %v %v" , cmp .name , err )
@@ -633,3 +658,19 @@ func listStackFiles(opts *options.TerragruntOptions, dir string) ([]string, erro
633
658
634
659
return stackFiles , nil
635
660
}
661
+
662
+ // validateTargetDir target destination directory.
663
+ func validateTargetDir (kind , name , destDir , expectedFile string ) error {
664
+ expectedPath := filepath .Join (destDir , expectedFile )
665
+
666
+ info , err := os .Stat (expectedPath )
667
+ if err != nil {
668
+ return fmt .Errorf ("%s '%s': expected file '%s' not found in target directory '%s': %w" , kind , name , expectedFile , destDir , err )
669
+ }
670
+
671
+ if info .IsDir () {
672
+ return fmt .Errorf ("%s '%s': expected file '%s' is a directory, not a file" , kind , name , expectedFile )
673
+ }
674
+
675
+ return nil
676
+ }
0 commit comments