Skip to content

Commit 92f20fc

Browse files
ri-roeemotatoes
andauthored
Add traverse_to_nested_projects flag (#1245)
* Adds traverse_to_nested_projects flag, tests, and docs --------- Signed-off-by: Roee Landesman <[email protected]> Co-authored-by: Mohamed Habib <[email protected]>
1 parent dbcc55f commit 92f20fc

File tree

7 files changed

+181
-115
lines changed

7 files changed

+181
-115
lines changed

docs/howto/generate-projects.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,15 @@ generate_projects:
3030

3131
[Demo repo](https://github.com/diggerhq/generate_projects_demo)
3232

33+
# Traversing nested directories
3334

35+
You can optionally set the top-level argument `traverse_to_nested_projects` to generate a project for all sub-directories:
3436

37+
```
38+
traverse_to_nested_projects: true
39+
generate_projects:
40+
blocks:
41+
- include: "environments/core/**"
42+
```
43+
44+
This will create a project for all sub-directories under environments/core. If set to `false`, only the first directory with a .tf file will be evaluated.

docs/reference/digger.yml.mdx

Lines changed: 105 additions & 106 deletions
Large diffs are not rendered by default.

libs/digger_config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type DiggerConfig struct {
77
Telemetry bool
88
Workflows map[string]Workflow
99
MentionDriftedProjectsInPR bool
10+
TraverseToNestedProjects bool
1011
}
1112

1213
type DependencyConfiguration struct {

libs/digger_config/converters.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package digger_config
33
import (
44
"errors"
55
"fmt"
6+
67
"github.com/dominikbraun/graph"
78
)
89

@@ -161,6 +162,12 @@ func ConvertDiggerYamlToConfig(diggerYaml *DiggerConfigYaml) (*DiggerConfig, gra
161162
diggerConfig.Telemetry = true
162163
}
163164

165+
if diggerYaml.TraverseToNestedProjects != nil {
166+
diggerConfig.TraverseToNestedProjects = *diggerYaml.TraverseToNestedProjects
167+
} else {
168+
diggerConfig.TraverseToNestedProjects = false
169+
}
170+
164171
// if workflow block is not specified in yaml we create a default one, and add it to every project
165172
if diggerYaml.Workflows != nil {
166173
workflows := copyWorkflows(diggerYaml.Workflows)

libs/digger_config/digger_config.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
)
1717

1818
type DirWalker interface {
19-
GetDirs(workingDir string) ([]string, error)
19+
GetDirs(workingDir string, config DiggerConfigYaml) ([]string, error)
2020
}
2121

2222
type FileSystemTopLevelTerraformDirWalker struct {
@@ -46,7 +46,7 @@ func GetFilesWithExtension(workingDir string, ext string) ([]string, error) {
4646
return files, nil
4747
}
4848

49-
func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string) ([]string, error) {
49+
func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string, configYaml *DiggerConfigYaml) ([]string, error) {
5050
var dirs []string
5151
err := filepath.Walk(workingDir,
5252
func(path string, info os.FileInfo, err error) error {
@@ -61,7 +61,9 @@ func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string) (
6161
terraformFiles, _ := GetFilesWithExtension(path, ".tf")
6262
if len(terraformFiles) > 0 {
6363
dirs = append(dirs, strings.ReplaceAll(path, workingDir+string(os.PathSeparator), ""))
64-
return filepath.SkipDir
64+
if configYaml.TraverseToNestedProjects != nil && !*configYaml.TraverseToNestedProjects {
65+
return filepath.SkipDir
66+
}
6567
}
6668
}
6769
return nil
@@ -72,7 +74,7 @@ func (walker *FileSystemTopLevelTerraformDirWalker) GetDirs(workingDir string) (
7274
return dirs, nil
7375
}
7476

75-
func (walker *FileSystemModuleDirWalker) GetDirs(workingDir string) ([]string, error) {
77+
func (walker *FileSystemModuleDirWalker) GetDirs(workingDir string, configYaml *DiggerConfigYaml) ([]string, error) {
7678
var dirs []string
7779
err := filepath.Walk(workingDir,
7880
func(path string, info os.FileInfo, err error) error {
@@ -92,7 +94,7 @@ func (walker *FileSystemModuleDirWalker) GetDirs(workingDir string) ([]string, e
9294
return dirs, nil
9395
}
9496

95-
func (walker *FileSystemTerragruntDirWalker) GetDirs(workingDir string) ([]string, error) {
97+
func (walker *FileSystemTerragruntDirWalker) GetDirs(workingDir string, configYaml *DiggerConfigYaml) ([]string, error) {
9698
var dirs []string
9799
err := filepath.Walk(workingDir,
98100
func(path string, info os.FileInfo, err error) error {
@@ -199,7 +201,7 @@ func HandleYamlProjectGeneration(config *DiggerConfigYaml, terraformDir string)
199201
}
200202
} else if config.GenerateProjectsConfig != nil {
201203
var dirWalker = &FileSystemTopLevelTerraformDirWalker{}
202-
dirs, err := dirWalker.GetDirs(terraformDir)
204+
dirs, err := dirWalker.GetDirs(terraformDir, config)
203205

204206
if err != nil {
205207
fmt.Printf("Error while walking through directories: %v", err)
@@ -410,22 +412,25 @@ func AutoDetectDiggerConfig(workingDir string) (*DiggerConfigYaml, error) {
410412
telemetry := true
411413
configYaml.Telemetry = &telemetry
412414

415+
TraverseToNestedProjects := false
416+
configYaml.TraverseToNestedProjects = &TraverseToNestedProjects
417+
413418
terragruntDirWalker := &FileSystemTerragruntDirWalker{}
414419
terraformDirWalker := &FileSystemTopLevelTerraformDirWalker{}
415420
moduleDirWalker := &FileSystemModuleDirWalker{}
416421

417-
terragruntDirs, err := terragruntDirWalker.GetDirs(workingDir)
422+
terragruntDirs, err := terragruntDirWalker.GetDirs(workingDir, configYaml)
418423

419424
if err != nil {
420425
return nil, err
421426
}
422427

423-
terraformDirs, err := terraformDirWalker.GetDirs(workingDir)
428+
terraformDirs, err := terraformDirWalker.GetDirs(workingDir, configYaml)
424429
if err != nil {
425430
return nil, err
426431
}
427432

428-
moduleDirs, err := moduleDirWalker.GetDirs(workingDir)
433+
moduleDirs, err := moduleDirWalker.GetDirs(workingDir, configYaml)
429434

430435
var modulePatterns []string
431436
for _, dir := range moduleDirs {

libs/digger_config/digger_config_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ func TestNoDiggerYaml(t *testing.T) {
9797
assert.Equal(t, 1, len(dg.Projects))
9898
assert.Equal(t, false, dg.AutoMerge)
9999
assert.Equal(t, true, dg.Telemetry)
100+
assert.Equal(t, false, dg.TraverseToNestedProjects)
100101
assert.Equal(t, 1, len(dg.Workflows))
101102
assert.Equal(t, "default", dg.Projects[0].Name)
102103
assert.Equal(t, "./", dg.Projects[0].Dir)
@@ -137,6 +138,7 @@ projects:
137138
assert.Equal(t, 1, len(dg.Projects))
138139
assert.Equal(t, false, dg.AutoMerge)
139140
assert.Equal(t, true, dg.Telemetry)
141+
assert.Equal(t, false, dg.TraverseToNestedProjects)
140142
assert.Equal(t, 1, len(dg.Workflows))
141143

142144
assert.Equal(t, "prod", dg.Projects[0].Name)
@@ -1114,3 +1116,44 @@ func TestDiggerGenerateProjectsMultipleBlocksDemo(t *testing.T) {
11141116
}
11151117

11161118
// todo test terragrunt digger_config with terragrunt_parsing block but without terragrunt: true
1119+
1120+
// TestDiggerTraverseToNestedProjects test if traverse_to_nested_projects is set to true, digger will traverse to nested projects
1121+
func TestDiggerTraverseToNestedProjects(t *testing.T) {
1122+
tempDir, teardown := setUp()
1123+
defer teardown()
1124+
1125+
diggerCfg := `
1126+
traverse_to_nested_projects: true
1127+
generate_projects:
1128+
blocks:
1129+
- include: dev/**
1130+
aws_role_to_assume:
1131+
state: "arn://abc:xyz:state"
1132+
command: "arn://abc:xyz:cmd"
1133+
`
1134+
deleteFile := createFile(path.Join(tempDir, "digger.yml"), diggerCfg)
1135+
defer deleteFile()
1136+
dirsToCreate := []string{"dev/test1", "dev/test2", "dev/project", "dev/project/test3", "testtt"}
1137+
1138+
for _, dir := range dirsToCreate {
1139+
err := os.MkdirAll(path.Join(tempDir, dir), os.ModePerm)
1140+
defer createFile(path.Join(tempDir, dir, "main.tf"), "")()
1141+
assert.NoError(t, err, "expected error to be nil")
1142+
}
1143+
1144+
dg, _, _, err := LoadDiggerConfig(tempDir)
1145+
assert.NoError(t, err, "expected error to be nil")
1146+
assert.NotNil(t, dg, "expected digger digger_config to be not nil")
1147+
assert.Equal(t, true, dg.TraverseToNestedProjects)
1148+
assert.Equal(t, 4, len(dg.Projects))
1149+
assert.Equal(t, "arn://abc:xyz:cmd", dg.Projects[0].AwsRoleToAssume.Command)
1150+
assert.Equal(t, "arn://abc:xyz:state", dg.Projects[0].AwsRoleToAssume.State)
1151+
assert.Equal(t, "dev_project", dg.Projects[0].Name)
1152+
assert.Equal(t, "dev/project", dg.Projects[0].Dir)
1153+
assert.Equal(t, "dev_project_test3", dg.Projects[1].Name)
1154+
assert.Equal(t, "dev/project/test3", dg.Projects[1].Dir)
1155+
assert.Equal(t, "dev_test1", dg.Projects[2].Name)
1156+
assert.Equal(t, "dev/test1", dg.Projects[2].Dir)
1157+
assert.Equal(t, "dev_test2", dg.Projects[3].Name)
1158+
assert.Equal(t, "dev/test2", dg.Projects[3].Dir)
1159+
}

libs/digger_config/yaml.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type DiggerConfigYaml struct {
1313
Workflows map[string]*WorkflowYaml `yaml:"workflows"`
1414
Telemetry *bool `yaml:"telemetry,omitempty"`
1515
GenerateProjectsConfig *GenerateProjectsConfigYaml `yaml:"generate_projects"`
16+
TraverseToNestedProjects *bool `yaml:"traverse_to_nested_projects"`
1617
MentionDriftedProjectsInPR *bool `yaml:"mention_drifted_projects_in_pr"`
1718
}
1819

0 commit comments

Comments
 (0)