Skip to content

Commit

Permalink
conditional reference
Browse files Browse the repository at this point in the history
  • Loading branch information
bfoley13 committed Oct 29, 2024
1 parent 6885973 commit 2fa805a
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 14 deletions.
23 changes: 15 additions & 8 deletions pkg/config/draftconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,29 @@ type DraftConfig struct {
}

type BuilderVar struct {
Name string `yaml:"name"`
Default BuilderVarDefault `yaml:"default"`
Description string `yaml:"description"`
ExampleValues []string `yaml:"exampleValues"`
Type string `yaml:"type"`
Kind string `yaml:"kind"`
Value string `yaml:"value"`
Versions string `yaml:"versions"`
Name string `yaml:"name"`
ConditionalRef BuilderVarConditionalReference `yaml:"conditionalReference"`
Default BuilderVarDefault `yaml:"default"`
Description string `yaml:"description"`
ExampleValues []string `yaml:"exampleValues"`
Type string `yaml:"type"`
Kind string `yaml:"kind"`
Value string `yaml:"value"`
Versions string `yaml:"versions"`
}

// BuilderVarDefault holds info on the default value of a variable
type BuilderVarDefault struct {
IsPromptDisabled bool `yaml:"disablePrompt"`
ReferenceVar string `yaml:"referenceVar"`
Value string `yaml:"value"`
}

// BuilderVarConditionalReference holds a reference to a variable thats value can effect validation/transformation of the associated variable
type BuilderVarConditionalReference struct {
ReferenceVar string `yaml:"referenceVar"`
}

func NewConfigFromFS(fileSys fs.FS, path string) (*DraftConfig, error) {
configBytes, err := fs.ReadFile(fileSys, path)
if err != nil {
Expand Down
54 changes: 48 additions & 6 deletions pkg/config/draftconfig_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func loadTemplatesWithValidation() error {
// }

referenceVarMap := map[string]*BuilderVar{}
conditionRefMap := map[string]*BuilderVar{}
allVariables := map[string]*BuilderVar{}
for _, variable := range currTemplate.Variables {
if variable.Name == "" {
Expand All @@ -130,20 +131,39 @@ func loadTemplatesWithValidation() error {
if variable.Default.ReferenceVar != "" {
referenceVarMap[variable.Name] = variable
}

if variable.ConditionalRef.ReferenceVar != "" {
conditionRefMap[variable.Name] = variable
}
}

for _, currVar := range referenceVarMap {
refVar, ok := allVariables[currVar.Default.ReferenceVar]
if !ok {
return fmt.Errorf("template %s has a variable %s with reference to a non-existent variable: %s", path, currVar.Name, currVar.Default.ReferenceVar)
return fmt.Errorf("template %s has a variable %s with default reference to a non-existent variable: %s", path, currVar.Name, currVar.Default.ReferenceVar)
}

if currVar.Name == refVar.Name {
return fmt.Errorf("template %s has a variable with cyclical reference to itself: %s", path, currVar.Name)
return fmt.Errorf("template %s has a variable with cyclical default reference to itself: %s", path, currVar.Name)
}

if isCyclicalVariableReference(currVar, refVar, allVariables, map[string]bool{}) {
return fmt.Errorf("template %s has a variable with cyclical reference to itself: %s", path, currVar.Name)
if isCyclicalDefaultVariableReference(currVar, refVar, allVariables, map[string]bool{}) {
return fmt.Errorf("template %s has a variable with cyclical default reference to itself: %s", path, currVar.Name)
}
}

for _, currVar := range conditionRefMap {
refVar, ok := allVariables[currVar.ConditionalRef.ReferenceVar]
if !ok {
return fmt.Errorf("template %s has a variable %s with conditional reference to a non-existent variable: %s", path, currVar.Name, currVar.ConditionalRef.ReferenceVar)
}

if currVar.Name == refVar.Name {
return fmt.Errorf("template %s has a variable with cyclical conditional reference to itself: %s", path, currVar.Name)
}

if isCyclicalConditionalVariableReference(currVar, refVar, allVariables, map[string]bool{}) {
return fmt.Errorf("template %s has a variable with cyclical conditional reference to itself: %s", path, currVar.Name)
}
}

Expand All @@ -152,7 +172,7 @@ func loadTemplatesWithValidation() error {
})
}

func isCyclicalVariableReference(initialVar, currRefVar *BuilderVar, allVariables map[string]*BuilderVar, visited map[string]bool) bool {
func isCyclicalDefaultVariableReference(initialVar, currRefVar *BuilderVar, allVariables map[string]*BuilderVar, visited map[string]bool) bool {
if initialVar.Name == currRefVar.Name {
return true
}
Expand All @@ -171,5 +191,27 @@ func isCyclicalVariableReference(initialVar, currRefVar *BuilderVar, allVariable
}

visited[currRefVar.Name] = true
return isCyclicalVariableReference(initialVar, refVar, allVariables, visited)
return isCyclicalDefaultVariableReference(initialVar, refVar, allVariables, visited)
}

func isCyclicalConditionalVariableReference(initialVar, currRefVar *BuilderVar, allVariables map[string]*BuilderVar, visited map[string]bool) bool {
if initialVar.Name == currRefVar.Name {
return true
}

if _, ok := visited[currRefVar.Name]; ok {
return true
}

if currRefVar.ConditionalRef.ReferenceVar == "" {
return false
}

refVar, ok := allVariables[currRefVar.ConditionalRef.ReferenceVar]
if !ok {
return false
}

visited[currRefVar.Name] = true
return isCyclicalConditionalVariableReference(initialVar, refVar, allVariables, visited)
}

0 comments on commit 2fa805a

Please sign in to comment.