Merge pull request #292 from nhooyr/autofmt-f0d3

d2format: Expose in CLI under fmt subcommand
This commit is contained in:
Anmol Sethi 2022-12-01 09:52:30 -08:00 committed by GitHub
commit 0cb71095b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 78 additions and 19 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@
*.got.json *.got.json
*.got.svg *.got.svg
e2e_report.html e2e_report.html
bin

7
ci/dev.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh
set -eu
cd -- "$(dirname "$0")/.."
. ./ci/sub/lib.sh
sh_c go build --tags=dev -o=bin/d2 .
sh_c ./bin/d2 "$@"

View file

@ -1,5 +1,7 @@
#### Features 🚀 #### Features 🚀
- Formatting of d2 scripts is supported on the CLI with the `fmt` subcommand.
[#292](https://github.com/terrastruct/d2/pull/292)
- Latex is now supported. See [docs](https://d2lang.com/tour/text) for more. - Latex is now supported. See [docs](https://d2lang.com/tour/text) for more.
[#229](https://github.com/terrastruct/d2/pull/229) [#229](https://github.com/terrastruct/d2/pull/229)
- `direction` keyword is now supported to specify `up`, `down`, `right`, `left` layouts. See - `direction` keyword is now supported to specify `up`, `down`, `right`, `left` layouts. See

View file

@ -12,6 +12,8 @@
.Op Ar file.svg | file.png .Op Ar file.svg | file.png
.Nm d2 .Nm d2
.Ar layout Op Ar name .Ar layout Op Ar name
.Nm d2
.Ar fmt Ar file.d2
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
compiles and renders compiles and renders
@ -75,6 +77,10 @@ Print version information and exit.
Lists available layout engine options with short help. Lists available layout engine options with short help.
.It Ar layout Op Ar name .It Ar layout Op Ar name
Display long help for a particular layout engine. Display long help for a particular layout engine.
.It Ar fmt Ar file.d2
Format
.Ar file.d2
.Ns .
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr d2plugin-tala 1 .Xr d2plugin-tala 1

2
ci/sub

@ -1 +1 @@
Subproject commit 702b771228f41e5485b5f3f593ce79f6efcb555d Subproject commit a39a678570a0454d6bf63f9012fb5ec107e24df5

36
fmt.go Normal file
View file

@ -0,0 +1,36 @@
package main
import (
"bytes"
"context"
"oss.terrastruct.com/xdefer"
"oss.terrastruct.com/d2/d2format"
"oss.terrastruct.com/d2/d2parser"
"oss.terrastruct.com/d2/lib/xmain"
)
func fmtCmd(ctx context.Context, ms *xmain.State) (err error) {
defer xdefer.Errorf(&err, "failed to fmt")
ms.Opts = xmain.NewOpts(ms.Env, ms.Log, ms.Opts.Flags.Args()[1:])
if len(ms.Opts.Args) == 0 {
return xmain.UsageErrorf("fmt must be passed the file to be formatted")
} else if len(ms.Opts.Args) > 1 {
return xmain.UsageErrorf("fmt accepts only one argument for the file to be formatted")
}
inputPath := ms.Opts.Args[0]
input, err := ms.ReadPath(inputPath)
if err != nil {
return err
}
m, err := d2parser.Parse(inputPath, bytes.NewReader(input), nil)
if err != nil {
return err
}
return ms.WritePath(inputPath, []byte(d2format.Format(m)))
}

11
help.go
View file

@ -15,7 +15,9 @@ import (
func help(ms *xmain.State) { func help(ms *xmain.State) {
fmt.Fprintf(ms.Stdout, `Usage: fmt.Fprintf(ms.Stdout, `Usage:
%s [--watch=false] [--theme=0] file.d2 [file.svg | file.png] %[1]s [--watch=false] [--theme=0] file.d2 [file.svg | file.png]
%[1]s layout [name]
%[1]s fmt 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.
@ -29,13 +31,14 @@ Flags:
Subcommands: Subcommands:
%[1]s layout - Lists available layout engine options with short help %[1]s layout - Lists available layout engine options with short help
%[1]s layout [layout name] - Display long help for a particular layout engine %[1]s layout [name] - Display long help for a particular layout engine
%[1]s fmt file.d2 - Format 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
`, ms.Name, ms.Opts.Defaults()) `, filepath.Base(ms.Name), ms.Opts.Defaults())
} }
func layoutHelp(ctx context.Context, ms *xmain.State) error { func layoutCmd(ctx context.Context, ms *xmain.State) error {
if len(ms.Opts.Flags.Args()) == 1 { if len(ms.Opts.Flags.Args()) == 1 {
return shortLayoutHelp(ctx, ms) return shortLayoutHelp(ctx, ms)
} else if len(ms.Opts.Flags.Args()) == 2 { } else if len(ms.Opts.Flags.Args()) == 2 {

View file

@ -66,10 +66,10 @@ func Main(run RunFunc) {
} }
if msg != "" { if msg != "" {
if usage {
msg = fmt.Sprintf("%s\n%s", msg, "Run with --help to see usage.")
}
ms.Log.Error.Print(msg) ms.Log.Error.Print(msg)
if usage {
ms.Log.Error.Print("Run with --help to see usage.")
}
} }
os.Exit(code) os.Exit(code)
} }

26
main.go
View file

@ -65,18 +65,26 @@ func run(ctx context.Context, ms *xmain.State) (err error) {
return xmain.UsageErrorf("failed to parse flags: %v", err) return xmain.UsageErrorf("failed to parse flags: %v", err)
} }
if len(ms.Opts.Flags.Args()) > 0 {
switch ms.Opts.Flags.Arg(0) {
case "layout":
return layoutHelp(ctx, ms)
}
}
if errors.Is(err, pflag.ErrHelp) { if errors.Is(err, pflag.ErrHelp) {
help(ms) help(ms)
return nil return nil
} }
if len(ms.Opts.Flags.Args()) > 0 {
switch ms.Opts.Flags.Arg(0) {
case "layout":
return layoutCmd(ctx, ms)
case "fmt":
return fmtCmd(ctx, ms)
case "version":
if len(ms.Opts.Flags.Args()) > 1 {
return xmain.UsageErrorf("version subcommand accepts no arguments")
}
fmt.Println(version.Version)
return nil
}
}
if *debugFlag { if *debugFlag {
ms.Env.Setenv("DEBUG", "1") ms.Env.Setenv("DEBUG", "1")
} }
@ -96,10 +104,6 @@ func run(ctx context.Context, ms *xmain.State) (err error) {
} }
if len(ms.Opts.Flags.Args()) >= 1 { if len(ms.Opts.Flags.Args()) >= 1 {
if ms.Opts.Flags.Arg(0) == "version" {
fmt.Println(version.Version)
return nil
}
inputPath = ms.Opts.Flags.Arg(0) inputPath = ms.Opts.Flags.Arg(0)
} }
if len(ms.Opts.Flags.Args()) >= 2 { if len(ms.Opts.Flags.Args()) >= 2 {