AskVariables returns the map of ALL variables to send to the server, whether they were prompted for, or came from the command line. variablesFromCmd is copied into the result, you don't need to merge them yourselves. Return values: 0: Variables to send to the server, 1: List of sensitive variable na
(asker question.Asker, variableSet *variables.VariableSet, variablesFromCmd map[string]string)
| 150 | // variablesFromCmd is copied into the result, you don't need to merge them yourselves. |
| 151 | // Return values: 0: Variables to send to the server, 1: List of sensitive variable names for masking automation command, 2: error |
| 152 | func AskVariables(asker question.Asker, variableSet *variables.VariableSet, variablesFromCmd map[string]string) (map[string]string, error) { |
| 153 | if asker == nil { |
| 154 | return nil, cliErrors.NewArgumentNullOrEmptyError("asker") |
| 155 | } |
| 156 | if variableSet == nil { |
| 157 | return nil, cliErrors.NewArgumentNullOrEmptyError("variableSet") |
| 158 | } |
| 159 | |
| 160 | // variablesFromCmd is pure user input and may not have correct casing. |
| 161 | lcaseVarsFromCmd := make(map[string]string, len(variablesFromCmd)) |
| 162 | for k, v := range variablesFromCmd { |
| 163 | lcaseVarsFromCmd[strings.ToLower(k)] = v |
| 164 | } |
| 165 | |
| 166 | result := make(map[string]string) |
| 167 | if len(variableSet.Variables) > 0 { // nothing to be done here, move along |
| 168 | for _, v := range variableSet.Variables { |
| 169 | valueFromCmd, foundValueOnCommandLine := lcaseVarsFromCmd[strings.ToLower(v.Name)] |
| 170 | if foundValueOnCommandLine { |
| 171 | // implicitly fixes up variable casing |
| 172 | result[v.Name] = valueFromCmd |
| 173 | } |
| 174 | |
| 175 | if v.Prompt != nil && !foundValueOnCommandLine { // this is a prompted variable, ask for input (unless we already have it) |
| 176 | // NOTE: there is a v.Prompt.Label which is shown in the web portal, |
| 177 | // but we explicitly don't use it here because it can lead to confusion. |
| 178 | // e.g. |
| 179 | // A variable "CrmTicketNumber" exists with Label "CRM Ticket Number" |
| 180 | // If we were to use the label then the prompt would ask for "CRM Ticket Number" but the command line |
| 181 | // invocation would say "CrmTicketNumber:<value>" and it wouldn't be clear to and end user whether |
| 182 | // "CrmTicketNumber" or "CRM Ticket Number" was the right thing. |
| 183 | promptMessage := v.Name |
| 184 | |
| 185 | if v.Prompt.Description != "" { |
| 186 | promptMessage = fmt.Sprintf("%s (%s)", promptMessage, v.Prompt.Description) // we'd like to dim the description, but survey overrides this, so we can't |
| 187 | } |
| 188 | |
| 189 | if v.Type == "String" || v.Type == "Sensitive" { |
| 190 | responseString, err := AskVariableSpecificPrompt(asker, promptMessage, v.Type, v.Value, v.Prompt.IsRequired, v.IsSensitive, v.Prompt.DisplaySettings) |
| 191 | if err != nil { |
| 192 | return nil, err |
| 193 | } |
| 194 | result[v.Name] = responseString |
| 195 | } |
| 196 | // else it's a complex variable type with the prompt flag, which (at time of writing) is currently broken |
| 197 | // and a decision on how to fix it had not yet been made. Ignore it. |
| 198 | // BUG: https://github.com/OctopusDeploy/Issues/issues/7699 |
| 199 | } |
| 200 | } |
| 201 | } |
| 202 | return result, nil |
| 203 | } |
| 204 | |
| 205 | func AskVariableSpecificPrompt(asker question.Asker, message string, variableType string, defaultValue string, isRequired bool, isSensitive bool, displaySettings *resources.DisplaySettings) (string, error) { |
| 206 | var askOpt survey.AskOpt = func(options *survey.AskOptions) error { |