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