Skip to content

Commit

Permalink
Add actionable error codes (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
gdavison authored Sep 13, 2020
1 parent 5156fd0 commit eb2190a
Show file tree
Hide file tree
Showing 11 changed files with 532 additions and 596 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ Use the `upgrade012` command to upgrade the blocks to 0.12:

![fmt](_docs/upgrade.png)

### Exit codes

To help usage of `terrafmt` in workflows, some commands will return actionable exit codes.

If a Terraform parsing error is encountered in a block, the exit code is `2`.

If the command `diff` with the `--check` flag enabled encounters a formatting difference, it will return `4`. If a file contains both blocks with parsing errors and a formatting difference, it will combine the exit codes to return `6`. These codes can be tested using bitwise checks.

Otherwise, `terrafmt` will return `1` on an error.

## Development and Testing

This project uses [Go Modules](https://github.com/golang/go/wiki/Modules) for dependency management.
Expand Down
47 changes: 43 additions & 4 deletions cli/blocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type block struct {
text string
}

var testcases = []struct {
var blocksTestcases = []struct {
name string
sourcefile string
lineCount int
Expand Down Expand Up @@ -104,6 +104,45 @@ var testcases = []struct {
bucket = "tf-test-bucket-extra-space-%d"
%s
}`,
},
},
},
{
name: "Go bad terraform",
sourcefile: "testdata/bad_terraform.go",
lineCount: 20,
expectedBlocks: []block{
{
endLine: 12,
text: `rrrrrresource "aws_s3_bucket" "rrrrrrr" {
bucket = "tf-test-bucket"
}`,
},
{
endLine: 19,
text: `resource "aws_s3_bucket" "unclosed" {
bucket = "tf-test-bucket"`,
},
},
},
{
name: "Go unsupported format verbs",
sourcefile: "testdata/unsupported_fmt.go",
lineCount: 21,
expectedBlocks: []block{
{
endLine: 20,
text: `resource "aws_s3_bucket" "multi-verb" {
bucket = "tf-test-bucket"
tags = {
%[1]q = %[2]q
Test = "${%[5]s.name}"
Name = "${%s.name}"
byte = "${aws_acm_certificate.test.*.arn[%[2]d]}"
Data = "${data.%s.name}"
}
}`,
},
},
Expand Down Expand Up @@ -171,7 +210,7 @@ var testcases = []struct {
func TestCmdBlocksDefault(t *testing.T) {
t.Parallel()

for _, testcase := range testcases {
for _, testcase := range blocksTestcases {
testcase := testcase
t.Run(testcase.name, func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -210,7 +249,7 @@ func TestCmdBlocksDefault(t *testing.T) {
func TestCmdBlocksVerbose(t *testing.T) {
t.Parallel()

for _, testcase := range testcases {
for _, testcase := range blocksTestcases {
testcase := testcase
t.Run(testcase.name, func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -239,7 +278,7 @@ func TestCmdBlocksVerbose(t *testing.T) {
func TestCmdBlocksZeroTerminated(t *testing.T) {
t.Parallel()

for _, testcase := range testcases {
for _, testcase := range blocksTestcases {
t.Run(testcase.name, func(t *testing.T) {
t.Parallel()

Expand Down
36 changes: 19 additions & 17 deletions cli/cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ import (
"github.com/spf13/viper"
)

const (
ExitCodeNoError = 0
ExitCodeMiscError = 1
ExitCodeBlockParsingError = 1 << 1
ExitCodeFormattingDiffError = 1 << 2
)

func Make() *cobra.Command {
root := &cobra.Command{
Use: "terrafmt [fmt|diff|blocks|upgrade012]",
Expand Down Expand Up @@ -62,7 +69,7 @@ func Make() *cobra.Command {
verbose := viper.GetBool("verbose")

var errs *multierror.Error
var hasProcessingErrors bool
exitCode := ExitCodeNoError

for _, filename := range filenames {
br, err := formatFile(fs, log, filename, fmtCompat, fixFinishLines, verbose, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr())
Expand All @@ -72,14 +79,14 @@ func Make() *cobra.Command {
}

if br.ErrorBlocks > 0 {
hasProcessingErrors = true
exitCode |= ExitCodeBlockParsingError
}
}
if errs != nil {
return errs
}
if hasProcessingErrors {
os.Exit(1)
if exitCode != ExitCodeNoError {
os.Exit(exitCode)
}

return nil
Expand Down Expand Up @@ -112,9 +119,8 @@ func Make() *cobra.Command {
if err != nil {
return err
}

if br.ErrorBlocks > 0 {
os.Exit(-1)
os.Exit(ExitCodeBlockParsingError)
}

return nil
Expand Down Expand Up @@ -144,8 +150,8 @@ func Make() *cobra.Command {
}

var errs *multierror.Error
var hasDiff bool
var hasProcessingErrors bool
check := viper.GetBool("check")
exitCode := ExitCodeNoError

for _, filename := range filenames {
br, fileDiff, err := diffFile(fs, log, filename, viper.GetBool("fmtcompat"), viper.GetBool("verbose"), cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr())
Expand All @@ -154,21 +160,17 @@ func Make() *cobra.Command {
continue
}
if br.ErrorBlocks > 0 {
hasProcessingErrors = true
exitCode |= ExitCodeBlockParsingError
}
if fileDiff {
hasDiff = true
if check && fileDiff {
exitCode |= ExitCodeFormattingDiffError
}
}
if errs != nil {
return errs
}

if viper.GetBool("check") && hasDiff {
os.Exit(1)
}
if hasProcessingErrors {
os.Exit(1)
if exitCode != ExitCodeNoError {
os.Exit(exitCode)
}

return nil
Expand Down
Loading

0 comments on commit eb2190a

Please sign in to comment.