• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

foomo / posh / 14267892308

04 Apr 2025 02:41PM UTC coverage: 6.101% (-0.07%) from 6.172%
14267892308

push

github

web-flow
Merge pull request #110 from foomo/feature/v0.11.0

feat: v0.11.0

3 of 122 new or added lines in 9 files covered. (2.46%)

5 existing lines in 2 files now uncovered.

159 of 2606 relevant lines covered (6.1%)

0.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

31.45
/pkg/command/tree/node.go
1
package tree
2

3
import (
4
        "context"
5
        "strings"
6

7
        "github.com/foomo/posh/pkg/prompt/goprompt"
8
        "github.com/foomo/posh/pkg/readline"
9
        xstrings "github.com/foomo/posh/pkg/util/strings"
10
        "github.com/foomo/posh/pkg/util/suggests"
11

12
        "github.com/pkg/errors"
13
)
14

15
type Node struct {
16
        Name        string
17
        Values      func(ctx context.Context, r *readline.Readline) []goprompt.Suggest
18
        Args        Args
19
        Flags       func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error
20
        Description string
21
        Nodes       []*Node
22
        Execute     func(ctx context.Context, r *readline.Readline) error
23
}
24

25
// ------------------------------------------------------------------------------------------------
26
// ~ Private methods
27
// ------------------------------------------------------------------------------------------------
28

29
func (c *Node) setFlags(ctx context.Context, r *readline.Readline, parse bool) error {
21✔
30
        fs := readline.NewFlagSets()
21✔
31
        if c.Flags != nil {
23✔
32
                if err := c.Flags(ctx, r, fs); err != nil {
2✔
33
                        return err
×
34
                }
×
35
        }
36
        r.SetFlagSets(fs)
21✔
37
        if parse {
42✔
38
                if err := r.ParseFlagSets(); err != nil {
21✔
39
                        return errors.Wrap(err, "failed to parse flags")
×
40
                }
×
41
        }
42
        return nil
21✔
43
}
44

45
func (c *Node) completeArguments(ctx context.Context, p *root, r *readline.Readline, i int) []goprompt.Suggest {
×
46
        var suggest []goprompt.Suggest
×
NEW
47
        localArgs := r.Args().From(i)
×
NEW
48

×
49
        switch {
×
NEW
50
        case len(c.Nodes) > 0:
×
51
                for _, command := range c.Nodes {
×
52
                        if command.Values != nil {
×
53
                                suggest = command.Values(ctx, r)
×
54
                        } else {
×
55
                                suggest = append(suggest, goprompt.Suggest{Text: command.Name, Description: command.Description})
×
56
                        }
×
57
                }
NEW
58
        case len(c.Args) > 0 && len(localArgs) == 0:
×
NEW
59
                if fn := c.Args[0].Suggest; fn != nil {
×
NEW
60
                        suggest = fn(ctx, p, r)
×
61
                }
×
NEW
62
        case len(c.Args) > 0 && len(c.Args) >= len(localArgs):
×
NEW
63
                if fn := c.Args[len(localArgs)-1].Suggest; fn != nil {
×
64
                        suggest = fn(ctx, p, r)
×
65
                }
×
66
        case len(c.Args) > 0 && c.Args.Last().Repeat && c.Args.Last().Suggest != nil:
×
67
                suggest = c.Args.Last().Suggest(ctx, p, r)
×
68
        }
69
        return suggest
×
70
}
71

72
func (c *Node) completeFlags(r *readline.Readline) []goprompt.Suggest {
×
73
        allFlags := r.AllFlags()
×
74
        if r.Flags().LenGt(1) {
×
75
                if fs := r.FlagSets(); fs != nil {
×
76
                        if values := fs.All().GetValues(strings.TrimPrefix(r.Flags().At(r.Flags().Len()-2), "--")); values != nil {
×
77
                                return suggests.List(values)
×
78
                        }
×
79
                }
80
        }
81
        suggest := make([]goprompt.Suggest, len(allFlags))
×
82
        for i, f := range allFlags {
×
83
                suggest[i] = goprompt.Suggest{Text: "--" + f.Name, Description: f.Usage}
×
84
        }
×
85
        return suggest
×
86
}
87

