New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add terramate fmt #351
Conversation
Codecov Report
@@ Coverage Diff @@
## main #351 +/- ##
==========================================
- Coverage 67.77% 67.76% -0.02%
==========================================
Files 36 37 +1
Lines 6685 6844 +159
==========================================
+ Hits 4531 4638 +107
- Misses 1903 1952 +49
- Partials 251 254 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
tcases := []testcase{ | ||
{ | ||
name: "attributes alignment", | ||
input: ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when we start adding extra formatting features the idea is to add more test cases here
@@ -92,13 +90,9 @@ func FuzzPartialEval(f *testing.F) { | |||
|
|||
const testattr = "attr" | |||
|
|||
cfg := hcldoc( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now hclwriter always produces valid HCL, so if you use it to build invalid HCL files it panics, seemed like the way to go since it is what we want on 99% of the tests, we use it to build some valid HCL file for testing. But here we generate possibly invalid HCLs and that would cause panics, so it seemed easier to just create the HCL with a string since it is a pretty straithforward attr = val.
@@ -222,7 +222,11 @@ func NumberInt(name string, val int64) BlockBuilder { | |||
|
|||
// Format formats the given HCL code. | |||
func Format(code string) string { | |||
return strings.Trim(string(hclwrite.Format([]byte(code))), "\n ") | |||
formatted, err := hcl.Format(code, "gen.hcl") | |||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One alternative to assuming that only valid HCL is allowed when using the hclwrite builders would be to just skip formatting if the code is not valid HCL (or maybe falling back to hclwrite.Format that formats anything). But the alternative seems clumsy, overall I think we want to build valid HCL using the builders, so if because a bug it is not valid HCL it is desireable for the tests to fail fast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm but left minor ideas/questions.
cmd/terramate/cli/cli.go
Outdated
|
||
logger.Trace().Msg("listing formatted files") | ||
for _, res := range results { | ||
path := strings.TrimPrefix(res.Path(), c.wd()+"/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filepath.Separator?
We have the prj.FriendlyFmtDir()
but for formatting directories (we use them for stacks) and them they return directories relative to root. Maybe use this?
dir := prj.FriendlyFmtDir(c.root(), c.wd(), filepath.Dir(res.Path()))
path := filepath.Join(dir, filepath.Base(res.Path()))
but not sure, ignore if doesn't make sense haha
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Man I always forget about the filepath.Separator. I saw FriendlyFmtDir but as you mentioned it does something else and it seemed simpler to do just this (FriendlyFmtDir is more involved).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using filepath.Separator. Maybe we could use prj.FriendlyFmtDir()
but I'm not so sure 🤔
c.log(path) | ||
} | ||
|
||
if c.parsedArgs.Fmt.Check { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
top
|
||
wantedFiles := []string{ | ||
"globals.tm", | ||
"another-stacks/globals.tm.hcl", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add a test with --chdir
into the generated tree to check if the file paths are expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks for catching this (actually I was aware the tests were lacking and went into rush mode anyway, but it is good investment to improve that now, it didn't even take that long 😆 )
} | ||
|
||
const ( | ||
errFormatTree errors.Kind = "formatting tree" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we were placing this at the top in all other packages. Just curious why in the bottom in this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default I never placed any private symbols/constants at the top =P. I'm just used to first listing all public things and then later all private things. But can also put on the top for consistency (not a strong opinion).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are adding on the top all exported error sentinels/kinds etc. But this is just my default mode of organizing things, very personal, but I do make a distinction between a private vs public error sentinel, the private one can't even be used by caller for any checking, it is just to avoid duplication internally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah ok, all the others are public indeed.
Adds the
terramate fmt
command. It will by default format all files inside the current working dir + all subdirs recursively (the -recursive flag on terraform fmt). We can also runterramate fmt --check
, in that case it only checks if there are any files to be formatted and if there is any exits with 1, 0 otherwise.Both on
terramate fmt
andterramate fmt --check
the list of the files changed will be sent to stdout.Also changed all references to hclwrite.Format to use our own hcl.Format function, with some further changes on testing code since our hcl.Format only formats valid code, not anything =P