github.com/minio/console@v1.4.1/cmd/console/main.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2021 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 // 17 18 package main 19 20 import ( 21 "os" 22 "path/filepath" 23 "sort" 24 "time" 25 26 "github.com/minio/cli" 27 "github.com/minio/console/pkg" 28 "github.com/minio/pkg/v3/console" 29 "github.com/minio/pkg/v3/trie" 30 "github.com/minio/pkg/v3/words" 31 ) 32 33 // Help template for Console. 34 var consoleHelpTemplate = `NAME: 35 {{.Name}} - {{.Usage}} 36 37 DESCRIPTION: 38 {{.Description}} 39 40 USAGE: 41 {{.HelpName}} {{if .VisibleFlags}}[FLAGS] {{end}}COMMAND{{if .VisibleFlags}}{{end}} [ARGS...] 42 43 COMMANDS: 44 {{range .VisibleCommands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} 45 {{end}}{{if .VisibleFlags}} 46 FLAGS: 47 {{range .VisibleFlags}}{{.}} 48 {{end}}{{end}} 49 VERSION: 50 {{.Version}} 51 ` 52 53 func newApp(name string) *cli.App { 54 // Collection of console commands currently supported are. 55 var commands []cli.Command 56 57 // Collection of console commands currently supported in a trie tree. 58 commandsTree := trie.NewTrie() 59 60 // registerCommand registers a cli command. 61 registerCommand := func(command cli.Command) { 62 commands = append(commands, command) 63 commandsTree.Insert(command.Name) 64 } 65 66 // register commands 67 for _, cmd := range appCmds { 68 registerCommand(cmd) 69 } 70 71 findClosestCommands := func(command string) []string { 72 var closestCommands []string 73 closestCommands = append(closestCommands, commandsTree.PrefixMatch(command)...) 74 75 sort.Strings(closestCommands) 76 // Suggest other close commands - allow missed, wrongly added and 77 // even transposed characters 78 for _, value := range commandsTree.Walk(commandsTree.Root()) { 79 if sort.SearchStrings(closestCommands, value) < len(closestCommands) { 80 continue 81 } 82 // 2 is arbitrary and represents the max 83 // allowed number of typed errors 84 if words.DamerauLevenshteinDistance(command, value) < 2 { 85 closestCommands = append(closestCommands, value) 86 } 87 } 88 89 return closestCommands 90 } 91 92 cli.HelpFlag = cli.BoolFlag{ 93 Name: "help, h", 94 Usage: "show help", 95 } 96 97 app := cli.NewApp() 98 app.Name = name 99 app.Version = pkg.Version + " - " + pkg.ShortCommitID 100 app.Author = "MinIO, Inc." 101 app.Usage = "MinIO Console Server" 102 app.Description = `MinIO Console Server` 103 app.Copyright = "(c) 2021 MinIO, Inc." 104 app.Compiled, _ = time.Parse(time.RFC3339, pkg.ReleaseTime) 105 app.Commands = commands 106 app.HideHelpCommand = true // Hide `help, h` command, we already have `minio --help`. 107 app.CustomAppHelpTemplate = consoleHelpTemplate 108 app.CommandNotFound = func(_ *cli.Context, command string) { 109 console.Printf("‘%s’ is not a console sub-command. See ‘console --help’.\n", command) 110 closestCommands := findClosestCommands(command) 111 if len(closestCommands) > 0 { 112 console.Println() 113 console.Println("Did you mean one of these?") 114 for _, cmd := range closestCommands { 115 console.Printf("\t‘%s’\n", cmd) 116 } 117 } 118 119 os.Exit(1) 120 } 121 122 return app 123 } 124 125 func main() { 126 args := os.Args 127 // Set the orchestrator app name. 128 appName := filepath.Base(args[0]) 129 // Run the app - exit on error. 130 if err := newApp(appName).Run(args); err != nil { 131 os.Exit(1) 132 } 133 }