Skip to content

Commit

Permalink
cmd/cue: add a fmt --check flag to list badly formatted files
Browse files Browse the repository at this point in the history
Adds a --check flag that will cause cue to fail with exit code 1
in case any files require formatting. A list of non formatted files
will be displayed, line by line, to stdout.

Also, a typo is fixed in cue/ast/ast.go.

fixes #363.

Change-Id: I27c8e9b18bb01f981cd061a23ee3323bc403c9a9
Signed-off-by: Noam Dolovich <noam.tzvi.dolovich@gmail.com>
  • Loading branch information
NoamTD committed Mar 31, 2024
1 parent 2887786 commit 3b0fe86
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 2 deletions.
42 changes: 41 additions & 1 deletion cmd/cue/cmd/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
package cmd

import (
"bytes"
"cuelang.org/go/internal/source"
"fmt"
"github.com/spf13/cobra"
"os"

"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/build"
Expand Down Expand Up @@ -56,6 +60,9 @@ func newFmtCmd(c *Command) *cobra.Command {
cfg.Format = opts
cfg.Force = true

check := flagCheck.Bool(cmd)
var badlyFormattedFiles []string

for _, inst := range builds {
if inst.Err != nil {
switch {
Expand All @@ -67,7 +74,21 @@ func newFmtCmd(c *Command) *cobra.Command {
}
}
for _, file := range inst.BuildFiles {
files := []*ast.File{}
// When using --check, we need to buffer the input and output bytes to compare them.
var original []byte
var formatted bytes.Buffer
if check {
if bs, ok := file.Source.([]byte); ok {
original = bs
} else {
original, err = source.ReadAll(file.Filename, file.Source)
exitOnErr(cmd, err, true)
file.Source = original
}
cfg.Out = &formatted
}

var files []*ast.File
d := encoding.NewDecoder(file, &cfg)
for ; !d.Done(); d.Next() {
f := d.File()
Expand All @@ -93,13 +114,32 @@ func newFmtCmd(c *Command) *cobra.Command {
err := e.EncodeFile(f)
exitOnErr(cmd, err, false)
}

if err := e.Close(); err != nil {
exitOnErr(cmd, err, true)
}

if check && !bytes.Equal(formatted.Bytes(), original) {
badlyFormattedFiles = append(badlyFormattedFiles, file.Filename)
}
}
}

if check && len(badlyFormattedFiles) > 0 {
stdout := cmd.OutOrStdout()
for _, f := range badlyFormattedFiles {
if f != "-" {
fmt.Fprintln(stdout, f)
}
}
os.Exit(1)
}

return nil
}),
}

cmd.Flags().Bool(string(flagCheck), false, "exits with non-zero status if any files are not formatted")

return cmd
}
30 changes: 30 additions & 0 deletions cmd/cue/cmd/testdata/script/fmt_check.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# succeeds when file is formatted
exec cue fmt --check formatted.cue

stdin formatted.cue
exec cue fmt --check -

# fails and displays non formatted files
! exec cue fmt --check not_formatted.cue another_not_formatted.cue
cmpenv stdout expected-output

# files are not modified with --check
# running twice returns the same file list
! exec cue fmt --check not_formatted.cue another_not_formatted.cue
cmpenv stdout expected-output

# stdin fails with no output
stdin not_formatted.cue
! exec cue fmt --check -
! stdout .

-- formatted.cue --
foo: "bar"
-- not_formatted.cue --
foo: "bar"
-- another_not_formatted.cue --
bar: "baz"
x: 1
-- expected-output --
$WORK${/}another_not_formatted.cue
$WORK${/}not_formatted.cue
2 changes: 1 addition & 1 deletion cue/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ func (d *EmbedDecl) End() token.Pos { return d.Expr.End() }
// ----------------------------------------------------------------------------
// Files and packages

// A File node represents a Go source file.
// A File node represents a CUE source file.
//
// The Comments list contains all comments in the source file in order of
// appearance, including the comments that are pointed to from other nodes
Expand Down

0 comments on commit 3b0fe86

Please sign in to comment.