88
func (c *Node) execute(ctx context.Context, r *readline.Readline, i int) error {
21✔
89
        localArgs := r.Args().From(i)
21✔
90

21✔
91
        // validate
21✔
92
        switch {
21✔
93
        case c.Execute == nil && len(c.Nodes) == 0:
1✔
94
                return ErrNoop
1✔
95
        case c.Execute == nil && len(c.Nodes) > 0 && len(localArgs) == 0:
×
96
                return ErrMissingCommand
×
97
        case c.Execute != nil && len(c.Nodes) == 0 && len(c.Args) == 0:
9✔
98
        case c.Execute != nil && len(c.Nodes) == 0 && c.Args.Validate(localArgs) == nil:
2✔
99
        case c.Execute != nil && len(c.Nodes) == 0 && c.Args.Validate(localArgs) != nil:
3✔
100
                return c.Args.Validate(localArgs)
3✔
101
        case c.Execute == nil:
×
102
                return ErrInvalidCommand
×
103
        }
104

105
        // execute
106
        return c.Execute(ctx, r)
17✔
107
}
108

109
func (c *Node) find(ctx context.Context, r *readline.Readline, i int) (*Node, int) {
26✔
110
        if r.Args().LenLt(i + 1) {
33✔
111
                return nil, i
7✔
112
        }
7✔
113
        arg := r.Args().At(i)
19✔
114
        for _, cmd := range c.Nodes {
47✔
115
                if cmd.Name == arg {
37✔
116
                        if subCmd, j := cmd.find(ctx, r, i+1); subCmd != nil {
11✔
117
                                return subCmd, j
2✔
118
                        }
2✔
119
                        return cmd, i + 1
7✔
120
                }
121
                if cmd.Values != nil {
23✔
122
                        for _, name := range cmd.Values(ctx, r) {
10✔
123
                                if name.Text == arg {
9✔
124
                                        if subCmd, j := cmd.find(ctx, r, i+1); subCmd != nil {
4✔
125
                                                return subCmd, j
1✔
126
                                        }
1✔
127
                                        return cmd, i + 1
2✔
128
                                }
129
                        }
130
                }
131
        }
132
        return nil, i
7✔
133
}
134

135
func (c *Node) help(ctx context.Context, r *readline.Readline) string {
×
136
        pad := "      "
×
137
        ret := c.Description
×
138

×
139
        if len(c.Nodes) > 0 {
×
140
                ret += "\n\nUsage:\n"
×
141
                ret += pad + c.Name + " [command]"
×
142

×
143
                ret += "\n\nAvailable Commands:\n"
×
144
                for _, node := range c.Nodes {
×
145
                        ret += pad + xstrings.PadEnd(node.Name, " ", 30) + node.Description + "\n"
×
146
                }
×
147
        } else {
×
148
                ret += "\n\nUsage:\n"
×
149
                ret += pad + c.Name
×
150

×
151
                for _, arg := range c.Args {
×
152
                        ret += " "
×
153
                        if arg.Optional {
×
154
                                ret += "<"
×
155
                        } else {
×
156
                                ret += "["
×
157
                        }
×
158
                        ret += arg.Name
×
159
                        if arg.Optional {
×
160
                                ret += ">"
×
161
                        } else {
×
162
                                ret += "]"
×
163
                        }
×
164
                        ret += "\n"
×
165
                }
166

167
                if len(c.Args) > 0 {
×
168
                        ret += "\n\nArguments:\n"
×
169
                        for _, arg := range c.Args {
×
170
                                ret += pad + xstrings.PadEnd(arg.Name, " ", 30) + arg.Description + "\n"
×
171
                        }
×
172
                }
173

174
                if c.Flags != nil {
×
175
                        fs := readline.NewFlagSets()
×
176
                        if err := c.Flags(ctx, r, fs); err == nil {
×
177
                                ret += "\n\nFlags:\n"
×
178
                                ret += fs.All().FlagUsages()
×
179
                        }
×
180
                }
181
        }
182
        return ret
×
183
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc