Skip to content

Commit fea83a4

Browse files
Mauricio FerrariVidya2606
andauthored
Draft Config Refactor (#320)
Co-authored-by: Vidya Reddy <[email protected]>
1 parent 01afd05 commit fea83a4

File tree

30 files changed

+353
-347
lines changed

30 files changed

+353
-347
lines changed

cmd/create.go

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -265,20 +265,22 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan
265265
return err
266266
}
267267

268-
// Check for existing duplicate defualts
268+
// Check for existing duplicate defaults
269269
for k, v := range extractedValues {
270270
variableExists := false
271-
for i, varD := range langConfig.VariableDefaults {
272-
if k == varD.Name {
271+
for i, variable := range langConfig.Variables {
272+
if k == variable.Name {
273273
variableExists = true
274-
langConfig.VariableDefaults[i].Value = v
274+
langConfig.Variables[i].Default.Value = v
275275
break
276276
}
277277
}
278278
if !variableExists {
279-
langConfig.VariableDefaults = append(langConfig.VariableDefaults, config.BuilderVarDefault{
280-
Name: k,
281-
Value: v,
279+
langConfig.Variables = append(langConfig.Variables, config.BuilderVar{
280+
Name: k,
281+
Default: config.BuilderVarDefault{
282+
Value: v,
283+
},
282284
})
283285
}
284286
}
@@ -290,7 +292,7 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan
290292
return err
291293
}
292294
} else {
293-
inputs, err = validateConfigInputsToPrompts(langConfig.Variables, cc.createConfig.LanguageVariables, langConfig.VariableDefaults)
295+
inputs, err = validateConfigInputsToPrompts(langConfig.Variables, cc.createConfig.LanguageVariables)
294296
if err != nil {
295297
return err
296298
}
@@ -328,7 +330,7 @@ func (cc *createCmd) createDeployment() error {
328330
if deployConfig == nil {
329331
return errors.New("invalid deployment type")
330332
}
331-
customInputs, err = validateConfigInputsToPrompts(deployConfig.Variables, cc.createConfig.DeployVariables, deployConfig.VariableDefaults)
333+
customInputs, err = validateConfigInputsToPrompts(deployConfig.Variables, cc.createConfig.DeployVariables)
332334
if err != nil {
333335
return err
334336
}
@@ -462,7 +464,7 @@ func init() {
462464
rootCmd.AddCommand(newCreateCmd())
463465
}
464466

465-
func validateConfigInputsToPrompts(required []config.BuilderVar, provided []UserInputs, defaults []config.BuilderVarDefault) (map[string]string, error) {
467+
func validateConfigInputsToPrompts(required []config.BuilderVar, provided []UserInputs) (map[string]string, error) {
466468
customInputs := make(map[string]string)
467469

468470
// set inputs to provided values
@@ -471,24 +473,27 @@ func validateConfigInputsToPrompts(required []config.BuilderVar, provided []User
471473
}
472474

473475
// fill in missing vars using variable default references
474-
for _, variableDefault := range defaults {
475-
if customInputs[variableDefault.Name] == "" && variableDefault.ReferenceVar != "" {
476-
log.Debugf("variable %s is empty, using default referenceVar value from %s", variableDefault.Name, variableDefault.ReferenceVar)
477-
customInputs[variableDefault.Name] = customInputs[variableDefault.ReferenceVar]
476+
for _, variable := range required {
477+
if customInputs[variable.Name] == "" && variable.Default.ReferenceVar != "" {
478+
log.Debugf("variable %s is empty, using default referenceVar value from %s", variable.Name, variable.Default.ReferenceVar)
479+
customInputs[variable.Name] = customInputs[variable.Default.ReferenceVar]
478480
}
479481
}
480482

481483
// fill in missing vars using variable default values
482-
for _, variableDefault := range defaults {
483-
if customInputs[variableDefault.Name] == "" && variableDefault.Value != "" {
484-
log.Debugf("setting default value for %s to %s", variableDefault.Name, variableDefault.Value)
485-
customInputs[variableDefault.Name] = variableDefault.Value
484+
for _, variable := range required {
485+
if customInputs[variable.Name] == "" && variable.Default.Value != "" {
486+
log.Debugf("variable %s is empty, using default value %s", variable.Name, variable.Default.Value)
487+
customInputs[variable.Name] = variable.Default.Value
486488
}
487489
}
488490

489491
for _, variable := range required {
490-
if _, ok := customInputs[variable.Name]; !ok {
492+
value, ok := customInputs[variable.Name]
493+
if !ok {
491494
return nil, fmt.Errorf("config missing required variable: %s with description: %s", variable.Name, variable.Description)
495+
} else if value == "" {
496+
return nil, fmt.Errorf("value for variable %s is empty", variable.Name)
492497
}
493498
}
494499

cmd/create_test.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,32 +143,39 @@ func TestInitConfig(t *testing.T) {
143143

144144
func TestValidateConfigInputsToPromptsPass(t *testing.T) {
145145
required := []config.BuilderVar{
146-
{Name: "REQUIRED_PROVIDED"},
147-
{Name: "REQUIRED_DEFAULTED"},
146+
{
147+
Name: "REQUIRED_PROVIDED",
148+
},
149+
{
150+
Name: "REQUIRED_DEFAULTED",
151+
Default: config.BuilderVarDefault{
152+
Value: "DEFAULT_VALUE",
153+
},
154+
},
148155
}
149156
provided := []UserInputs{
150157
{Name: "REQUIRED_PROVIDED", Value: "PROVIDED_VALUE"},
151158
}
152-
defaults := []config.BuilderVarDefault{
153-
{Name: "REQUIRED_DEFAULTED", Value: "DEFAULT_VALUE"},
154-
}
155159

156-
vars, err := validateConfigInputsToPrompts(required, provided, defaults)
160+
vars, err := validateConfigInputsToPrompts(required, provided)
157161
assert.True(t, err == nil)
158162
assert.Equal(t, vars["REQUIRED_DEFAULTED"], "DEFAULT_VALUE")
159163
}
160164

161165
func TestValidateConfigInputsToPromptsMissing(t *testing.T) {
162166
required := []config.BuilderVar{
163-
{Name: "REQUIRED_PROVIDED"},
164-
{Name: "REQUIRED_MISSING"},
167+
{
168+
Name: "REQUIRED_PROVIDED",
169+
},
170+
{
171+
Name: "REQUIRED_MISSING",
172+
},
165173
}
166174
provided := []UserInputs{
167175
{Name: "REQUIRED_PROVIDED"},
168176
}
169-
defaults := []config.BuilderVarDefault{}
170177

171-
_, err := validateConfigInputsToPrompts(required, provided, defaults)
178+
_, err := validateConfigInputsToPrompts(required, provided)
172179
assert.NotNil(t, err)
173180
}
174181

cmd/setup-gh.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func fillSetUpConfig(sc *providers.SetUpCmd) error {
8787
return fmt.Errorf("getting subscription labels: %w", err)
8888
}
8989

90-
sc.SubscriptionID, err = GetAzSubscriptionId(subLabels, currentSub)
90+
sc.SubscriptionID, err = getAzSubscriptionId(subLabels, currentSub)
9191
if err != nil {
9292
return fmt.Errorf("getting subscription ID: %w", err)
9393
}
@@ -223,7 +223,7 @@ func getCloudProvider() string {
223223
return selectResponse
224224
}
225225

226-
func GetAzSubscriptionId(subLabels []providers.SubLabel, currentSub providers.SubLabel) (string, error) {
226+
func getAzSubscriptionId(subLabels []providers.SubLabel, currentSub providers.SubLabel) (string, error) {
227227
subLabel, err := prompts.Select("Please choose the subscription ID you would like to use", subLabels, &prompts.SelectOpt[providers.SubLabel]{
228228
Field: func(subLabel providers.SubLabel) string {
229229
return subLabel.Name + " (" + subLabel.ID + ")"

pkg/config/draftconfig.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package config
22

33
import (
4+
"errors"
5+
46
log "github.com/sirupsen/logrus"
57
)
68

79
// TODO: remove Name Overrides since we don't need them anymore
810
type DraftConfig struct {
9-
DisplayName string `yaml:"displayName"`
10-
NameOverrides []FileNameOverride `yaml:"nameOverrides"`
11-
Variables []BuilderVar `yaml:"variables"`
12-
VariableDefaults []BuilderVarDefault `yaml:"variableDefaults"`
11+
DisplayName string `yaml:"displayName"`
12+
NameOverrides []FileNameOverride `yaml:"nameOverrides"`
13+
Variables []BuilderVar `yaml:"variables"`
1314

1415
nameOverrideMap map[string]string
1516
}
@@ -20,17 +21,17 @@ type FileNameOverride struct {
2021
}
2122

2223
type BuilderVar struct {
23-
Name string `yaml:"name"`
24-
Description string `yaml:"description"`
25-
VarType string `yaml:"type"`
26-
ExampleValues []string `yaml:"exampleValues"`
24+
Name string `yaml:"name"`
25+
Default BuilderVarDefault `yaml:"default"`
26+
Description string `yaml:"description"`
27+
ExampleValues []string `yaml:"exampleValues"`
28+
Type string `yaml:"type"`
2729
}
2830

2931
type BuilderVarDefault struct {
30-
Name string `yaml:"name"`
31-
Value string `yaml:"value"`
32-
ReferenceVar string `yaml:"referenceVar"`
3332
IsPromptDisabled bool `yaml:"disablePrompt"`
33+
ReferenceVar string `yaml:"referenceVar"`
34+
Value string `yaml:"value"`
3435
}
3536

3637
func (d *DraftConfig) GetVariableExampleValues() map[string][]string {
@@ -40,6 +41,7 @@ func (d *DraftConfig) GetVariableExampleValues() map[string][]string {
4041
variableExampleValues[variable.Name] = variable.ExampleValues
4142
}
4243
}
44+
4345
return variableExampleValues
4446
}
4547

@@ -65,14 +67,29 @@ func (d *DraftConfig) GetNameOverride(path string) string {
6567
}
6668

6769
// ApplyDefaultVariables will apply the defaults to variables that are not already set
68-
func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) {
69-
for _, variable := range d.VariableDefaults {
70+
func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) error {
71+
for _, variable := range d.Variables {
7072
// handle where variable is not set or is set to an empty string from cli handling
71-
if defaultVal, ok := customConfig[variable.Name]; !ok || defaultVal == "" {
72-
log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Value)
73-
customConfig[variable.Name] = variable.Value
73+
if val, ok := customConfig[variable.Name]; !ok || val == "" {
74+
if variable.Default.Value == "" {
75+
return errors.New("variable " + variable.Name + " has no default value")
76+
}
77+
log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Default.Value)
78+
customConfig[variable.Name] = variable.Default.Value
7479
}
7580
}
81+
82+
return nil
83+
}
84+
85+
func VariableIdxMap(variables []BuilderVar) map[string]int {
86+
varIdxMap := make(map[string]int)
87+
88+
for i, variable := range variables {
89+
varIdxMap[variable.Name] = i
90+
}
91+
92+
return varIdxMap
7693
}
7794

7895
// TemplateVariableRecorder is an interface for recording variables that are used read using draft configs

pkg/prompts/prompts.go

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -39,56 +39,49 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st
3939

4040
inputs := make(map[string]string)
4141

42-
for _, customPrompt := range config.Variables {
43-
promptVariableName := customPrompt.Name
44-
if _, ok := skipMap[promptVariableName]; ok {
45-
log.Debugf("Skipping prompt for %s", promptVariableName)
42+
for _, variable := range config.Variables {
43+
if val, ok := skipMap[variable.Name]; ok && val != "" {
44+
log.Debugf("Skipping prompt for %s", variable.Name)
4645
continue
4746
}
48-
if GetIsPromptDisabled(customPrompt.Name, config.VariableDefaults) {
49-
log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", promptVariableName)
50-
noPromptDefaultValue := GetVariableDefaultValue(promptVariableName, config.VariableDefaults, inputs)
47+
48+
if variable.Default.IsPromptDisabled {
49+
log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", variable.Name)
50+
noPromptDefaultValue := GetVariableDefaultValue(variable, inputs)
5151
if noPromptDefaultValue == "" {
52-
return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", promptVariableName)
52+
return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", variable.Name)
5353
}
54-
log.Debugf("Using default value %s for %s", noPromptDefaultValue, promptVariableName)
55-
inputs[promptVariableName] = noPromptDefaultValue
54+
log.Debugf("Using default value %s for %s", noPromptDefaultValue, variable.Name)
55+
inputs[variable.Name] = noPromptDefaultValue
5656
continue
5757
}
5858

59-
log.Debugf("constructing prompt for: %s", promptVariableName)
60-
if customPrompt.VarType == "bool" {
61-
input, err := RunBoolPrompt(customPrompt, Stdin, Stdout)
59+
log.Debugf("constructing prompt for: %s", variable.Name)
60+
if variable.Type == "bool" {
61+
input, err := RunBoolPrompt(variable, Stdin, Stdout)
6262
if err != nil {
6363
return nil, err
6464
}
65-
inputs[promptVariableName] = input
65+
inputs[variable.Name] = input
6666
} else {
67-
defaultValue := GetVariableDefaultValue(promptVariableName, config.VariableDefaults, inputs)
67+
defaultValue := GetVariableDefaultValue(variable, inputs)
6868

69-
stringInput, err := RunDefaultableStringPrompt(customPrompt, defaultValue, nil, Stdin, Stdout)
69+
stringInput, err := RunDefaultableStringPrompt(defaultValue, variable, nil, Stdin, Stdout)
7070
if err != nil {
7171
return nil, err
7272
}
73-
inputs[promptVariableName] = stringInput
74-
}
75-
}
76-
77-
// Substitute the default value for variables where the user didn't enter anything
78-
for _, variableDefault := range config.VariableDefaults {
79-
if inputs[variableDefault.Name] == "" {
80-
inputs[variableDefault.Name] = variableDefault.Value
73+
inputs[variable.Name] = stringInput
8174
}
8275
}
8376

8477
return inputs, nil
8578
}
8679

87-
// GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal VariableDefault.Value in that order.
88-
func GetVariableDefaultValue(variableName string, variableDefaults []config.BuilderVarDefault, inputs map[string]string) string {
80+
// GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal Variable.DefaultValue in that order.
81+
func GetVariableDefaultValue(variable config.BuilderVar, inputs map[string]string) string {
8982
defaultValue := ""
9083

91-
if variableName == "APPNAME" {
84+
if variable.Name == "APPNAME" {
9285
dirName, err := getCurrentDirNameFunc()
9386
if err != nil {
9487
log.Errorf("Error retrieving current directory name: %s", err)
@@ -98,26 +91,14 @@ func GetVariableDefaultValue(variableName string, variableDefaults []config.Buil
9891
return defaultValue
9992
}
10093

101-
for _, variableDefault := range variableDefaults {
102-
if variableDefault.Name == variableName {
103-
defaultValue = variableDefault.Value
104-
log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue)
105-
if variableDefault.ReferenceVar != "" && inputs[variableDefault.ReferenceVar] != "" {
106-
defaultValue = inputs[variableDefault.ReferenceVar]
107-
log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variableDefault.ReferenceVar)
108-
}
109-
}
94+
defaultValue = variable.Default.Value
95+
log.Debugf("setting default value for %s to %s from variable default rule", variable.Name, defaultValue)
96+
if variable.Default.ReferenceVar != "" && inputs[variable.Default.ReferenceVar] != "" {
97+
defaultValue = inputs[variable.Default.ReferenceVar]
98+
log.Debugf("setting default value for %s to %s from referenceVar %s", variable.Name, defaultValue, variable.Default.ReferenceVar)
11099
}
111-
return defaultValue
112-
}
113100

114-
func GetIsPromptDisabled(variableName string, variableDefaults []config.BuilderVarDefault) bool {
115-
for _, variableDefault := range variableDefaults {
116-
if variableDefault.Name == variableName {
117-
return variableDefault.IsPromptDisabled
118-
}
119-
}
120-
return false
101+
return defaultValue
121102
}
122103

123104
func RunBoolPrompt(customPrompt config.BuilderVar, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) {
@@ -176,7 +157,7 @@ func appNameValidator(name string) error {
176157
}
177158

178159
// RunDefaultableStringPrompt runs a prompt for a string variable, returning the user string input for the prompt
179-
func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue string, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) {
160+
func RunDefaultableStringPrompt(defaultValue string, customPrompt config.BuilderVar, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) {
180161
if validate == nil {
181162
validate = NoBlankStringValidator
182163
}

0 commit comments

Comments
 (0)