github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/help.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"sort"
     8  	"strings"
     9  
    10  	"github.com/mitchellh/cli"
    11  )
    12  
    13  // helpFunc is a cli.HelpFunc that can is used to output the help for Terraform.
    14  func helpFunc(commands map[string]cli.CommandFactory) string {
    15  	// Determine the maximum key length, and classify based on type
    16  	porcelain := make(map[string]cli.CommandFactory)
    17  	plumbing := make(map[string]cli.CommandFactory)
    18  	maxKeyLen := 0
    19  	for key, f := range commands {
    20  		if len(key) > maxKeyLen {
    21  			maxKeyLen = len(key)
    22  		}
    23  
    24  		if _, ok := PlumbingCommands[key]; ok {
    25  			plumbing[key] = f
    26  		} else {
    27  			porcelain[key] = f
    28  		}
    29  	}
    30  
    31  	// The output produced by this is included in the docs at
    32  	// website/source/docs/commands/index.html.markdown; if you
    33  	// change this then consider updating that to match.
    34  	helpText := fmt.Sprintf(`
    35  Usage: terraform [--version] [--help] <command> [args]
    36  
    37  The available commands for execution are listed below.
    38  The most common, useful commands are shown first, followed by
    39  less common or more advanced commands. If you're just getting
    40  started with Terraform, stick with the common commands. For the
    41  other commands, please read the help and docs before usage.
    42  
    43  Common commands:
    44  %s
    45  All other commands:
    46  %s
    47  `, listCommands(porcelain, maxKeyLen), listCommands(plumbing, maxKeyLen))
    48  
    49  	return strings.TrimSpace(helpText)
    50  }
    51  
    52  // listCommands just lists the commands in the map with the
    53  // given maximum key length.
    54  func listCommands(commands map[string]cli.CommandFactory, maxKeyLen int) string {
    55  	var buf bytes.Buffer
    56  
    57  	// Get the list of keys so we can sort them, and also get the maximum
    58  	// key length so they can be aligned properly.
    59  	keys := make([]string, 0, len(commands))
    60  	for key, _ := range commands {
    61  		// This is an internal command that users should never call directly so
    62  		// we will hide it from the command listing.
    63  		if key == "internal-plugin" {
    64  			continue
    65  		}
    66  		keys = append(keys, key)
    67  	}
    68  	sort.Strings(keys)
    69  
    70  	for _, key := range keys {
    71  		commandFunc, ok := commands[key]
    72  		if !ok {
    73  			// This should never happen since we JUST built the list of
    74  			// keys.
    75  			panic("command not found: " + key)
    76  		}
    77  
    78  		command, err := commandFunc()
    79  		if err != nil {
    80  			log.Printf("[ERR] cli: Command '%s' failed to load: %s",
    81  				key, err)
    82  			continue
    83  		}
    84  
    85  		key = fmt.Sprintf("%s%s", key, strings.Repeat(" ", maxKeyLen-len(key)))
    86  		buf.WriteString(fmt.Sprintf("    %s    %s\n", key, command.Synopsis()))
    87  	}
    88  
    89  	return buf.String()
    90  }