Skip to content

Commit 84df362

Browse files
authored
feat: Adding --filter source= support (#5075)
1 parent d941ec9 commit 84df362

File tree

16 files changed

+231
-4
lines changed

16 files changed

+231
-4
lines changed

internal/component/component.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Component interface {
2828
SetExternal()
2929
Reading() []string
3030
SetReading(...string)
31+
Sources() []string
3132
DiscoveryContext() *DiscoveryContext
3233
SetDiscoveryContext(*DiscoveryContext)
3334
AddDependency(Component)

internal/component/stack.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ func (s *Stack) SetReading(files ...string) {
8787
s.reading = files
8888
}
8989

90+
// Sources returns the list of sources for this component.
91+
//
92+
// Stacks don't support leveraging sources right now, so we just return an empty list.
93+
func (s *Stack) Sources() []string {
94+
return []string{}
95+
}
96+
9097
// DiscoveryContext returns the discovery context for this component.
9198
func (s *Stack) DiscoveryContext() *DiscoveryContext {
9299
return s.discoveryContext

internal/component/unit.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,15 @@ func (u *Unit) SetReading(files ...string) {
9292
u.reading = files
9393
}
9494

95+
// Sources returns the list of sources for this component.
96+
func (u *Unit) Sources() []string {
97+
if u.cfg == nil || u.cfg.Terraform == nil || u.cfg.Terraform.Source == nil {
98+
return []string{}
99+
}
100+
101+
return []string{*u.cfg.Terraform.Source}
102+
}
103+
95104
// DiscoveryContext returns the discovery context for this component.
96105
func (u *Unit) DiscoveryContext() *DiscoveryContext {
97106
return u.discoveryContext

internal/filter/ast.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (a *AttributeFilter) CompileGlob() (glob.Glob, error) {
103103

104104
// supportsGlob returns true if the attribute filter supports glob patterns.
105105
func (a *AttributeFilter) supportsGlob() bool {
106-
return a.Key == AttributeReading || a.Key == AttributeName
106+
return a.Key == AttributeReading || a.Key == AttributeName || a.Key == AttributeSource
107107
}
108108

109109
func (a *AttributeFilter) expressionNode() {}

internal/filter/evaluator.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package filter
22

33
import (
44
"path/filepath"
5+
"slices"
56

67
"github.com/gruntwork-io/terragrunt/internal/component"
78
"github.com/gruntwork-io/terragrunt/pkg/log"
@@ -12,6 +13,7 @@ const (
1213
AttributeType = "type"
1314
AttributeExternal = "external"
1415
AttributeReading = "reading"
16+
AttributeSource = "source"
1517

1618
AttributeTypeValueUnit = string(component.UnitKind)
1719
AttributeTypeValueStack = string(component.StackKind)
@@ -148,6 +150,17 @@ func evaluateAttributeFilter(filter *AttributeFilter, components []component.Com
148150
}
149151
}
150152
}
153+
case AttributeSource:
154+
g, err := filter.CompileGlob()
155+
if err != nil {
156+
return nil, NewEvaluationErrorWithCause("failed to compile glob pattern for source filter: "+filter.Value, err)
157+
}
158+
159+
for _, c := range components {
160+
if slices.ContainsFunc(c.Sources(), g.Match) {
161+
result = append(result, c)
162+
}
163+
}
151164
default:
152165
return nil, NewEvaluationError("unknown attribute key: " + filter.Key)
153166
}

internal/filter/evaluator_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package filter_test
33
import (
44
"testing"
55

6+
"github.com/gruntwork-io/terragrunt/config"
67
"github.com/gruntwork-io/terragrunt/internal/component"
78
"github.com/gruntwork-io/terragrunt/internal/filter"
89
"github.com/gruntwork-io/terragrunt/pkg/log"
10+
"github.com/gruntwork-io/terragrunt/test/helpers"
911
"github.com/stretchr/testify/assert"
1012
"github.com/stretchr/testify/require"
1113
)
@@ -263,6 +265,67 @@ func TestEvaluate_AttributeFilter_Reading(t *testing.T) {
263265
}
264266
}
265267

268+
func TestEvaluate_AttributeFilter_Source(t *testing.T) {
269+
t.Parallel()
270+
271+
components := []component.Component{
272+
component.NewUnit("./apps/app1").WithConfig(
273+
&config.TerragruntConfig{
274+
Terraform: &config.TerraformConfig{
275+
Source: helpers.PointerTo("github.com/acme/foo"),
276+
},
277+
},
278+
),
279+
component.NewUnit("./apps/app2").WithConfig(
280+
&config.TerragruntConfig{
281+
Terraform: &config.TerraformConfig{
282+
Source: helpers.PointerTo("git::[email protected]:acme/bar?ref=v1.0.0"),
283+
},
284+
},
285+
),
286+
}
287+
288+
tests := []struct {
289+
name string
290+
filter *filter.AttributeFilter
291+
expected []component.Component
292+
}{
293+
{
294+
name: "glob pattern with single wildcard - github.com/acme/*",
295+
filter: &filter.AttributeFilter{Key: "source", Value: "github.com/acme/*"},
296+
expected: []component.Component{
297+
components[0],
298+
},
299+
},
300+
{
301+
name: "glob pattern with double wildcard - git::[email protected]:acme/**",
302+
filter: &filter.AttributeFilter{Key: "source", Value: "git::[email protected]:acme/**"},
303+
expected: []component.Component{
304+
components[1],
305+
},
306+
},
307+
{
308+
name: "glob pattern with double wildcard - **github.com**",
309+
filter: &filter.AttributeFilter{Key: "source", Value: "**github.com**"},
310+
expected: []component.Component{
311+
components[0],
312+
components[1],
313+
},
314+
},
315+
}
316+
317+
for _, tt := range tests {
318+
t.Run(tt.name, func(t *testing.T) {
319+
t.Parallel()
320+
321+
l := log.New()
322+
result, err := filter.Evaluate(l, tt.filter, components)
323+
require.NoError(t, err)
324+
assert.ElementsMatch(t, tt.expected, result)
325+
})
326+
}
327+
}
328+
266329
func TestEvaluate_AttributeFilter_Reading_ComponentAddedOnlyOnce(t *testing.T) {
267330
t.Parallel()
268331

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Empty module
2+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
terraform {
2+
source = "git::[email protected]:acme/bar?ref=v1.0.0"
3+
}
4+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Empty module
2+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
terraform {
2+
source = "github.com/acme/foo"
3+
}
4+

0 commit comments

Comments
 (0)