Commit Graph

17 Commits

Author SHA1 Message Date
Martin Atkins ff0dbd6215 command/fmt: Restore some opinionated behaviors
In Terraform 0.11 and earlier, the "terraform fmt" command was very
opinionated in the interests of consistency. While that remains its goal,
for pragmatic reasons Terraform 0.12 significantly reduced the number
of formatting behaviors in the fmt command. We've held off on introducing
0.12-and-later-flavored cleanups out of concern it would make it harder
to maintain modules that are cross-compatible with both Terraform 0.11
and 0.12, but with this aimed to land in 0.14 -- two major releases
later -- our new goal is to help those who find older Terraform language
examples learn about the more modern idiom.

More rules may follow later, now that the implementation is set up to
allow modifications to tokens as well as modifications to whitespace, but
for this initial pass the command will now apply the following formatting
conventions:

 - 0.11-style quoted variable type constraints will be replaced with their
   0.12 syntax equivalents. For example, "string" becomes just string.
   (This change quiets a deprecation warning.)
 - Collection type constraints that don't specify an element type will
   be rewritten to specify the "any" element type explicitly, so
   list becomes list(any).
 - Arguments whose expressions consist of a quoted string template with
   only a single interpolation sequence inside will be "unwrapped" to be
   the naked expression instead, which is functionally equivalent.
   (This change quiets a deprecation warning.)
 - Block labels are given in quotes.

Two of the rules above are coming from a secondary motivation of
continuing down the deprecation path for two existing warnings, so authors
can have two active deprecation warnings quieted automatically by
"terraform fmt", without the need to run any third-party tools.

All of these rules match with current documented idiom as shown in the
Terraform documentation, so anyone who follows the documented style should
see no changes as a result of this. Those who have adopted other local
style will see their configuration files rewritten to the standard
Terraform style, but it should not make any changes that affect the
functionality of the configuration.

There are some further similar rewriting rules that could be added in
future, such as removing 0.11-style quotes around various keyword or
static reference arguments, but this initial pass focused only on some
rules that have been proven out in the third-party tool
terraform-clean-syntax, from which much of this commit is a direct port.

For now this doesn't attempt to re-introduce any rules about vertical
whitespace, even though the 0.11 "terraform fmt" would previously apply
such changes. We'll be more cautious about those because the results of
those rules in Terraform 0.11 were often sub-optimal and so we'd prefer
to re-introduce those with some care to the implications for those who
may be using vertical formatting differences for some semantic purpose,
like grouping together related arguments.
2020-09-28 09:04:03 -07:00
Alisdair McDiarmid 206e2e6d6a command/fmt: Include source snippets in errors
Previously, diagnostic errors would display the filename and line
number, along with "(source code not available)". This is because the
fmt command directly loads and parses the configuration, instead of
using the config loader.

This commit registers the manually parsed source as a synthetic
configuration file, so that the diagnostic formatter can look up the
source for the range with the error and display it.
2020-03-26 14:00:26 -04:00
Pam Selle 82dcd5276e Normalize in the fmt -check test 2019-06-18 17:15:59 -04:00
Martin Atkins 176a5abfd3 command: Restore single-file support in "terraform fmt"
This possibility was lost in the rewrite to use HCL2, but it's used by
a number of external utilities and text editor integrations, so we'll
restore it here.

Using the stdin/stdout mode is generally preferable for text editor use
since it allows formatting of the in-memory buffer rather than directly
the file on disk, but for editors that don't have support for that sort of
tooling it can be convenient to just launch a single command and directly
modify the on-disk file.
2019-01-17 14:21:18 -08:00
Martin Atkins b0a43cab84 command: "terraform fmt" must fail if file has invalid syntax
Since the HCL formatter only works with tokens, it can in principle be
called with any input and produce some output. However, when given invalid
syntax it will tend to produce nonsensical results that may drastically
change the input file and be hard for the user to undo.

Since there's no strong reason to try to format an invalid or incomplete
file, we'll instead try parsing first and fail if parsing does not
complete successfully.

