diff --git a/internal/exec/vendor_utils.go b/internal/exec/vendor_utils.go index d2d5cd7a6..c4cb4f06f 100644 --- a/internal/exec/vendor_utils.go +++ b/internal/exec/vendor_utils.go @@ -153,7 +153,8 @@ func ReadAndProcessVendorConfigFile( if !u.FileExists(pathToVendorConfig) { vendorConfigFileExists = false - return vendorConfig, vendorConfigFileExists, "", fmt.Errorf("vendor config file or directory '%s' does not exist", pathToVendorConfig) + u.LogWarning(cliConfig, fmt.Sprintf("Vendor config file '%s' does not exist. Proceeding without vendor configurations", pathToVendorConfig)) + return vendorConfig, vendorConfigFileExists, "", nil } foundVendorConfigFile = pathToVendorConfig diff --git a/pkg/vender/vendor_config_test.go b/pkg/vender/vendor_config_test.go new file mode 100644 index 000000000..a37bf2696 --- /dev/null +++ b/pkg/vender/vendor_config_test.go @@ -0,0 +1,144 @@ +// The package name `vendor` is reserved in Go for dependency management. +// To avoid conflicts, the name `vender` was chosen as an alternative. +package vender + +import ( + "os" + "path" + "testing" + + "github.com/stretchr/testify/assert" + + e "github.com/cloudposse/atmos/internal/exec" + "github.com/cloudposse/atmos/pkg/schema" +) + +func TestVendorConfigScenarios(t *testing.T) { + testDir := t.TempDir() + + // Initialize CLI config with required paths + cliConfig := schema.CliConfiguration{ + BasePath: testDir, + Components: schema.Components{ + Terraform: schema.Terraform{ + BasePath: "components/terraform", + }, + }, + } + cliConfig.Logs.Level = "Trace" + + // Setup test component directory + componentPath := path.Join(testDir, "components", "terraform", "myapp") + err := os.MkdirAll(componentPath, 0755) + assert.Nil(t, err) + + // Test Case 1: vendor.yaml exists and component is defined in it + t.Run("vendor.yaml exists with defined component", func(t *testing.T) { + // Create vendor.yaml + vendorYaml := `apiVersion: atmos/v1 +kind: AtmosVendorConfig +metadata: + name: test-vendor-config +spec: + sources: + - component: myapp + source: github.com/cloudposse/terraform-null-label.git//exports?ref={{.Version}} + version: 0.25.0 + included_paths: + - "**/*.tf" +` + vendorYamlPath := path.Join(testDir, "vendor.yaml") + err := os.WriteFile(vendorYamlPath, []byte(vendorYaml), 0644) + assert.Nil(t, err) + + // Test vendoring with component flag + vendorConfig, exists, configFile, err := e.ReadAndProcessVendorConfigFile(cliConfig, vendorYamlPath) + assert.Nil(t, err) + assert.True(t, exists) + assert.NotEmpty(t, configFile) + + // Verify the component exists in vendor config + var found bool + for _, source := range vendorConfig.Spec.Sources { + if source.Component == "myapp" { + found = true + break + } + } + assert.True(t, found, "Component 'myapp' should be defined in vendor.yaml") + + // Clean up + err = os.Remove(vendorYamlPath) + assert.Nil(t, err) + }) + + // Test Case 2: No vendor.yaml but component.yaml exists + t.Run("component.yaml exists without vendor.yaml", func(t *testing.T) { + // Create component.yaml + componentYaml := `apiVersion: atmos/v1 +kind: ComponentVendorConfig +metadata: + name: myapp-vendor-config +spec: + source: + uri: github.com/cloudposse/terraform-null-label.git//exports?ref={{.Version}} + version: 0.25.0 +` + componentYamlPath := path.Join(componentPath, "component.yaml") + err := os.WriteFile(componentYamlPath, []byte(componentYaml), 0644) + assert.Nil(t, err) + + // Test component vendoring + componentConfig, compPath, err := e.ReadAndProcessComponentVendorConfigFile(cliConfig, "myapp", "terraform") + assert.Nil(t, err) + assert.NotNil(t, componentConfig) + assert.Equal(t, componentPath, compPath) + + // Clean up + err = os.Remove(componentYamlPath) + assert.Nil(t, err) + }) + + // Test Case 3: Neither vendor.yaml nor component.yaml exists + t.Run("no vendor.yaml or component.yaml", func(t *testing.T) { + // Test vendoring with component flag + vendorYamlPath := path.Join(testDir, "vendor.yaml") + _, exists, _, err := e.ReadAndProcessVendorConfigFile(cliConfig, vendorYamlPath) + assert.Nil(t, err) + assert.False(t, exists) + + // Test component vendoring + _, _, err = e.ReadAndProcessComponentVendorConfigFile(cliConfig, "myapp", "terraform") + assert.Error(t, err) + assert.Contains(t, err.Error(), "does not exist") + }) + + // Test Case 4: No component specified with vendor.yaml + t.Run("no component specified with vendor.yaml", func(t *testing.T) { + // Create vendor.yaml + vendorYaml := `apiVersion: atmos/v1 +kind: AtmosVendorConfig +metadata: + name: test-vendor-config +spec: + sources: + - component: myapp + source: github.com/cloudposse/terraform-null-label.git//exports?ref={{.Version}} + version: 0.25.0 +` + vendorYamlPath := path.Join(testDir, "vendor.yaml") + err := os.WriteFile(vendorYamlPath, []byte(vendorYaml), 0644) + assert.Nil(t, err) + + // Test vendoring without component flag + vendorConfig, exists, configFile, err := e.ReadAndProcessVendorConfigFile(cliConfig, vendorYamlPath) + assert.Nil(t, err) + assert.True(t, exists) + assert.NotEmpty(t, configFile) + assert.NotNil(t, vendorConfig.Spec.Sources) + + // Clean up + err = os.Remove(vendorYamlPath) + assert.Nil(t, err) + }) +}