Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions internal/stacks/stackconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,17 @@
}
finalRel := rel.Versioned(selectedVersion)
return sourceaddrs.ResolveRelativeFinalSource(base, finalRel)

case sourceaddrs.ComponentSource:
// Component registry sources work similar to module registry sources
allowedVersions := versions.MeetingConstraints(versionConstraints)
availableVersions := sources.ComponentPackageVersions(rel.Package())

Check failure on line 398 in internal/stacks/stackconfig/config.go

View workflow job for this annotation

GitHub Actions / Race Tests

sources.ComponentPackageVersions undefined (type *sourcebundle.Bundle has no field or method ComponentPackageVersions)

Check failure on line 398 in internal/stacks/stackconfig/config.go

View workflow job for this annotation

GitHub Actions / End-to-end Tests

sources.ComponentPackageVersions undefined (type *sourcebundle.Bundle has no field or method ComponentPackageVersions)

Check failure on line 398 in internal/stacks/stackconfig/config.go

View workflow job for this annotation

GitHub Actions / Equivalence Test Diff

sources.ComponentPackageVersions undefined (type *sourcebundle.Bundle has no field or method ComponentPackageVersions)

Check failure on line 398 in internal/stacks/stackconfig/config.go

View workflow job for this annotation

GitHub Actions / Unit Tests

sources.ComponentPackageVersions undefined (type *sourcebundle.Bundle has no field or method ComponentPackageVersions)

Check failure on line 398 in internal/stacks/stackconfig/config.go

View workflow job for this annotation

GitHub Actions / Code Consistency Checks

sources.ComponentPackageVersions undefined (type *sourcebundle.Bundle has no field or method ComponentPackageVersions)
selectedVersion := availableVersions.NewestInSet(allowedVersions)
if selectedVersion == versions.Unspecified {
return nil, fmt.Errorf("no cached versions of %s match the given version constraints", rel.Package())
}
finalRel := rel.Versioned(selectedVersion)
return sourceaddrs.ResolveRelativeFinalSource(base, finalRel)
default:
// Should not get here because the above cases should be exhaustive
// for all implementations of sourceaddrs.Source.
Expand Down
82 changes: 82 additions & 0 deletions internal/stacks/stackconfig/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,85 @@ func TestOmittingBuiltInProviders(t *testing.T) {
})
})
}

func TestComponentSourceResolution(t *testing.T) {
bundle, err := sourcebundle.OpenDir("testdata/basics-bundle")
if err != nil {
t.Fatal(err)
}

rootAddr := sourceaddrs.MustParseSource("git::https://example.com/component-test.git").(sourceaddrs.RemoteSource)
config, diags := LoadConfigDir(rootAddr, bundle)
if len(diags) != 0 {
t.Fatalf("unexpected diagnostics:\n%s", diags.NonFatalErr().Error())
}

t.Run("component source resolution", func(t *testing.T) {
// Verify that the component was loaded
if got, want := len(config.Root.Stack.Components), 1; got != want {
t.Errorf("wrong number of components %d; want %d", got, want)
}

t.Run("pet-nulls component", func(t *testing.T) {
cmpn, ok := config.Root.Stack.Components["pet-nulls"]
if !ok {
t.Fatal("Root stack config has no component named \"pet-nulls\".")
}

// Verify component name
if got, want := cmpn.Name, "pet-nulls"; got != want {
t.Errorf("wrong component name\ngot: %s\nwant: %s", got, want)
}

// Verify that the source address was parsed correctly
componentSource, ok := cmpn.SourceAddr.(sourceaddrs.ComponentSource)
if !ok {
t.Fatalf("expected ComponentSource, got %T", cmpn.SourceAddr)
}

expectedSourceStr := "app.staging.terraform.io/component-configurations/pet-nulls"
if got := componentSource.String(); got != expectedSourceStr {
t.Errorf("wrong source address\ngot: %s\nwant: %s", got, expectedSourceStr)
}

// Verify that version constraints were parsed
if cmpn.VersionConstraints == nil {
t.Fatal("component has no version constraints")
}

// Verify that the final source address was resolved
if cmpn.FinalSourceAddr == nil {
t.Fatal("component FinalSourceAddr was not resolved")
}

// The final source should be a ComponentSourceFinal
componentSourceFinal, ok := cmpn.FinalSourceAddr.(sourceaddrs.ComponentSourceFinal)
if !ok {
t.Fatalf("expected ComponentSourceFinal for FinalSourceAddr, got %T", cmpn.FinalSourceAddr)
}

// Verify it resolved to the correct version (0.0.2)
expectedVersion := "0.0.2"
if got := componentSourceFinal.SelectedVersion().String(); got != expectedVersion {
t.Errorf("wrong selected version\ngot: %s\nwant: %s", got, expectedVersion)
}

// Verify the unversioned component source matches
if got := componentSourceFinal.Unversioned().String(); got != expectedSourceStr {
t.Errorf("wrong unversioned source in final address\ngot: %s\nwant: %s", got, expectedSourceStr)
}

// Verify we can get the local path from the bundle
localPath, err := bundle.LocalPathForSource(cmpn.FinalSourceAddr)
if err != nil {
t.Fatalf("failed to get local path for component source: %s", err)
}

// The local path should point to the pet-nulls directory
if localPath == "" {
t.Error("local path is empty")
}
t.Logf("Component resolved to local path: %s", localPath)
})
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
component "pet-nulls" {
source = "app.staging.terraform.io/component-configurations/pet-nulls"
version = "0.0.2"

inputs = {
instances = var.instances
prefix = var.prefix
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variable "instances" {
type = number
}

variable "prefix" {
type = string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
variable "instances" {
type = number
}

variable "prefix" {
type = string
}

resource "null_resource" "pet" {
count = var.instances
}

output "pet_ids" {
value = null_resource.pet[*].id
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
"source": "git::https://example.com/builtin.git",
"local": "builtin",
"meta": {}
},
{
"source": "git::https://example.com/component-test.git",
"local": "component-test",
"meta": {}
},
{
"source": "git::https://example.com/pet-nulls.git?ref=v0.0.2",
"local": "pet-nulls",
"meta": {}
}
],
"registry": [
Expand All @@ -44,5 +54,18 @@
}
}
}
],
"components": [
{
"source": "app.staging.terraform.io/component-configurations/pet-nulls",
"versions": {
"0.0.1": {
"source": "git::https://example.com/pet-nulls.git?ref=v0.0.1"
},
"0.0.2": {
"source": "git::https://example.com/pet-nulls.git?ref=v0.0.2"
}
}
}
]
}
Loading