github.com/divan/complete@v0.0.0-20170515130636-337e95201af7/cmd/cmd.go (about) 1 // Package cmd used for command line options for the complete tool 2 package cmd 3 4 import ( 5 "errors" 6 "flag" 7 "fmt" 8 "os" 9 "strings" 10 11 "github.com/posener/complete/cmd/install" 12 ) 13 14 // CLI for command line 15 type CLI struct { 16 Name string 17 18 install bool 19 uninstall bool 20 yes bool 21 } 22 23 const ( 24 defaultInstallName = "install" 25 defaultUninstallName = "uninstall" 26 ) 27 28 // Run is used when running complete in command line mode. 29 // this is used when the complete is not completing words, but to 30 // install it or uninstall it. 31 func (f *CLI) Run() bool { 32 33 // add flags and parse them in case they were not added and parsed 34 // by the main program 35 f.AddFlags(nil, "", "") 36 flag.Parse() 37 38 err := f.validate() 39 if err != nil { 40 os.Stderr.WriteString(err.Error() + "\n") 41 os.Exit(1) 42 } 43 44 switch { 45 case f.install: 46 f.prompt() 47 err = install.Install(f.Name) 48 case f.uninstall: 49 f.prompt() 50 err = install.Uninstall(f.Name) 51 default: 52 // non of the action flags matched, 53 // returning false should make the real program execute 54 return false 55 } 56 57 if err != nil { 58 fmt.Printf("%s failed! %s\n", f.action(), err) 59 os.Exit(3) 60 } 61 fmt.Println("Done!") 62 return true 63 } 64 65 // prompt use for approval 66 // exit if approval was not given 67 func (f *CLI) prompt() { 68 defer fmt.Println(f.action() + "ing...") 69 if f.yes { 70 return 71 } 72 fmt.Printf("%s completion for %s? ", f.action(), f.Name) 73 var answer string 74 fmt.Scanln(&answer) 75 76 switch strings.ToLower(answer) { 77 case "y", "yes": 78 return 79 default: 80 fmt.Println("Cancelling...") 81 os.Exit(1) 82 } 83 } 84 85 // AddFlags adds the CLI flags to the flag set. 86 // If flags is nil, the default command line flags will be taken. 87 // Pass non-empty strings as installName and uninstallName to override the default 88 // flag names. 89 func (f *CLI) AddFlags(flags *flag.FlagSet, installName, uninstallName string) { 90 if flags == nil { 91 flags = flag.CommandLine 92 } 93 94 if installName == "" { 95 installName = defaultInstallName 96 } 97 if uninstallName == "" { 98 uninstallName = defaultUninstallName 99 } 100 101 if flags.Lookup(installName) == nil { 102 flags.BoolVar(&f.install, installName, false, 103 fmt.Sprintf("Install completion for %s command", f.Name)) 104 } 105 if flags.Lookup(uninstallName) == nil { 106 flags.BoolVar(&f.uninstall, uninstallName, false, 107 fmt.Sprintf("Uninstall completion for %s command", f.Name)) 108 } 109 if flags.Lookup("y") == nil { 110 flags.BoolVar(&f.yes, "y", false, "Don't prompt user for typing 'yes'") 111 } 112 } 113 114 // validate the CLI 115 func (f *CLI) validate() error { 116 if f.install && f.uninstall { 117 return errors.New("Install and uninstall are mutually exclusive") 118 } 119 return nil 120 } 121 122 // action name according to the CLI values. 123 func (f *CLI) action() string { 124 switch { 125 case f.install: 126 return "Install" 127 case f.uninstall: 128 return "Uninstall" 129 default: 130 return "unknown" 131 } 132 }