-
Notifications
You must be signed in to change notification settings - Fork 35
/
stack_selector.go
92 lines (75 loc) · 2.08 KB
/
stack_selector.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package stack
import (
"context"
"fmt"
"strings"
"github.com/manifoldco/promptui"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)
var errNoStackFound = errors.New("no stack found")
// getStackID will try to retreive a stack ID from multiple sources.
// It will do so in the following order:
// 1. Check the --id flag, if set, use that value.
// 2. Check the current directory to determine repository and subdirectory and search for a stack.
func getStackID(cliCtx *cli.Context) (string, error) {
if cliCtx.IsSet(flagStackID.Name) {
return cliCtx.String(flagStackID.Name), nil
}
subdir, err := getGitRepositorySubdir()
if err != nil {
return "", err
}
name, err := getRepositoryName()
if err != nil {
return "", err
}
got, err := findAndSelectStack(cliCtx.Context, &stackSearchParams{
count: 50,
projectRoot: &subdir,
repositoryName: name,
}, true)
if err != nil {
if errors.Is(err, errNoStackFound) {
return "", errors.New("no --id flag was provided and stack could not be found by searching the current directory")
}
return "", err
}
return got, nil
}
func findAndSelectStack(ctx context.Context, p *stackSearchParams, forcePrompt bool) (string, error) {
stacks, err := searchStacks(ctx, p)
if err != nil {
return "", err
}
items := []string{}
found := map[string]string{}
for _, stack := range stacks {
items = append(items, stack.Name)
found[stack.Name] = stack.ID
}
if len(found) == 0 {
return "", errNoStackFound
}
selected := items[0]
if len(items) > 1 || forcePrompt {
if len(items) == p.count {
fmt.Printf("Search results exceeded maximum capacity (%d) some stacks might be missing\n", p.count)
}
prompt := promptui.Select{
Label: fmt.Sprintf("Found %d stacks, select one", len(items)),
Items: items,
Size: 10,
StartInSearchMode: len(items) > 5,
Searcher: func(input string, index int) bool {
return strings.Contains(items[index], input)
},
}
_, result, err := prompt.Run()
if err != nil {
return "", err
}
selected = result
}
return selected, nil
}