Skip to content
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

cli: Implement d2 fmt --check #2253

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/release/changelogs/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Connections now support `link` [#1955](https://github.com/terrastruct/d2/pull/1955)
- Vars: vars in markdown blocks are substituted [#2218](https://github.com/terrastruct/d2/pull/2218)
- Markdown: Github-flavored tables work in `md` blocks [#2221](https://github.com/terrastruct/d2/pull/2221)
- `d2 fmt` now supports a `--check` flag [#2253](https://github.com/terrastruct/d2/pull/2253)

#### Improvements 🧹

Expand Down
5 changes: 5 additions & 0 deletions ci/release/template/man/d2.1
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ In watch mode, images used in icons are cached for subsequent compilations. This
.It Fl -timeout Ar 120
The maximum number of seconds that D2 runs for before timing out and exiting. When rendering a large diagram, it is recommended to increase this value
.Ns .
.It Fl -check Ar false
Check that the specified files are formatted correctly
.Ns .
.It Fl h , -help
Print usage information and exit
.Ns .
Expand Down Expand Up @@ -180,6 +183,8 @@ See --font-semibold flag.
See --animate-interval flag.
.It Ev Sy D2_TIMEOUT
See --timeout flag.
.It Ev Sy D2_CHECK
See --check flag.
.El
.Bl -tag -width Ds
.It Ev Sy DEBUG
Expand Down
24 changes: 21 additions & 3 deletions d2cli/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@ import (

"oss.terrastruct.com/d2/d2format"
"oss.terrastruct.com/d2/d2parser"
"oss.terrastruct.com/d2/lib/log"
)

func fmtCmd(ctx context.Context, ms *xmain.State) (err error) {
func fmtCmd(ctx context.Context, ms *xmain.State, check bool) (err error) {
defer xdefer.Errorf(&err, "failed to fmt")

ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:])
if len(ms.Opts.Args) == 0 {
return xmain.UsageErrorf("fmt must be passed at least one file to be formatted")
}

unformattedCount := 0

for _, inputPath := range ms.Opts.Args {
if inputPath != "-" {
inputPath = ms.AbsPath(inputPath)
Expand All @@ -43,10 +46,25 @@ func fmtCmd(ctx context.Context, ms *xmain.State) (err error) {

output := []byte(d2format.Format(m))
if !bytes.Equal(output, input) {
if err := ms.WritePath(inputPath, output); err != nil {
return err
if check {
unformattedCount += 1
log.Warn(ctx, inputPath)
} else {
if err := ms.WritePath(inputPath, output); err != nil {
return err
}
}
}
}

if unformattedCount > 0 {
pluralFiles := "file"
if unformattedCount > 1 {
pluralFiles = "files"
}

return xmain.ExitErrorf(1, "found %d unformatted %s. Run d2 fmt to fix.", unformattedCount, pluralFiles)
}

return nil
}
7 changes: 6 additions & 1 deletion d2cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
fontBoldFlag := ms.Opts.String("D2_FONT_BOLD", "font-bold", "", "", "path to .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used.")
fontSemiboldFlag := ms.Opts.String("D2_FONT_SEMIBOLD", "font-semibold", "", "", "path to .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used.")

checkFlag, err := ms.Opts.Bool("D2_CHECK", "check", "", false, "check that the specified files are formatted correctly.")
if err != nil {
return err
}

plugins, err := d2plugin.ListPlugins(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -153,7 +158,7 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
themesCmd(ctx, ms)
return nil
case "fmt":
return fmtCmd(ctx, ms)
return fmtCmd(ctx, ms, *checkFlag)
case "version":
if len(ms.Opts.Flags.Args()) > 1 {
return xmain.UsageErrorf("version subcommand accepts no arguments")
Expand Down
23 changes: 23 additions & 0 deletions e2etests-cli/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,29 @@ layers: {
assert.Equal(t, "x -> y\n", string(gotBar))
},
},
{
name: "fmt-check-unformatted",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "foo.d2", `a ---> b`)
writeFile(t, dir, "bar.d2", `x ---> y`)
writeFile(t, dir, "baz.d2", "a -> z\n")
err := runTestMainPersist(t, ctx, dir, env, "fmt", "--check", "foo.d2", "bar.d2", "baz.d2")
assert.ErrorString(t, err, "failed to wait xmain test: e2etests-cli/d2: failed to fmt: exiting with code 1: found 2 unformatted files. Run d2 fmt to fix.")
gotFoo := readFile(t, dir, "foo.d2")
gotBar := readFile(t, dir, "bar.d2")
assert.Equal(t, "a ---> b", string(gotFoo))
assert.Equal(t, "x ---> y", string(gotBar))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you extend this to have d2 fmt --check run on formatted files?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7cb58fc. I added a formatted file to this first test case, and also added another one where all the files are already formatted correctly.

},
},
{
name: "fmt-check-formatted",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "foo.d2", "a -> b\n")
writeFile(t, dir, "bar.d2", "x -> y\n")
err := runTestMainPersist(t, ctx, dir, env, "fmt", "--check", "foo.d2", "bar.d2")
assert.Success(t, err)
},
},
{
name: "watch-regular",
serial: true,
Expand Down