Since we talk directly to the HCL API here this is only a _syntax_ check,
and so it can be applied to files that are invalid in other ways as far
as Terraform is concerned, such as using unsupported top-level block types,
resource types that don't exist, etc.
2019-01-17 14:21:18 -08:00
Martin Atkins c0baedac84 command: Fix tests for "terraform fmt" command
Some underlying assumptions have shifted here, so although the behavior
is still broadly the same we need to accommodate some different details.
2018-10-16 19:14:11 -07:00
James Bardin e980156451 cleanup temp files from command tests
Rather than try to modify all the hundreds of calls to the temp helper
functions, and cleanup the temp files at every call site, have all tests
work within a single temp directory that is removed at the end of
TestMain.
2018-03-28 13:08:38 -04:00
Kyle McCullough ad896b65c9
command: add -check flag to fmt (#15304) 2017-07-21 14:37:15 -05:00
Martin Atkins 8364383c35 Push plugin discovery down into command package
Previously we did plugin discovery in the main package, but as we move
towards versioned plugins we need more information available in order to
resolve plugins, so we move this responsibility into the command package
itself.

For the moment this is just preserving the existing behavior as long as
there are only internal and unversioned plugins present. This is the
final state for provisioners in 0.10, since we don't want to support
versioned provisioners yet. For providers this is just a checkpoint along
the way, since further work is required to apply version constraints from
configuration and support additional plugin search directories.

The automatic plugin discovery behavior is not desirable for tests because
we want to mock the plugins there, so we add a new backdoor for the tests
to use to skip the plugin discovery and just provide their own mock
implementations. Most of this diff is thus noisy rework of the tests to
use this new mechanism.
2017-06-09 14:03:59 -07:00
Paul Hinze c74c5fe7f0
Update HCL to latest, unskip fmt tests
See https://github.com/hashicorp/hcl/pull/115
2016-04-27 07:37:47 -05:00
Paul Hinze ac10a7979d
command/fmt tests: temporarily skip newline failures
Skipping tests to get the master build green while I sort out these
failing tests.

They should be fixed for real in just a few here.
2016-04-26 15:26:16 -05:00
Dan Carley d883b76070 command/fmt: Test non-default options
To ensure that these are passed over to `fmtcmd` correctly.
2016-03-07 15:07:15 +00:00
Dan Carley 79e2753e41 command/fmt: Disable list/write when using STDIN
These options don't make sense when passing STDIN. `-write` will raise an
error because there is no file to write to. `-list` will always say
`<standard input>`. So disable whenever using STDIN, making the command
much simpler:

    cat main.tf | terraform fmt -
2016-03-07 15:07:15 +00:00
Dan Carley e9128769b5 command/fmt: Accept input from STDIN
So that you can do automatic formatting from an editor. You probably want to
disable the `-write` and `-list` options so that you just get the
re-formatted content, e.g.

    cat main.tf | terraform fmt -write=false -list=false -

I've added a non-exported field called `input` so that we can override this
for the tests. If not specified, like in `commands.go`, then it will default
to `os.Stdin` which works on the command line.
2016-03-07 15:07:15 +00:00
Dan Carley 1b967e612f command/fmt: Accept optional directory argument
So that you can operate on files in a directory other than your current
working directory.
2016-03-07 15:07:14 +00:00
Dan Carley c753390399 command/fmt: Default write and list to true
The most common usage usage will be enabling the `-write` and `-list`
options so that files are updated in place and a list of any modified files
is printed. This matches the default behaviour of `go fmt` (not `gofmt`). So
enable these options by default.

This does mean that you will have to explicitly disable these if you want to
generate valid patches, e.g. `terraform fmt -diff -write=false -list=false`
2016-03-07 15:07:14 +00:00
Dan Carley cc41c7cfa0 command/fmt: Add new fmt command
This uses the `fmtcmd` package which has recently been merged into HCL. Per
the usage text, this rewrites Terraform config files to their canonical
formatting and style.

Some notes about the implementation for this initial commit:

- all of the fmtcmd options are exposed as CLI flags
- it operates on all files that have a `.tf` suffix
- it currently only operates on the working directory and doesn't accept a
  directory argument, but I'll extend this in subsequent commits
- output is proxied through `cli.UiWriter` so that we write in the same way
  as other commands and we can capture the output during tests
- the test uses a very simple fixture just to ensure that it is working
  correctly end-to-end; the fmtcmd package has more exhaustive tests
- we have to write the fixture to a file in a temporary directory because it
  will be modified and for this reason it was easier to define the fixture
  contents as a raw string
2016-03-07 15:07:04 +00:00