github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/help.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package main 5 6 import ( 7 "bytes" 8 "fmt" 9 "log" 10 "sort" 11 "strings" 12 13 "github.com/mitchellh/cli" 14 ) 15 16 // helpFunc is a cli.HelpFunc that can be used to output the help CLI instructions for Terraform. 17 func helpFunc(commands map[string]cli.CommandFactory) string { 18 // Determine the maximum key length, and classify based on type 19 var otherCommands []string 20 maxKeyLen := 0 21 22 for key := range commands { 23 if _, ok := HiddenCommands[key]; ok { 24 // We don't consider hidden commands when deciding the 25 // maximum command length. 26 continue 27 } 28 29 if len(key) > maxKeyLen { 30 maxKeyLen = len(key) 31 } 32 33 isOther := true 34 for _, candidate := range PrimaryCommands { 35 if candidate == key { 36 isOther = false 37 break 38 } 39 } 40 if isOther { 41 otherCommands = append(otherCommands, key) 42 } 43 } 44 sort.Strings(otherCommands) 45 46 // The output produced by this is included in the docs at 47 // website/source/docs/cli/commands/index.html.markdown; if you 48 // change this then consider updating that to match. 49 helpText := fmt.Sprintf(` 50 Usage: terraform [global options] <subcommand> [args] 51 52 The available commands for execution are listed below. 53 The primary workflow commands are given first, followed by 54 less common or more advanced commands. 55 56 Main commands: 57 %s 58 All other commands: 59 %s 60 Global options (use these before the subcommand, if any): 61 -chdir=DIR Switch to a different working directory before executing the 62 given subcommand. 63 -help Show this help output, or the help for a specified subcommand. 64 -version An alias for the "version" subcommand. 65 `, listCommands(commands, PrimaryCommands, maxKeyLen), listCommands(commands, otherCommands, maxKeyLen)) 66 67 return strings.TrimSpace(helpText) 68 } 69 70 // listCommands just lists the commands in the map with the 71 // given maximum key length. 72 func listCommands(allCommands map[string]cli.CommandFactory, order []string, maxKeyLen int) string { 73 var buf bytes.Buffer 74 75 for _, key := range order { 76 commandFunc, ok := allCommands[key] 77 if !ok { 78 // This suggests an inconsistency in the command table definitions 79 // in commands.go . 80 panic("command not found: " + key) 81 } 82 83 command, err := commandFunc() 84 if err != nil { 85 // This would be really weird since there's no good reason for 86 // any of our command factories to fail. 87 log.Printf("[ERR] cli: Command '%s' failed to load: %s", 88 key, err) 89 continue 90 } 91 92 key = fmt.Sprintf("%s%s", key, strings.Repeat(" ", maxKeyLen-len(key))) 93 buf.WriteString(fmt.Sprintf(" %s %s\n", key, command.Synopsis())) 94 } 95 96 return buf.String() 97 }