From 90906f38425c4f611292b25fd91d02ac5b725a84 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 23 Oct 2020 15:38:45 -0700 Subject: [PATCH 1/6] command: Remove the useless "debug" subcommand This is just a husk of a container command that has no nested commands under it, so it isn't serving any purpose. --- command/debug_command.go | 30 ------------------------------ commands.go | 7 ------- 2 files changed, 37 deletions(-) delete mode 100644 command/debug_command.go diff --git a/command/debug_command.go b/command/debug_command.go deleted file mode 100644 index 7058553b9f..0000000000 --- a/command/debug_command.go +++ /dev/null @@ -1,30 +0,0 @@ -package command - -import ( - "strings" - - "github.com/mitchellh/cli" -) - -// DebugCommand is a Command implementation that just shows help for -// the subcommands nested below it. -type DebugCommand struct { - Meta -} - -func (c *DebugCommand) Run(args []string) int { - return cli.RunResultHelp -} - -func (c *DebugCommand) Help() string { - helpText := ` -Usage: terraform debug [options] [args] - - This command has subcommands for debug output management -` - return strings.TrimSpace(helpText) -} - -func (c *DebugCommand) Synopsis() string { - return "Debug output management (experimental)" -} diff --git a/commands.go b/commands.go index 1e947d681f..7040cbb33f 100644 --- a/commands.go +++ b/commands.go @@ -95,7 +95,6 @@ func initCommands( PlumbingCommands = map[string]struct{}{ "state": struct{}{}, // includes all subcommands - "debug": struct{}{}, // includes all subcommands "force-unlock": struct{}{}, "push": struct{}{}, "0.12upgrade": struct{}{}, @@ -339,12 +338,6 @@ func initCommands( }, nil }, - "debug": func() (cli.Command, error) { - return &command.DebugCommand{ - Meta: meta, - }, nil - }, - "force-unlock": func() (cli.Command, error) { return &command.UnlockCommand{ Meta: meta, From ac729c469672bc82b29883acc59208da405ee588 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 23 Oct 2020 15:48:46 -0700 Subject: [PATCH 2/6] main: Hide several commands from our help These are commands that either no longer do anything aside from emitting an error message or are just backward-compatibility aliases for other commands. This generalizes our previous situation where we were specifically hiding "internal-plugin", and does so in a way that fixes the long-standing cosmetic bug that the column width in the help output was chosen based on the hidden command "internal-plugin", which is unfortunately also the longest command in our command set. --- commands.go | 12 +++++++++--- help.go | 11 ++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/commands.go b/commands.go index 7040cbb33f..a63dd527ed 100644 --- a/commands.go +++ b/commands.go @@ -26,6 +26,7 @@ const runningInAutomationEnvName = "TF_IN_AUTOMATION" // Commands is the mapping of all the available Terraform commands. var Commands map[string]cli.CommandFactory var PlumbingCommands map[string]struct{} +var HiddenCommands map[string]struct{} // Ui is the cli.Ui used for communicating to the outside world. var Ui cli.Ui @@ -96,9 +97,14 @@ func initCommands( PlumbingCommands = map[string]struct{}{ "state": struct{}{}, // includes all subcommands "force-unlock": struct{}{}, - "push": struct{}{}, - "0.12upgrade": struct{}{}, - "0.13upgrade": struct{}{}, + } + + HiddenCommands = map[string]struct{}{ + "0.12upgrade": struct{}{}, + "0.13upgrade": struct{}{}, + "env": struct{}{}, + "internal-plugin": struct{}{}, + "push": struct{}{}, } Commands = map[string]cli.CommandFactory{ diff --git a/help.go b/help.go index e020edea9c..6de48cd355 100644 --- a/help.go +++ b/help.go @@ -17,6 +17,12 @@ func helpFunc(commands map[string]cli.CommandFactory) string { plumbing := make(map[string]cli.CommandFactory) maxKeyLen := 0 for key, f := range commands { + if _, ok := HiddenCommands[key]; ok { + // We don't consider hidden commands when deciding the + // maximum command length. + continue + } + if len(key) > maxKeyLen { maxKeyLen = len(key) } @@ -65,11 +71,6 @@ func listCommands(commands map[string]cli.CommandFactory, maxKeyLen int) string // key length so they can be aligned properly. keys := make([]string, 0, len(commands)) for key, _ := range commands { - // This is an internal command that users should never call directly so - // we will hide it from the command listing. - if key == "internal-plugin" { - continue - } keys = append(keys, key) } sort.Strings(keys) From 545ceb03fb529c2c8d91f6b0fa356fe42b941e7a Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 23 Oct 2020 16:13:41 -0700 Subject: [PATCH 3/6] main: Emphasize only the primary workflow commands in our help A long time ago we introduced this separation between "common commands" and "all other commands", but over the intervening years we've not really done a good job of classifying new commands we've added and so by default most of them ended up being classified as "common". In the interests of making this output more useful for those getting started, this switches the two categories so that "Main commands" is now the curated list, and "all other commands" is the bucket for everything else. The intent here is that the "main commands" are the ones users are likely to try as part of their initial learning of Terraform, while the other commands are for less common situations where the user is more likely to learn about a specific command in some other context, like a tutorial about a special situation. The "main commands" are also now ordered by the sequence users will typically run them in, rather than alphabetical order. That's a subjective readability tradeoff, but I think as long as the list stays relatively short (which it should) it's still relatively easy to scan and find a particular command in the shortlist. --- commands.go | 47 +++++++++++++++++++++++++++++------------ help.go | 61 +++++++++++++++++++++++++---------------------------- 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/commands.go b/commands.go index a63dd527ed..43bcf60fdc 100644 --- a/commands.go +++ b/commands.go @@ -25,7 +25,22 @@ const runningInAutomationEnvName = "TF_IN_AUTOMATION" // Commands is the mapping of all the available Terraform commands. var Commands map[string]cli.CommandFactory -var PlumbingCommands map[string]struct{} + +// PrimaryCommands is an ordered sequence of the top-level commands (not +// subcommands) that we emphasize at the top of our help output. This is +// ordered so that we can show them in the typical workflow order, rather +// than in alphabetical order. Anything not in this sequence or in the +// HiddenCommands set appears under "all other commands". +var PrimaryCommands []string + +// HiddenCommands is a set of top-level commands (not subcommands) that are +// not advertised in the top-level help at all. This is typically because +// they are either just stubs that return an error message about something +// no longer being supported or backward-compatibility aliases for other +// commands. +// +// No commands in the PrimaryCommands sequence should also appear in the +// HiddenCommands set, because that would be rather silly. var HiddenCommands map[string]struct{} // Ui is the cli.Ui used for communicating to the outside world. @@ -94,19 +109,6 @@ func initCommands( // add, remove or reclassify commands then consider updating // that to match. - PlumbingCommands = map[string]struct{}{ - "state": struct{}{}, // includes all subcommands - "force-unlock": struct{}{}, - } - - HiddenCommands = map[string]struct{}{ - "0.12upgrade": struct{}{}, - "0.13upgrade": struct{}{}, - "env": struct{}{}, - "internal-plugin": struct{}{}, - "push": struct{}{}, - } - Commands = map[string]cli.CommandFactory{ "apply": func() (cli.Command, error) { return &command.ApplyCommand{ @@ -402,6 +404,23 @@ func initCommands( }, nil }, } + + PrimaryCommands = []string{ + "init", + "validate", + "plan", + "apply", + "destroy", + } + + HiddenCommands = map[string]struct{}{ + "0.12upgrade": struct{}{}, + "0.13upgrade": struct{}{}, + "env": struct{}{}, + "internal-plugin": struct{}{}, + "push": struct{}{}, + } + } // makeShutdownCh creates an interrupt listener and returns a channel. diff --git a/help.go b/help.go index 6de48cd355..789218454b 100644 --- a/help.go +++ b/help.go @@ -13,10 +13,10 @@ import ( // helpFunc is a cli.HelpFunc that can is used to output the help for Terraform. func helpFunc(commands map[string]cli.CommandFactory) string { // Determine the maximum key length, and classify based on type - porcelain := make(map[string]cli.CommandFactory) - plumbing := make(map[string]cli.CommandFactory) + var otherCommands []string maxKeyLen := 0 - for key, f := range commands { + + for key := range commands { if _, ok := HiddenCommands[key]; ok { // We don't consider hidden commands when deciding the // maximum command length. @@ -27,12 +27,18 @@ func helpFunc(commands map[string]cli.CommandFactory) string { maxKeyLen = len(key) } - if _, ok := PlumbingCommands[key]; ok { - plumbing[key] = f - } else { - porcelain[key] = f + isOther := true + for _, candidate := range PrimaryCommands { + if candidate == key { + isOther = false + break + } + } + if isOther { + otherCommands = append(otherCommands, key) } } + sort.Strings(otherCommands) // The output produced by this is included in the docs at // website/source/docs/commands/index.html.markdown; if you @@ -41,50 +47,41 @@ func helpFunc(commands map[string]cli.CommandFactory) string { Usage: terraform [global options] [args] The available commands for execution are listed below. -The most common, useful commands are shown first, followed by -less common or more advanced commands. If you're just getting -started with Terraform, stick with the common commands. For the -other commands, please read the help and docs before usage. +The primary workflow commands are given first, followed by +less common or more advanced commands. -Common commands: +Main commands: %s All other commands: %s - Global options (use these before the subcommand, if any): - -chdir=DIR Switch to a different working directory before executing - the given subcommand. - -help Show this help output, or the help for a specified - subcommand. - -version An alias for the "version" subcommand. -`, listCommands(porcelain, maxKeyLen), listCommands(plumbing, maxKeyLen)) + -chdir=DIR Switch to a different working directory before executing + the given subcommand. + -help Show this help output, or the help for a specified + subcommand. + -version An alias for the "version" subcommand. +`, listCommands(commands, PrimaryCommands, maxKeyLen), listCommands(commands, otherCommands, maxKeyLen)) return strings.TrimSpace(helpText) } // listCommands just lists the commands in the map with the // given maximum key length. -func listCommands(commands map[string]cli.CommandFactory, maxKeyLen int) string { +func listCommands(allCommands map[string]cli.CommandFactory, order []string, maxKeyLen int) string { var buf bytes.Buffer - // Get the list of keys so we can sort them, and also get the maximum - // key length so they can be aligned properly. - keys := make([]string, 0, len(commands)) - for key, _ := range commands { - keys = append(keys, key) - } - sort.Strings(keys) - - for _, key := range keys { - commandFunc, ok := commands[key] + for _, key := range order { + commandFunc, ok := allCommands[key] if !ok { - // This should never happen since we JUST built the list of - // keys. + // This suggests an inconsistency in the command table definitions + // in commands.go . panic("command not found: " + key) } command, err := commandFunc() if err != nil { + // This would be really weird since there's no good reason for + // any of our command factories to fail. log.Printf("[ERR] cli: Command '%s' failed to load: %s", key, err) continue From c60dd7c783aea2f9c17d2959dda2f6af12e64872 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 23 Oct 2020 16:55:32 -0700 Subject: [PATCH 4/6] command: Improve consistency of the command short descriptions The short description of our commands (as shown in the main help output from "terraform") was previously very inconsistent, using different tense/mood for different commands. Some of the commands were also using some terminology choices inconsistent with how we currently talk about the related ideas in our documentation. Here I've tried to add some consistency by first rewriting them all in the imperative mood (except the ones that just are just subcommand groupings), and tweaking some of the terminology to hopefully gel better with how we present similar ideas in our recently-updated docs. While working on this I inevitably spotted some similar inconsistencies in the longer-form help output of some of the commands. I've not reviewed all of these for consistency, but I did update some where the wording was either left inconsstent with the short form changes I'd made or where the prose stood out to me as particularly inconsistent with our current usual documentation language style. All of this is subjective, so I expect we'll continue to tweak these over time as we continue to develop our documentation writing style based on user questions and feedback. --- command/apply.go | 19 ++++++++++--------- command/console.go | 2 +- command/fmt.go | 2 +- command/get.go | 6 +++++- command/graph.go | 2 +- command/import.go | 2 +- command/init.go | 2 +- command/output.go | 2 +- command/plan.go | 12 ++++++------ command/providers.go | 2 +- command/providers_lock.go | 2 +- command/providers_mirror.go | 2 +- command/providers_schema.go | 2 +- command/refresh.go | 2 +- command/show.go | 2 +- command/taint.go | 26 ++++++++++++++++---------- command/unlock.go | 4 ++-- command/untaint.go | 19 +++++++++++-------- command/validate.go | 2 +- command/version.go | 2 +- 20 files changed, 64 insertions(+), 50 deletions(-) diff --git a/command/apply.go b/command/apply.go index eb2740e79c..36b66f677b 100644 --- a/command/apply.go +++ b/command/apply.go @@ -196,23 +196,24 @@ func (c *ApplyCommand) Help() string { func (c *ApplyCommand) Synopsis() string { if c.Destroy { - return "Destroy Terraform-managed infrastructure" + return "Destroy previously-created infrastructure" } - return "Builds or changes infrastructure" + return "Create or update infrastructure" } func (c *ApplyCommand) helpApply() string { helpText := ` -Usage: terraform apply [options] [DIR-OR-PLAN] +Usage: terraform apply [options] [PLAN] - Builds or changes infrastructure according to Terraform configuration - files in DIR. + Creates or updates infrastructure according to Terraform configuration + files in the current directory. - By default, apply scans the current directory for the configuration - and applies the changes appropriately. However, a path to another - configuration or an execution plan can be provided. Execution plans can be - used to only execute a pre-determined set of actions. + By default, Terraform will generate a new plan and present it for your + approval before taking any action. You can optionally provide a plan + file created by a previous call to "terraform plan", in which case + Terraform will take the actions described in that plan without any + confirmation prompt. Options: diff --git a/command/console.go b/command/console.go index 359d9dca06..c6f872b905 100644 --- a/command/console.go +++ b/command/console.go @@ -203,5 +203,5 @@ Options: } func (c *ConsoleCommand) Synopsis() string { - return "Interactive console for Terraform interpolations" + return "Try Terraform expressions at an interactive command prompt" } diff --git a/command/fmt.go b/command/fmt.go index 13e84a2187..ff59d2b9d5 100644 --- a/command/fmt.go +++ b/command/fmt.go @@ -526,7 +526,7 @@ Options: } func (c *FmtCommand) Synopsis() string { - return "Rewrites config files to canonical format" + return "Reformat your configuration in the standard style" } func bytesDiff(b1, b2 []byte, path string) (data []byte, err error) { diff --git a/command/get.go b/command/get.go index 238020a942..49cb207c33 100644 --- a/command/get.go +++ b/command/get.go @@ -54,6 +54,10 @@ Usage: terraform get [options] PATH already downloaded, it will not be redownloaded or checked for updates unless the -update flag is specified. + Module installation also happens automatically by default as part of + the "terraform init" command, so you should rarely need to run this + command separately. + Options: -update Check already-downloaded modules for available updates @@ -66,7 +70,7 @@ Options: } func (c *GetCommand) Synopsis() string { - return "Download and install modules for the configuration" + return "Install or upgrade remote Terraform modules" } func getModules(m *Meta, path string, upgrade bool) tfdiags.Diagnostics { diff --git a/command/graph.go b/command/graph.go index cdfaaa2e78..fba33c6f8a 100644 --- a/command/graph.go +++ b/command/graph.go @@ -190,5 +190,5 @@ Options: } func (c *GraphCommand) Synopsis() string { - return "Create a visual graph of Terraform resources" + return "Generate a Graphviz graph of the steps in an operation" } diff --git a/command/import.go b/command/import.go index f5891ed6dc..cf22946c5c 100644 --- a/command/import.go +++ b/command/import.go @@ -327,7 +327,7 @@ Options: } func (c *ImportCommand) Synopsis() string { - return "Import existing infrastructure into Terraform" + return "Associate existing infrastructure with a Terraform resource" } const importCommandInvalidAddressReference = `For information on valid syntax, see: diff --git a/command/init.go b/command/init.go index 6cd9a27bfc..e90449ca51 100644 --- a/command/init.go +++ b/command/init.go @@ -1052,7 +1052,7 @@ Options: } func (c *InitCommand) Synopsis() string { - return "Initialize a Terraform working directory" + return "Prepare your working directory for other commands" } const errInitConfigError = ` diff --git a/command/output.go b/command/output.go index e389c458c0..3f5cc2bea0 100644 --- a/command/output.go +++ b/command/output.go @@ -223,5 +223,5 @@ Options: } func (c *OutputCommand) Synopsis() string { - return "Read an output from a state file" + return "Show output values from your root module" } diff --git a/command/plan.go b/command/plan.go index 8064cad57d..dc578f42e8 100644 --- a/command/plan.go +++ b/command/plan.go @@ -193,12 +193,12 @@ func (c *PlanCommand) Help() string { helpText := ` Usage: terraform plan [options] [DIR] - Generates an execution plan for Terraform. + Generates a speculative execution plan, showing what actions Terraform + would take to apply the current configuration. This command will not + actually perform the planned actions. - This execution plan can be reviewed prior to running apply to get a - sense for what Terraform will do. Optionally, the plan can be saved to - a Terraform plan file, and apply can take this plan file to execute - this plan exactly. + You can optionally save the plan to a file, which you can then pass to + the "apply" command to perform exactly the actions described in the plan. Options: @@ -249,5 +249,5 @@ Options: } func (c *PlanCommand) Synopsis() string { - return "Generate and show an execution plan" + return "Show changes required by the current configuration" } diff --git a/command/providers.go b/command/providers.go index 918fd841e3..d2042d122b 100644 --- a/command/providers.go +++ b/command/providers.go @@ -21,7 +21,7 @@ func (c *ProvidersCommand) Help() string { } func (c *ProvidersCommand) Synopsis() string { - return "Prints a tree of the providers used in the configuration" + return "Show the providers required for this configuration" } func (c *ProvidersCommand) Run(args []string) int { diff --git a/command/providers_lock.go b/command/providers_lock.go index 38bf2184ae..74f23cef09 100644 --- a/command/providers_lock.go +++ b/command/providers_lock.go @@ -23,7 +23,7 @@ type ProvidersLockCommand struct { } func (c *ProvidersLockCommand) Synopsis() string { - return "Creates or updates dependency locks for providers in the configuration" + return "Write out dependency locks for the configured providers" } func (c *ProvidersLockCommand) Run(args []string) int { diff --git a/command/providers_mirror.go b/command/providers_mirror.go index 029b086304..a2367707a0 100644 --- a/command/providers_mirror.go +++ b/command/providers_mirror.go @@ -24,7 +24,7 @@ type ProvidersMirrorCommand struct { } func (c *ProvidersMirrorCommand) Synopsis() string { - return "Mirrors the provider plugins needed for the current configuration" + return "Save local copies of all required provider plugins" } func (c *ProvidersMirrorCommand) Run(args []string) int { diff --git a/command/providers_schema.go b/command/providers_schema.go index 60e4c4c39f..00634cf2f9 100644 --- a/command/providers_schema.go +++ b/command/providers_schema.go @@ -20,7 +20,7 @@ func (c *ProvidersSchemaCommand) Help() string { } func (c *ProvidersSchemaCommand) Synopsis() string { - return "Prints the schemas of the providers used in the configuration" + return "Show schemas for the providers used in the configuration" } func (c *ProvidersSchemaCommand) Run(args []string) int { diff --git a/command/refresh.go b/command/refresh.go index 4ab3932f4b..36c40633fc 100644 --- a/command/refresh.go +++ b/command/refresh.go @@ -154,5 +154,5 @@ Options: } func (c *RefreshCommand) Synopsis() string { - return "Update local state file against real resources" + return "Update the state to match remote systems" } diff --git a/command/show.go b/command/show.go index 3bf034c9e1..56d0e34b9e 100644 --- a/command/show.go +++ b/command/show.go @@ -209,7 +209,7 @@ Options: } func (c *ShowCommand) Synopsis() string { - return "Inspect Terraform state or plan" + return "Show the current state or a saved plan" } // getPlanFromPath returns a plan and statefile if the user-supplied path points diff --git a/command/taint.go b/command/taint.go index 04a5bf1f10..ad4f10f06d 100644 --- a/command/taint.go +++ b/command/taint.go @@ -201,21 +201,27 @@ func (c *TaintCommand) Help() string { helpText := ` Usage: terraform taint [options]
- Manually mark a resource as tainted, forcing a destroy and recreate - on the next plan/apply. + Terraform uses the term "tainted" to describe a resource instance + which may not be fully functional, either because its creation + partially failed or because you've manually marked it as such using + this command. - This will not modify your infrastructure. This command changes your - state to mark a resource as tainted so that during the next plan or - apply that resource will be destroyed and recreated. This command on - its own will not modify infrastructure. This command can be undone - using the "terraform untaint" command with the same address. + This will not modify your infrastructure directly, but subsequent + Terraform plans will include actions to destroy the remote object + and create a new object to replace it. - The address is in the usual resource address syntax, as shown in - the output from other commands, such as: + You can remove the "taint" state from a resource instance using + the "terraform untaint" command. + + The address is in the usual resource address syntax, such as: aws_instance.foo aws_instance.bar[1] module.foo.module.bar.aws_instance.baz + Use your shell's quoting or escaping syntax to ensure that the + address will reach Terraform correctly, without any special + interpretation. + Options: -allow-missing If specified, the command will succeed (exit code 0) @@ -240,7 +246,7 @@ Options: } func (c *TaintCommand) Synopsis() string { - return "Manually mark a resource for recreation" + return "Mark a resource instance as not fully functional" } func (c *TaintCommand) allowMissingExit(name addrs.AbsResourceInstance) int { diff --git a/command/unlock.go b/command/unlock.go index 94b2f7d8f2..6376fd0f6d 100644 --- a/command/unlock.go +++ b/command/unlock.go @@ -121,7 +121,7 @@ Usage: terraform force-unlock LOCK_ID [DIR] Manually unlock the state for the defined configuration. This will not modify your infrastructure. This command removes the lock on the - state for the current configuration. The behavior of this lock is dependent + state for the current workspace. The behavior of this lock is dependent on the backend being used. Local state files cannot be unlocked by another process. @@ -133,7 +133,7 @@ Options: } func (c *UnlockCommand) Synopsis() string { - return "Manually unlock the terraform state" + return "Release a stuck lock on the current workspace" } const outputUnlockSuccess = ` diff --git a/command/untaint.go b/command/untaint.go index 2f91d44829..96493bcb0c 100644 --- a/command/untaint.go +++ b/command/untaint.go @@ -175,14 +175,17 @@ func (c *UntaintCommand) Help() string { helpText := ` Usage: terraform untaint [options] name - Manually unmark a resource as tainted, restoring it as the primary - instance in the state. This reverses either a manual 'terraform taint' - or the result of provisioners failing on a resource. + Terraform uses the term "tainted" to describe a resource instance + which may not be fully functional, either because its creation + partially failed or because you've manually marked it as such using + the "terraform taint" command. - This will not modify your infrastructure. This command changes your - state to unmark a resource as tainted. This command can be undone by - reverting the state backup file that is created, or by running - 'terraform taint' on the resource. + This command removes that state from a resource instance, causing + Terraform to see it as fully-functional and not in need of + replacement. + + This will not modify your infrastructure directly. It only avoids + Terraform planning to replace a tainted instance in a future operation. Options: @@ -212,7 +215,7 @@ Options: } func (c *UntaintCommand) Synopsis() string { - return "Manually unmark a resource as tainted" + return "Remove the 'tainted' state from a resource instance" } func (c *UntaintCommand) allowMissingExit(name addrs.AbsResourceInstance) int { diff --git a/command/validate.go b/command/validate.go index e9c8914de0..6519a5db9b 100644 --- a/command/validate.go +++ b/command/validate.go @@ -235,7 +235,7 @@ func (c *ValidateCommand) showResults(diags tfdiags.Diagnostics, jsonOutput bool } func (c *ValidateCommand) Synopsis() string { - return "Validates the Terraform files" + return "Check whether the configuration is valid" } func (c *ValidateCommand) Help() string { diff --git a/command/version.go b/command/version.go index b20cc4c6a3..cbece20ac9 100644 --- a/command/version.go +++ b/command/version.go @@ -169,5 +169,5 @@ func (c *VersionCommand) Run(args []string) int { } func (c *VersionCommand) Synopsis() string { - return "Prints the Terraform version" + return "Show the current Terraform version" } From 67934e83050e8fd758f0ff5b74614a4a435e4725 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 23 Oct 2020 16:59:29 -0700 Subject: [PATCH 5/6] main: A slightly more compact presentation of the main help text This just reduces the amount of space between different elements on in the main help output from four columns to two. The main motivation here was to give some of the longer command descriptions a little more horizontal breathing room, but subjectively I also find the tighter column gutters easier to scan. Others may disagree, of course. --- help.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/help.go b/help.go index 789218454b..64eb032732 100644 --- a/help.go +++ b/help.go @@ -55,11 +55,10 @@ Main commands: All other commands: %s Global options (use these before the subcommand, if any): - -chdir=DIR Switch to a different working directory before executing - the given subcommand. - -help Show this help output, or the help for a specified - subcommand. - -version An alias for the "version" subcommand. + -chdir=DIR Switch to a different working directory before executing the + given subcommand. + -help Show this help output, or the help for a specified subcommand. + -version An alias for the "version" subcommand. `, listCommands(commands, PrimaryCommands, maxKeyLen), listCommands(commands, otherCommands, maxKeyLen)) return strings.TrimSpace(helpText) @@ -88,7 +87,7 @@ func listCommands(allCommands map[string]cli.CommandFactory, order []string, max } key = fmt.Sprintf("%s%s", key, strings.Repeat(" ", maxKeyLen-len(key))) - buf.WriteString(fmt.Sprintf(" %s %s\n", key, command.Synopsis())) + buf.WriteString(fmt.Sprintf(" %s %s\n", key, command.Synopsis())) } return buf.String() From d053e9195065fd71940288bc41103debcae72f37 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 23 Oct 2020 17:17:59 -0700 Subject: [PATCH 6/6] website: Update the CLI commands index page for latest help output My initial motivation here was to update the example output from Terraform's top-level help list to match recent updates in the layout and language used. However, while here I took the opportunity to update some dated language that was not consistent with our modern documentation writing style, in particular including a totally unnecessary and potentially-alienating claim that Terraform is "very easy to use". Our modern writing style discourages this sort of "boastful" language and encourages us to focus on the facts at hand. --- commands.go | 2 +- website/docs/commands/index.html.markdown | 111 ++++++++++------------ 2 files changed, 53 insertions(+), 60 deletions(-) diff --git a/commands.go b/commands.go index 43bcf60fdc..dd6010ce10 100644 --- a/commands.go +++ b/commands.go @@ -105,7 +105,7 @@ func initCommands( // The command list is included in the terraform -help // output, which is in turn included in the docs at - // website/source/docs/commands/index.html.markdown; if you + // website/docs/commands/index.html.markdown; if you // add, remove or reclassify commands then consider updating // that to match. diff --git a/website/docs/commands/index.html.markdown b/website/docs/commands/index.html.markdown index 4617ebb617..2f8ee2a4e2 100644 --- a/website/docs/commands/index.html.markdown +++ b/website/docs/commands/index.html.markdown @@ -3,86 +3,79 @@ layout: "docs" page_title: "Commands" sidebar_current: "docs-commands" description: |- - Terraform is controlled via a very easy to use command-line interface (CLI). Terraform is only a single command-line application: terraform. This application then takes a subcommand such as "apply" or "plan". The complete list of subcommands is in the navigation to the left. + Main usage information for the Terraform CLI tool. --- # Terraform Commands (CLI) > **Hands-on:** Try the [Terraform: Get Started](https://learn.hashicorp.com/collections/terraform/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) collection on HashiCorp Learn. -Terraform is controlled via a very easy to use command-line interface (CLI). -Terraform is only a single command-line application: terraform. This application -then takes a subcommand such as "apply" or "plan". The complete list of subcommands -is in the navigation to the left. +The command line interface to Terraform is via the `terraform` command, which +accepts a variety of subcommands such as `terraform init` or `terraform plan`. +A full list of all of the supported subcommands is in the navigation section +of this page. -The terraform CLI is a well-behaved command line application. In erroneous cases, -a non-zero exit status will be returned. It also responds to -h and --help as you'd -most likely expect. +We refer to the `terraform` command line tool as "Terraform CLI" elsewhere +in the documentation. This terminology is often used to distinguish it from +other components you might use in the Terraform product family, such as +[Terraform Cloud](/docs/cloud/) or +the various [Terraform providers](/docs/providers/), which are developed and +released separately from Terraform CLI. -To view a list of the available commands at any time, just run terraform with no arguments: +To view a list of the commands available in your current Terraform version, +run `terraform` with no additional arguments: ```text Usage: terraform [global options] [args] The available commands for execution are listed below. -The most common, useful commands are shown first, followed by -less common or more advanced commands. If you're just getting -started with Terraform, stick with the common commands. For the -other commands, please read the help and docs before usage. - -Common commands: - apply Builds or changes infrastructure - console Interactive console for Terraform interpolations - destroy Destroy Terraform-managed infrastructure - env Workspace management - fmt Rewrites config files to canonical format - get Download and install modules for the configuration - graph Create a visual graph of Terraform resources - import Import existing infrastructure into Terraform - init Initialize a Terraform working directory - login Obtain and save credentials for a remote host - logout Remove locally-stored credentials for a remote host - output Read an output from a state file - plan Generate and show an execution plan - providers Prints a tree of the providers used in the configuration - refresh Update local state file against real resources - show Inspect Terraform state or plan - taint Manually mark a resource for recreation - untaint Manually unmark a resource as tainted - validate Validates the Terraform files - version Prints the Terraform version - workspace Workspace management +The primary workflow commands are given first, followed by +less common or more advanced commands. -All other commands: - debug Debug output management (experimental) - force-unlock Manually unlock the terraform state - state Advanced state management +Main commands: + init Prepare your working directory for other commands + validate Check whether the configuration is valid + plan Show changes required by the current configuration + apply Create or update infrastructure + destroy Destroy previously-created infrastructure +All other commands: + console Try Terraform expressions at an interactive command prompt + fmt Reformat your configuration in the standard style + force-unlock Release a stuck lock on the current workspace + get Install or upgrade remote Terraform modules + graph Generate a Graphviz graph of the steps in an operation + import Associate existing infrastructure with a Terraform resource + login Obtain and save credentials for a remote host + logout Remove locally-stored credentials for a remote host + output Show output values from your root module + providers Show the providers required for this configuration + refresh Update the state to match remote systems + show Show the current state or a saved plan + state Advanced state management + taint Mark a resource instance as not fully functional + untaint Remove the 'tainted' state from a resource instance + version Show the current Terraform version + workspace Workspace management Global options (use these before the subcommand, if any): - -chdir=DIR Switch to a different working directory before executing - the given subcommand. - -help Show this help output, or the help for a specified - subcommand. - -version An alias for the "version" subcommand. + -chdir=DIR Switch to a different working directory before executing the + given subcommand. + -help Show this help output, or the help for a specified subcommand. + -version An alias for the "version" subcommand. ``` -To get help for any specific command, use the -help option to the relevant -subcommand. For example, to see help about the graph subcommand: +(The output from your current Terraform version may be different than the +above example.) -```text -$ terraform graph -help -Usage: terraform graph [options] PATH +To get specific help for any specific command, use the `-help` option with the +relevant subcommand. For example, to see help about the "validate" subcommand +you can run `terraform validate -help`. - Outputs the visual graph of Terraform resources. If the path given is - the path to a configuration, the dependency graph of the resources are - shown. If the path is a plan file, then the dependency graph of the - plan itself is shown. - - The graph is outputted in DOT format. The typical program that can - read this format is GraphViz, but many web services are also available - to read this format. -``` +The inline help built in to Terraform CLI describes the most important +characteristics of each command. For more detailed information, refer to each +command's section of this documentation, available in the navigation +section of this page. ## Switching working directory with `-chdir`