From ccebfc312ba54564a5f5c97fb5bc2714d3f7e510 Mon Sep 17 00:00:00 2001 From: Sam Tholiya Date: Sun, 9 Mar 2025 18:03:16 +0100 Subject: [PATCH] refactor schema name --- internal/exec/validate_stacks.go | 6 +-- pkg/config/config.go | 1 + pkg/config/utils.go | 4 +- pkg/schema/schema.go | 68 +++++++++++++++++++++++++++----- pkg/schema/schema_test.go | 2 +- 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/internal/exec/validate_stacks.go b/internal/exec/validate_stacks.go index 523ec32bd..73602f9a3 100644 --- a/internal/exec/validate_stacks.go +++ b/internal/exec/validate_stacks.go @@ -55,7 +55,7 @@ func ExecuteValidateStacksCmd(cmd *cobra.Command, args []string) error { } if schemasAtmosManifestFlag != "" { - atmosConfig.Schemas["atmos"] = schema.Schemas{ + atmosConfig.Schemas["atmos"] = schema.SchemaRegistry{ Manifest: schemasAtmosManifestFlag, } } @@ -102,7 +102,7 @@ func ValidateStacks(atmosConfig schema.AtmosConfiguration) error { // Check if the Atmos manifest JSON Schema is configured and the file exists // The path to the Atmos manifest JSON Schema can be absolute path or a path relative to the `base_path` setting in `atmos.yaml` var atmosManifestJsonSchemaFilePath string - manifestSchema := atmosConfig.GetSchemas("atmos") + manifestSchema := atmosConfig.GetSchemaRegistry("atmos") atmosManifestJsonSchemaFileAbsPath := filepath.Join(atmosConfig.BasePath, manifestSchema.Manifest) if manifestSchema.Manifest == "" { @@ -386,7 +386,7 @@ func checkComponentStackMap(componentStackMap map[string]map[string][]string) ([ // downloadSchemaFromURL downloads the Atmos JSON Schema file from the provided URL func downloadSchemaFromURL(atmosConfig schema.AtmosConfiguration) (string, error) { - manifestSchema := atmosConfig.GetSchemas("atmos") + manifestSchema := atmosConfig.GetSchemaRegistry("atmos") manifestURL := manifestSchema.Manifest parsedURL, err := url.Parse(manifestURL) if err != nil { diff --git a/pkg/config/config.go b/pkg/config/config.go index 2709e3a17..32fbba4a1 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -258,6 +258,7 @@ func InitCliConfig(configAndStacksInfo schema.ConfigAndStacksInfo, processStacks // https://gist.github.com/chazcheadle/45bf85b793dea2b71bd05ebaa3c28644 // https://sagikazarmark.hu/blog/decoding-custom-formats-with-viper/ err = v.Unmarshal(&atmosConfig) + atmosConfig.ProcessSchemas() if err != nil { return atmosConfig, err } diff --git a/pkg/config/utils.go b/pkg/config/utils.go index 7937d616c..b832b5cff 100644 --- a/pkg/config/utils.go +++ b/pkg/config/utils.go @@ -351,7 +351,7 @@ func processEnvVars(atmosConfig *schema.AtmosConfiguration) error { atmosManifestJsonSchemaPath := os.Getenv("ATMOS_SCHEMAS_ATMOS_MANIFEST") if len(atmosManifestJsonSchemaPath) > 0 { u.LogDebug(fmt.Sprintf("Found ENV var ATMOS_SCHEMAS_ATMOS_MANIFEST=%s", atmosManifestJsonSchemaPath)) - atmosConfig.Schemas["atmos"] = schema.Schemas{ + atmosConfig.Schemas["atmos"] = schema.SchemaRegistry{ Manifest: atmosManifestJsonSchemaPath, } } @@ -493,7 +493,7 @@ func processCommandLineArgs(atmosConfig *schema.AtmosConfiguration, configAndSta u.LogDebug(fmt.Sprintf("Using command line argument '%s' as CUE schemas directory", configAndStacksInfo.CueDir)) } if len(configAndStacksInfo.AtmosManifestJsonSchema) > 0 { - atmosConfig.Schemas["atmos"] = schema.Schemas{ + atmosConfig.Schemas["atmos"] = schema.SchemaRegistry{ Manifest: configAndStacksInfo.AtmosManifestJsonSchema, } u.LogDebug(fmt.Sprintf("Using command line argument '%s' as path to Atmos JSON Schema", configAndStacksInfo.AtmosManifestJsonSchema)) diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go index 74bb3987d..8df1c1c4c 100644 --- a/pkg/schema/schema.go +++ b/pkg/schema/schema.go @@ -1,6 +1,8 @@ package schema import ( + "encoding/json" + "github.com/cloudposse/atmos/pkg/store" "gopkg.in/yaml.v3" ) @@ -41,28 +43,28 @@ type AtmosConfiguration struct { CliConfigPath string `yaml:"cli_config_path" json:"cli_config_path,omitempty" mapstructure:"cli_config_path"` } -func (m *AtmosConfiguration) GetSchemas(key string) Schemas { +func (m *AtmosConfiguration) GetSchemaRegistry(key string) SchemaRegistry { atmosSchemaInterface, interfaceOk := m.Schemas[key] - var manifestSchema Schemas + var manifestSchema SchemaRegistry atmosSchemaFound := false if interfaceOk { - manifestSchema, atmosSchemaFound = atmosSchemaInterface.(Schemas) + manifestSchema, atmosSchemaFound = atmosSchemaInterface.(SchemaRegistry) } if atmosSchemaFound { return manifestSchema } - return Schemas{} + return SchemaRegistry{} } func (m *AtmosConfiguration) GetResourcePath(key string) ResourcePath { atmosSchemaInterface, interfaceOk := m.Schemas[key] - var manifestSchema ResourcePath + var resourcePath ResourcePath atmosSchemaFound := false if interfaceOk { - manifestSchema, atmosSchemaFound = atmosSchemaInterface.(ResourcePath) + resourcePath, atmosSchemaFound = atmosSchemaInterface.(ResourcePath) } if atmosSchemaFound { - return manifestSchema + return resourcePath } return ResourcePath{} } @@ -101,7 +103,7 @@ func (m *AtmosConfiguration) UnmarshalYAML(value *yaml.Node) error { } // Try decoding as Manifest struct - var manifest Schemas + var manifest SchemaRegistry if err := node.Decode(&manifest); err == nil { m.Schemas[key] = manifest continue @@ -114,6 +116,54 @@ func (m *AtmosConfiguration) UnmarshalYAML(value *yaml.Node) error { return nil } +func (a *AtmosConfiguration) ProcessSchemas() error { + for key := range a.Schemas { + if key == "cue" || key == "opa" || key == "jsonschema" { + a.processResourceSchema(key) + continue + } + a.processManifestSchemas(key) + } + return nil +} + +func (a *AtmosConfiguration) processManifestSchemas(key string) { + val, exists := a.Schemas[key] + if !exists { + return + } + // Marshal the interface{} to JSON + data, err := json.Marshal(val) + if err != nil { + return + } + // Unmarshal JSON into ResourcePath struct + var schemasStruct SchemaRegistry + if err := json.Unmarshal(data, &schemasStruct); err != nil { + return + } + a.Schemas[key] = schemasStruct +} + +func (a *AtmosConfiguration) processResourceSchema(key string) { + val, exists := a.Schemas[key] + if !exists { + return + } + // Marshal the interface{} to JSON + data, err := json.Marshal(val) + if err != nil { + return + } + + // Unmarshal JSON into ResourcePath struct + var resource ResourcePath + if err := json.Unmarshal(data, &resource); err != nil { + return + } + a.Schemas[key] = resource +} + type Validate struct { EditorConfig EditorConfig `yaml:"editorconfig,omitempty" json:"editorconfig,omitempty" mapstructure:"editorconfig"` } @@ -554,7 +604,7 @@ type ResourcePath struct { BasePath string `yaml:"base_path,omitempty" json:"base_path,omitempty" mapstructure:"base_path"` } -type Schemas struct { +type SchemaRegistry struct { Manifest string `yaml:"manifest,omitempty" json:"manifest,omitempty" mapstructure:"manifest"` Matches []string `yaml:"matches,omitempty" json:"matches,omitempty" mapstructure:"matches"` } diff --git a/pkg/schema/schema_test.go b/pkg/schema/schema_test.go index 918730381..f95e37c8e 100644 --- a/pkg/schema/schema_test.go +++ b/pkg/schema/schema_test.go @@ -32,7 +32,7 @@ schemas: atmosConfig := &AtmosConfiguration{} err := yaml.Unmarshal([]byte(yamlString), atmosConfig) assert.NoError(t, err) - schemas := atmosConfig.GetSchemas("atmos") + schemas := atmosConfig.GetSchemaRegistry("atmos") assert.Equal(t, "some/random/path", schemas.Manifest) assert.Equal(t, []string{"hello", "world"}, schemas.Matches) }