forked from redhat-developer/odo
/
odo.go
117 lines (102 loc) · 3.09 KB
/
odo.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package main
import (
"flag"
"os"
"github.com/openshift/odo/pkg/log"
"github.com/openshift/odo/pkg/odo/cli"
"github.com/openshift/odo/pkg/odo/cli/version"
"github.com/openshift/odo/pkg/odo/util"
"github.com/openshift/odo/pkg/odo/util/completion"
"github.com/openshift/odo/pkg/preference"
"github.com/posener/complete"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"k8s.io/klog"
)
func main() {
// create the complete command
klog.InitFlags(nil)
root := cli.NewCmdOdo(cli.OdoRecommendedName, cli.OdoRecommendedName)
rootCmp := createCompletion(root)
cmp := complete.New("odo", rootCmp)
// AddFlags adds the completion flags to the program flags, specifying custom names
cmp.CLI.InstallName = "complete"
cmp.CLI.UninstallName = "uncomplete"
cmp.AddFlags(nil)
// add the completion flags to the root command, though they won't appear in completions
root.Flags().AddGoFlagSet(flag.CommandLine)
// override usage so that flag.Parse uses root command's usage instead of default one when invoked with -h
flag.Usage = func() {
_ = root.Help()
}
// parse the flags but hack around to avoid exiting with error code 2 on help
flag.CommandLine.Init(os.Args[0], flag.ContinueOnError)
args := os.Args[1:]
if err := flag.CommandLine.Parse(args); err != nil {
if err == flag.ErrHelp {
os.Exit(0)
}
}
// run the completion, in case that the completion was invoked
// and ran as a completion script or handled a flag that passed
// as argument, the Run method will return true,
// in that case, our program have nothing to do and should return.
if cmp.Complete() {
return
}
// Call commands
// checking the value of updatenotification in config
// before proceeding with fetching the latest version
cfg, err := preference.New()
if err != nil {
util.LogErrorAndExit(err, "")
}
if cfg.GetUpdateNotification() {
updateInfo := make(chan string)
go version.GetLatestReleaseInfo(updateInfo)
util.LogErrorAndExit(root.Execute(), "")
select {
case message := <-updateInfo:
log.Italic(message)
default:
klog.V(4).Info("Could not get the latest release information in time. Never mind, exiting gracefully :)")
}
} else {
util.LogErrorAndExit(root.Execute(), "")
}
}
func createCompletion(root *cobra.Command) complete.Command {
rootCmp := complete.Command{}
rootCmp.Flags = make(complete.Flags)
addFlags := func(flag *pflag.Flag) {
if flag.Hidden {
return
}
var handler complete.Predictor
handler, ok := completion.GetCommandFlagHandler(root, flag.Name)
if !ok {
handler = complete.PredictAnything
}
if len(flag.Shorthand) > 0 {
rootCmp.Flags["-"+flag.Shorthand] = handler
}
rootCmp.Flags["--"+flag.Name] = handler
}
root.LocalFlags().VisitAll(addFlags)
root.InheritedFlags().VisitAll(addFlags)
if root.HasAvailableSubCommands() {
rootCmp.Sub = make(complete.Commands)
for _, c := range root.Commands() {
if !c.Hidden {
rootCmp.Sub[c.Name()] = createCompletion(c)
}
}
}
var handler complete.Predictor
handler, ok := completion.GetCommandHandler(root)
if !ok {
handler = complete.PredictNothing
}
rootCmp.Args = handler
return rootCmp
}