Merge pull request #2415 from melsonic/issue-2410

cli: add validate command
This commit is contained in:
Alexander Wang 2025-03-11 12:53:29 -07:00 committed by GitHub
commit 38851ef88d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 68 additions and 0 deletions

View file

@ -24,6 +24,9 @@
- Support relative imports. Improve elk error handling: [#2382](https://github.com/terrastruct/d2/pull/2382) - Support relative imports. Improve elk error handling: [#2382](https://github.com/terrastruct/d2/pull/2382)
- Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): [#2384](https://github.com/terrastruct/d2/pull/2384) - Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): [#2384](https://github.com/terrastruct/d2/pull/2384)
- d2cli:
- Support `validate` command. [#2415](https://github.com/terrastruct/d2/pull/2415)
#### Bugfixes ⛑️ #### Bugfixes ⛑️
- Compiler: - Compiler:

View file

@ -17,6 +17,8 @@
.Ar fmt Ar file.d2 ... .Ar fmt Ar file.d2 ...
.Nm d2 .Nm d2
.Ar play Ar file.d2 .Ar play Ar file.d2
.Nm d2
.Ar validate Ar file.d2
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
compiles and renders compiles and renders
@ -162,6 +164,8 @@ Lists available themes
Format all passed files Format all passed files
.It Ar play Ar file.d2 .It Ar play Ar file.d2
Opens the file in playground, an online web viewer (https://play.d2lang.com) Opens the file in playground, an online web viewer (https://play.d2lang.com)
.It Ar validate Ar file.d2
Validates file.d2
.El .El
.Sh ENVIRONMENT VARIABLES .Sh ENVIRONMENT VARIABLES
Many flags can also be set with environment variables. Many flags can also be set with environment variables.

View file

@ -23,6 +23,7 @@ Usage:
%[1]s layout [name] %[1]s layout [name]
%[1]s fmt file.d2 ... %[1]s fmt file.d2 ...
%[1]s play [--theme=0] [--sketch] file.d2 %[1]s play [--theme=0] [--sketch] file.d2
%[1]s validate file.d2
%[1]s compiles and renders file.d2 to file.svg | file.png %[1]s compiles and renders file.d2 to file.svg | file.png
It defaults to file.svg if an output path is not provided. It defaults to file.svg if an output path is not provided.
@ -40,6 +41,7 @@ Subcommands:
%[1]s themes - Lists available themes %[1]s themes - Lists available themes
%[1]s fmt file.d2 ... - Format passed files %[1]s fmt file.d2 ... - Format passed files
%[1]s play file.d2 - Opens the file in playground, an online web viewer (https://play.d2lang.com) %[1]s play file.d2 - Opens the file in playground, an online web viewer (https://play.d2lang.com)
%[1]s validate file.d2 - Validates file.d2
See more docs and the source code at https://oss.terrastruct.com/d2. See more docs and the source code at https://oss.terrastruct.com/d2.
Hosted icons at https://icons.terrastruct.com. Hosted icons at https://icons.terrastruct.com.

View file

@ -173,6 +173,8 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
return fmtCmd(ctx, ms, *checkFlag) return fmtCmd(ctx, ms, *checkFlag)
case "play": case "play":
return playCmd(ctx, ms) return playCmd(ctx, ms)
case "validate":
return validateCmd(ctx, ms)
case "version": case "version":
if len(ms.Opts.Flags.Args()) > 1 { if len(ms.Opts.Flags.Args()) > 1 {
return xmain.UsageErrorf("version subcommand accepts no arguments") return xmain.UsageErrorf("version subcommand accepts no arguments")

41
d2cli/validate.go Normal file
View file

@ -0,0 +1,41 @@
package d2cli
import (
"context"
"fmt"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/util-go/xdefer"
"oss.terrastruct.com/util-go/xmain"
)
func validateCmd(ctx context.Context, ms *xmain.State) (err error) {
defer xdefer.Errorf(&err, "")
ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:])
if len(ms.Opts.Args) == 0 {
return xmain.UsageErrorf("input argument required")
}
inputPath := ms.Opts.Args[0]
if inputPath != "-" {
inputPath = ms.AbsPath(inputPath)
}
input, err := ms.ReadPath(inputPath)
if err != nil {
return err
}
_, err = d2lib.Parse(ctx, string(input), nil)
if err != nil {
return err
}
if inputPath == "-" {
inputPath = "Input"
}
fmt.Printf("Success! [%s] is valid D2.\n", inputPath)
return nil
}

View file

@ -1346,6 +1346,22 @@ c
assert.Success(t, err) assert.Success(t, err)
}, },
}, },
{
name: "validate-against-correct-d2",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "correct.d2", `x -> y`)
err := runTestMainPersist(t, ctx, dir, env, "validate", "correct.d2")
assert.Success(t, err)
},
},
{
name: "validate-against-incorrect-d2",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "incorrect.d2", `x > y`)
err := runTestMainPersist(t, ctx, dir, env, "validate", "incorrect.d2")
assert.Error(t, err)
},
},
} }
ctx := context.Background() ctx := context.Background()