1 package asker
2
3 import (
4 "fmt"
5 "sort"
6 "strings"
7
8 "github.com/AlecAivazis/survey/v2"
9
10 "github.com/redhat-developer/odo/pkg/api"
11 "github.com/redhat-developer/odo/pkg/log"
12 "github.com/redhat-developer/odo/pkg/registry"
13 )
14
15 const (
16 GOBACK = "** GO BACK **"
17 )
18
19 type Survey struct{}
20
21 var _ Asker = (*Survey)(nil)
22
23 func NewSurveyAsker() *Survey {
24 return &Survey{}
25 }
26
27 func (o *Survey) AskArchitectures(archs []string, selectedDefault []string) ([]string, error) {
28 question := &survey.MultiSelect{
29 Message: "Select architectures to filter by:",
30 Options: archs,
31 Default: selectedDefault,
32 }
33 var answer []string
34 err := survey.AskOne(question, &answer)
35 if err != nil {
36 return nil, err
37 }
38 return answer, nil
39 }
40
41 func (o *Survey) AskLanguage(langs []string) (bool, string, error) {
42 sort.Strings(langs)
43 langs = append(langs, GOBACK)
44 question := &survey.Select{
45 Message: "Select language:",
46 Options: langs,
47 }
48 var answerPos int
49 err := survey.AskOne(question, &answerPos)
50 if err != nil {
51 return false, "", err
52 }
53 if answerPos == len(langs)-1 {
54 return true, "", nil
55 }
56 return false, langs[answerPos], nil
57 }
58
59 func (o *Survey) AskType(types registry.TypesWithDetails) (back bool, _ api.DevfileStack, _ error) {
60 stringTypes := types.GetOrderedLabels()
61 stringTypes = append(stringTypes, GOBACK)
62 question := &survey.Select{
63 Message: "Select project type:",
64 Options: stringTypes,
65 }
66 var answerPos int
67 err := survey.AskOne(question, &answerPos)
68 if err != nil {
69 return false, api.DevfileStack{}, err
70 }
71 if answerPos == len(stringTypes)-1 {
72 return true, api.DevfileStack{}, nil
73 }
74 compType, err := types.GetAtOrderedPosition(answerPos)
75 return false, compType, err
76 }
77
78 func (o *Survey) AskVersion(versions []api.DevfileStackVersion) (back bool, version string, _ error) {
79 var stringVersions []string
80 for _, version := range versions {
81 sVersion := version.Version
82 if version.IsDefault {
83 sVersion += " (default)"
84 }
85 stringVersions = append(stringVersions, sVersion)
86 }
87 stringVersions = append(stringVersions, GOBACK)
88 question := &survey.Select{
89 Message: "Select version: ",
90 Options: stringVersions,
91 }
92 var answerPos int
93 err := survey.AskOne(question, &answerPos)
94 if err != nil {
95 return false, "", err
96 }
97 if answerPos == len(stringVersions)-1 {
98 return true, "", nil
99 }
100 return false, strings.ReplaceAll(stringVersions[answerPos], " (default)", ""), err
101 }
102
103 func (o *Survey) AskStarterProject(projects []string) (bool, int, error) {
104 projects = append(projects, "** NO STARTER PROJECT **")
105 question := &survey.Select{
106 Message: "Which starter project do you want to use?",
107 Options: projects,
108 }
109 var answer int
110 err := survey.AskOne(question, &answer)
111 if err != nil {
112 return false, 0, err
113 }
114 if answer == len(projects)-1 {
115 return false, 0, nil
116 }
117 return true, answer, nil
118 }
119
120 func (o *Survey) AskName(defaultName string) (string, error) {
121 question := &survey.Input{
122 Message: "Enter component name:",
123 Default: defaultName,
124 }
125 var answer string
126 err := survey.AskOne(question, &answer)
127 if err != nil {
128 return "", err
129 }
130 return answer, nil
131 }
132
133 func (o *Survey) AskCorrect() (bool, error) {
134 question := &survey.Confirm{
135 Message: "Is this correct?",
136 Default: true,
137 }
138 var answer bool
139 err := survey.AskOne(question, &answer)
140 if err != nil {
141 return false, err
142 }
143 return answer, nil
144 }
145
146
147 func (o *Survey) AskPersonalizeConfiguration(configuration ContainerConfiguration) (OperationOnContainer, error) {
148 options, tracker := buildPersonalizedConfigurationOptions(configuration)
149 configChangeQuestion := &survey.Select{
150 Message: "What configuration do you want change?",
151 Default: options[0],
152 Options: options,
153 }
154 var configChangeIndex int
155 err := survey.AskOne(configChangeQuestion, &configChangeIndex)
156 if err != nil {
157 return OperationOnContainer{}, err
158 }
159 return tracker[configChangeIndex], nil
160 }
161
162
163 func (o *Survey) AskAddEnvVar() (string, string, error) {
164 newEnvNameQuesion := &survey.Input{
165 Message: "Enter new environment variable name:",
166 }
167 var newEnvNameAnswer string
168 err := survey.AskOne(newEnvNameQuesion, &newEnvNameAnswer)
169 if err != nil {
170 return "", "", err
171 }
172 newEnvValueQuestion := &survey.Input{
173 Message: fmt.Sprintf("Enter value for %q environment variable:", newEnvNameAnswer),
174 }
175 var newEnvValueAnswer string
176 err = survey.AskOne(newEnvValueQuestion, &newEnvValueAnswer)
177 if err != nil {
178 return "", "", err
179 }
180 return newEnvNameAnswer, newEnvValueAnswer, nil
181 }
182
183
184 func (o *Survey) AskAddPort() (string, error) {
185 newPortQuestion := &survey.Input{
186 Message: "Enter port number:",
187 }
188 var newPortAnswer string
189 log.Warning("Please ensure that you do not add a duplicate port number")
190 err := survey.AskOne(newPortQuestion, &newPortAnswer)
191 if err != nil {
192 return "", err
193 }
194 return newPortAnswer, nil
195 }
196
197 func (o *Survey) AskContainerName(containers []string) (string, error) {
198 selectContainerQuestion := &survey.Select{
199 Message: "Select container for which you want to change configuration?",
200 Default: containers[len(containers)-1],
201 Options: containers,
202 }
203 var selectContainerAnswer string
204 err := survey.AskOne(selectContainerQuestion, &selectContainerAnswer)
205 if err != nil {
206 return selectContainerAnswer, err
207 }
208 return selectContainerAnswer, nil
209 }
210
211 func (dc *DevfileConfiguration) GetContainers() []string {
212 keys := []string{}
213 for k := range *dc {
214 keys = append(keys, k)
215 }
216 return keys
217 }
218
219 func buildPersonalizedConfigurationOptions(configuration ContainerConfiguration) (options []string, tracker []OperationOnContainer) {
220 options = []string{
221 "NOTHING - configuration is correct",
222 }
223
224 tracker = []OperationOnContainer{{Ops: "Nothing"}}
225
226
227 for _, port := range configuration.Ports {
228 options = append(options, fmt.Sprintf("Delete port %q", port))
229 tracker = append(tracker, OperationOnContainer{
230 Ops: "Delete",
231 Kind: "Port",
232 Key: port,
233 })
234 }
235 options = append(options, "Add new port")
236 tracker = append(tracker, OperationOnContainer{
237 Ops: "Add",
238 Kind: "Port",
239 })
240
241
242 for key := range configuration.Envs {
243 options = append(options, fmt.Sprintf("Delete environment variable %q", key))
244 tracker = append(tracker, OperationOnContainer{
245 Ops: "Delete",
246 Kind: "EnvVar",
247 Key: key,
248 })
249 }
250 options = append(options, "Add new environment variable")
251 tracker = append(tracker, OperationOnContainer{
252 Ops: "Add",
253 Kind: "EnvVar",
254 })
255
256 return
257 }
258
View as plain text