diff --git a/internal/apply/apply.go b/internal/apply/apply.go index 33cc2c778..382b14b46 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -101,9 +101,9 @@ func applyAll(dir string, projectConfig projectconfig.ZeroProjectConfig, applyEn // promptEnvironments Prompts the user for the environments to apply against and returns a slice of strings representing the environments func promptEnvironments() []string { items := map[string][]string{ - "Staging ": {"staging"}, - "Production": {"production"}, - "Both Staging and Production": {"staging", "production"}, + "Staging ": {"stage"}, + "Production": {"prod"}, + "Both Staging and Production": {"stage", "prod"}, } var labels []string diff --git a/internal/config/moduleconfig/module_config.go b/internal/config/moduleconfig/module_config.go index 2368c75d8..132ac3466 100644 --- a/internal/config/moduleconfig/module_config.go +++ b/internal/config/moduleconfig/module_config.go @@ -17,13 +17,20 @@ type ModuleConfig struct { } type Parameter struct { - Field string - Label string `yaml:"label,omitempty"` - Options []string `yaml:"options,omitempty"` - Execute string `yaml:"execute,omitempty"` - Value string `yaml:"value,omitempty"` - Default string `yaml:"default,omitempty"` - Info string `yaml:"info,omitempty"` + Field string + Label string `yaml:"label,omitempty"` + Options []string `yaml:"options,omitempty"` + Execute string `yaml:"execute,omitempty"` + Value string `yaml:"value,omitempty"` + Default string `yaml:"default,omitempty"` + Info string `yaml:"info,omitempty"` + FieldValidation Validate `yaml:"fieldValidation,omitempty"` +} + +type Validate struct { + Type string `yaml:"type,omitempty"` + Value string `yaml:"value,omitempty"` + ErrorMessage string `yaml:"errorMessage,omitempty"` } type TemplateConfig struct { diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 907ad9f60..988474359 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -8,4 +8,10 @@ const ( ZeroHomeDirectory = ".zero" IgnoredPaths = "(?i)zero.module.yml|.git/" TemplateExtn = ".tmpl" + + // prompt constants + + MaxPnameLength = 16 + RegexValidation = "regex" + FunctionValidation = "function" ) diff --git a/internal/init/init.go b/internal/init/init.go index d5884b1bb..c69552948 100644 --- a/internal/init/init.go +++ b/internal/init/init.go @@ -125,7 +125,7 @@ func getProjectNamePrompt() PromptHandler { Default: "", }, Condition: NoCondition, - Validate: NoValidation, + Validate: ValidateProjectName, } } diff --git a/internal/init/prompts.go b/internal/init/prompts.go index a5fb56103..018375c87 100644 --- a/internal/init/prompts.go +++ b/internal/init/prompts.go @@ -11,6 +11,7 @@ import ( "github.com/commitdev/zero/internal/config/globalconfig" "github.com/commitdev/zero/internal/config/moduleconfig" + "github.com/commitdev/zero/internal/constants" "github.com/commitdev/zero/internal/util" "github.com/commitdev/zero/pkg/credentials" "github.com/commitdev/zero/pkg/util/exit" @@ -88,7 +89,20 @@ func ValidateSAK(input string) error { return nil } -// TODO: validation / allow prompt retry ...etc +// ValidateProjectName validates Project Name field user input. +func ValidateProjectName(input string) error { + // the first 62 char out of base64 and - + var pName = regexp.MustCompile(`^[A-Za-z0-9-]{1,16}$`) + if !pName.MatchString(input) { + // error if char len is greater than 16 + if len(input) > constants.MaxPnameLength { + return errors.New("Invalid, Project Name: (cannot exceed a max length of 16)") + } + return errors.New("Invalid, Project Name: (can only contain alphanumeric chars & '-')") + } + return nil +} + func (p PromptHandler) GetParam(projectParams map[string]string) string { var err error var result string @@ -170,7 +184,6 @@ func sanitizeParameterValue(str string) string { // PromptParams renders series of prompt UI based on the config func PromptModuleParams(moduleConfig moduleconfig.ModuleConfig, parameters map[string]string, projectCredentials globalconfig.ProjectCredential) (map[string]string, error) { - credentialEnvs := projectCredentials.SelectedVendorsCredentialsAsEnv(moduleConfig.RequiredCredentials) for _, promptConfig := range moduleConfig.Parameters { // deduplicate fields already prompted and received @@ -178,10 +191,24 @@ func PromptModuleParams(moduleConfig moduleconfig.ModuleConfig, parameters map[s continue } + var validateFunc func(input string) error = nil + + // type:regex field validation for zero-module.yaml + if promptConfig.FieldValidation.Type == constants.RegexValidation { + validateFunc = func(input string) error { + var regexRule = regexp.MustCompile(promptConfig.FieldValidation.Value) + if !regexRule.MatchString(input) { + return errors.New(promptConfig.FieldValidation.ErrorMessage) + } + return nil + } + } + // TODO: type:fuction field validation for zero-module.yaml + promptHandler := PromptHandler{ Parameter: promptConfig, Condition: NoCondition, - Validate: NoValidation, + Validate: validateFunc, } // merging the context of param and credentals // this treats credentialEnvs as throwaway, parameters is shared between modules