Skip to content

Commit

Permalink
cmd/action: multi path support for fmt (#496)
Browse files Browse the repository at this point in the history
  • Loading branch information
rotemtam authored Jan 26, 2022
1 parent 4210db9 commit 75dbe55
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 30 deletions.
14 changes: 9 additions & 5 deletions cmd/action/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ Unless stated otherwise, the fmt command will use the current directory.
After running, the command will print the names of the files it has formatted. If all
files in the directory are formatted, no input will be printed out.
`,
Run: CmdFmtRun,
Args: cobra.MaximumNArgs(1),
Run: CmdFmtRun,
}
)

Expand All @@ -40,10 +39,15 @@ func init() {
// CmdFmtRun formats all HCL files in a given directory using canonical HCL formatting
// rules.
func CmdFmtRun(cmd *cobra.Command, args []string) {
path := "./"
if len(args) > 0 {
path = args[0]
if len(args) == 0 {
args = append(args, "./")
}
for _, path := range args {
handlePath(cmd, path)
}
}

func handlePath(cmd *cobra.Command, path string) {
tasks, err := tasks(path)
cobra.CheckErr(err)
for _, task := range tasks {
Expand Down
120 changes: 95 additions & 25 deletions cmd/action/fmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package action

import (
"bytes"
"io/ioutil"
"os"
"path"
"path/filepath"
Expand All @@ -30,49 +31,118 @@ const (
func TestFmt(t *testing.T) {
for _, tt := range []struct {
name string
input string
inputDir map[string]string
expectedDir map[string]string
expectedFile string
expectedOut string
args []string
expectedPrint bool
}{
{
name: "unformatted",
input: unformatted,
expectedFile: formatted,
expectedPrint: true,
name: "specific file",
inputDir: map[string]string{
"test.hcl": unformatted,
},
expectedDir: map[string]string{
"test.hcl": formatted,
},
args: []string{"test.hcl"},
expectedOut: "test.hcl\n",
},
{
name: "formatted",
input: formatted,
expectedFile: formatted,
expectedPrint: false,
name: "current dir",
inputDir: map[string]string{
"test.hcl": unformatted,
},
expectedDir: map[string]string{
"test.hcl": formatted,
},
expectedOut: "test.hcl\n",
},
{
name: "multi path implicit",
inputDir: map[string]string{
"test.hcl": unformatted,
"test2.hcl": unformatted,
},
expectedDir: map[string]string{
"test.hcl": formatted,
"test2.hcl": formatted,
},
expectedOut: "test.hcl\ntest2.hcl\n",
},
{
name: "multi path explicit",
inputDir: map[string]string{
"test.hcl": unformatted,
"test2.hcl": unformatted,
},
expectedDir: map[string]string{
"test.hcl": formatted,
"test2.hcl": formatted,
},
args: []string{"test.hcl", "test2.hcl"},
expectedOut: "test.hcl\ntest2.hcl\n",
},
{
name: "formatted",
inputDir: map[string]string{
"test.hcl": formatted,
},
expectedDir: map[string]string{
"test.hcl": formatted,
},
},
} {
t.Run(tt.name, func(t *testing.T) {
var out bytes.Buffer
filename := "test.hcl"
dir := setupFmtTest(t, filename, tt.input)
FmtCmd.ResetCommands() // Detach from sub-commands and parents, needed to skip input validation done by them.
FmtCmd.SetOut(&out)
FmtCmd.SetArgs([]string{dir})
err := FmtCmd.Execute()
require.NoError(t, err)
require.Equal(t, tt.expectedPrint, out.Len() > 0)
rf, err := os.ReadFile(filepath.Join(dir, filename))
require.NoError(t, err)
require.Equal(t, tt.expectedFile, string(rf))
dir := setupFmtTest(t, tt.inputDir)
out := runFmt(t, tt.args)
assertDir(t, dir, tt.expectedDir)
require.EqualValues(t, tt.expectedOut, out)
})
}
}

func setupFmtTest(t *testing.T, filename, contents string) string {
func runFmt(t *testing.T, args []string) string {
var out bytes.Buffer
FmtCmd.ResetCommands() // Detach from sub-commands and parents, needed to skip input validation done by them.
FmtCmd.SetOut(&out)
FmtCmd.SetArgs(args)
err := FmtCmd.Execute()
require.NoError(t, err)
return out.String()
}

func assertDir(t *testing.T, dir string, expected map[string]string) {
act := make(map[string]string)
files, err := ioutil.ReadDir(dir)
require.NoError(t, err)
for _, f := range files {
if f.IsDir() {
continue
}
contents, err := os.ReadFile(filepath.Join(dir, f.Name()))
require.NoError(t, err)
act[f.Name()] = string(contents)
}
require.EqualValues(t, expected, act)
}

func setupFmtTest(t *testing.T, inputDir map[string]string) string {
wd, err := os.Getwd()
require.NoError(t, err)
dir, err := os.MkdirTemp(os.TempDir(), "fmt-test-")
require.NoError(t, err)
err = os.Chdir(dir)
require.NoError(t, err)
t.Cleanup(func() {
os.RemoveAll(dir)
os.Chdir(wd) //nolint:errcheck
})

file := path.Join(dir, filename)
err = os.WriteFile(file, []byte(contents), 0644)
for name, contents := range inputDir {
file := path.Join(dir, name)
err = os.WriteFile(file, []byte(contents), 0644)
}
require.NoError(t, err)
return dir
}

0 comments on commit 75dbe55

Please sign in to comment.