-
Notifications
You must be signed in to change notification settings - Fork 18
/
prepare.go
93 lines (82 loc) · 2.22 KB
/
prepare.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
93
// SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Open Component Model contributors.
//
// SPDX-License-Identifier: Apache-2.0
package app
import (
"strings"
"github.com/spf13/pflag"
"github.com/open-component-model/ocm/v2/pkg/contexts/clictx"
)
// Prepare pre-prepares CLI options by evaluation the main options
// and providing an appropriately configured cli context.
func Prepare(ctx clictx.Context, args []string) (*CLIOptions, []string, error) {
if ctx == nil {
ctx = clictx.DefaultContext()
}
opts := &CLIOptions{
Context: ctx,
}
flagset := pflag.NewFlagSet("dummy", pflag.ContinueOnError)
opts.AddFlags(flagset)
flags := []string{}
inFlag := false
help := false
for i, arg := range args {
switch {
case arg == "--help" || arg == "-h":
help = true
continue
// A long flag with a space separated value
case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
inFlag = !hasNoOptDefVal(arg[2:], flagset)
flags = append(flags, arg)
continue
// A short flag with a space separated value
case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], flagset):
inFlag = true
flags = append(flags, arg)
continue
// The value for a flag
case inFlag:
inFlag = false
flags = append(flags, arg)
continue
// A flag without a value, or with an `=` separated value
case isFlagArg(arg):
flags = append(flags, arg)
continue
}
args = args[i:]
break
}
err := flagset.Parse(flags)
if err != nil {
return nil, nil, err
}
if help {
args = append([]string{"--help"}, args...)
}
return opts, args, opts.Complete()
}
func hasNoOptDefVal(name string, fs *pflag.FlagSet) bool {
flag := fs.Lookup(name)
if flag == nil {
return false
}
return flag.NoOptDefVal != ""
}
func shortHasNoOptDefVal(name string, fs *pflag.FlagSet) bool {
if len(name) == 0 {
return false
}
flag := fs.ShorthandLookup(name[:1])
if flag == nil {
return false
}
return flag.NoOptDefVal != ""
}
func isFlagArg(arg string) bool {
return ((len(arg) >= 3 && arg[1] == '-') ||
(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
}