cli: Handle invalid board paths
This commit is contained in:
parent
7f9dcf78f8
commit
46bf849e2b
8 changed files with 91 additions and 5 deletions
|
|
@ -20,3 +20,4 @@
|
||||||
- Correctly reports errors from invalid values set by globs. [#1691](https://github.com/terrastruct/d2/pull/1691)
|
- Correctly reports errors from invalid values set by globs. [#1691](https://github.com/terrastruct/d2/pull/1691)
|
||||||
- Fixes panic when spread substitution referenced a nonexistant var. [#1695](https://github.com/terrastruct/d2/pull/1695)
|
- Fixes panic when spread substitution referenced a nonexistant var. [#1695](https://github.com/terrastruct/d2/pull/1695)
|
||||||
- Fixes incorrect appendix icon numbering. [#1704](https://github.com/terrastruct/d2/pull/1704)
|
- Fixes incorrect appendix icon numbering. [#1704](https://github.com/terrastruct/d2/pull/1704)
|
||||||
|
- Fixes crash when using `--watch` and navigating to an invalid board path [#1693](https://github.com/terrastruct/d2/pull/1693)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
func fmtCmd(ctx context.Context, ms *xmain.State) (err error) {
|
func fmtCmd(ctx context.Context, ms *xmain.State) (err error) {
|
||||||
defer xdefer.Errorf(&err, "failed to fmt")
|
defer xdefer.Errorf(&err, "failed to fmt")
|
||||||
|
|
||||||
ms.Opts = xmain.NewOpts(ms.Env, ms.Log, ms.Opts.Flags.Args()[1:])
|
ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:])
|
||||||
if len(ms.Opts.Args) == 0 {
|
if len(ms.Opts.Args) == 0 {
|
||||||
return xmain.UsageErrorf("fmt must be passed at least one file to be formatted")
|
return xmain.UsageErrorf("fmt must be passed at least one file to be formatted")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package d2cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -490,6 +491,8 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, la
|
||||||
default:
|
default:
|
||||||
compileDur := time.Since(start)
|
compileDur := time.Since(start)
|
||||||
if animateInterval <= 0 {
|
if animateInterval <= 0 {
|
||||||
|
b, _ := json.MarshalIndent(diagram, "", " ")
|
||||||
|
println("\033[1;31m--- DEBUG:", string(b), "\033[m")
|
||||||
// Rename all the "root.layers.x" to the paths that the boards get output to
|
// Rename all the "root.layers.x" to the paths that the boards get output to
|
||||||
linkToOutput, err := resolveLinks("root", outputPath, diagram)
|
linkToOutput, err := resolveLinks("root", outputPath, diagram)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -503,7 +506,7 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, la
|
||||||
|
|
||||||
board := diagram.GetBoard(boardPath)
|
board := diagram.GetBoard(boardPath)
|
||||||
if board == nil {
|
if board == nil {
|
||||||
return nil, false, fmt.Errorf("Diagram with path %s not found", boardPath)
|
return nil, false, fmt.Errorf(`Diagram with path "%s" not found. Did you mean to specify a board like "layers.%s"?`, boardPath, boardPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
boards, err := render(ctx, ms, compileDur, plugin, renderOpts, inputPath, outputPath, bundle, forceAppendix, page, ruler, board)
|
boards, err := render(ctx, ms, compileDur, plugin, renderOpts, inputPath, outputPath, bundle, forceAppendix, page, ruler, board)
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ func (p *dagrePlugin) HydrateOpts(opts []byte) error {
|
||||||
func (p *dagrePlugin) Info(ctx context.Context) (*PluginInfo, error) {
|
func (p *dagrePlugin) Info(ctx context.Context) (*PluginInfo, error) {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
opts := xmain.NewOpts(nil, nil, nil)
|
opts := xmain.NewOpts(nil, nil)
|
||||||
flags, err := p.Flags(ctx)
|
flags, err := p.Flags(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ func (p *elkPlugin) HydrateOpts(opts []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) {
|
func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) {
|
||||||
opts := xmain.NewOpts(nil, nil, nil)
|
opts := xmain.NewOpts(nil, nil)
|
||||||
flags, err := p.Flags(ctx)
|
flags, err := p.Flags(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,17 @@ package e2etests_cli
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"nhooyr.io/websocket"
|
||||||
"oss.terrastruct.com/util-go/assert"
|
"oss.terrastruct.com/util-go/assert"
|
||||||
"oss.terrastruct.com/util-go/diff"
|
"oss.terrastruct.com/util-go/diff"
|
||||||
"oss.terrastruct.com/util-go/xmain"
|
"oss.terrastruct.com/util-go/xmain"
|
||||||
|
|
@ -544,6 +549,77 @@ i used to read
|
||||||
assert.Equal(t, "x -> y\n", string(gotBar))
|
assert.Equal(t, "x -> y\n", string(gotBar))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "watch",
|
||||||
|
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
|
||||||
|
writeFile(t, dir, "index.d2", `
|
||||||
|
a -> b
|
||||||
|
b.link: cream
|
||||||
|
|
||||||
|
layers: {
|
||||||
|
cream: {
|
||||||
|
c -> b
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
stderr := &bytes.Buffer{}
|
||||||
|
tms := testMain(dir, env, "--watch", "--browser=0", "index.d2")
|
||||||
|
tms.Stderr = stderr
|
||||||
|
|
||||||
|
doneChan := make(chan struct{}, 1)
|
||||||
|
|
||||||
|
tms.Start(t, ctx)
|
||||||
|
defer tms.Cleanup(t)
|
||||||
|
|
||||||
|
go tms.Wait(ctx)
|
||||||
|
|
||||||
|
ticker := time.NewTicker(100 * time.Millisecond)
|
||||||
|
urlRE := regexp.MustCompile(`127.0.0.1:([0-9]+)`)
|
||||||
|
compiled := false
|
||||||
|
go func() {
|
||||||
|
var url string
|
||||||
|
for i := 0; i < 10 && url == ""; i++ {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
out := string(stderr.Bytes())
|
||||||
|
url = urlRE.FindString(out)
|
||||||
|
compiled, _ = regexp.MatchString(`failed to recompile`, out)
|
||||||
|
println("\033[1;31m--- DEBUG:", compiled, "\033[m")
|
||||||
|
case <-ctx.Done():
|
||||||
|
ticker.Stop()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if url != "" {
|
||||||
|
c, _, err := websocket.Dial(ctx, fmt.Sprintf("ws://%s/watch", url), nil)
|
||||||
|
assert.Success(t, err)
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("http://%s/cream", url), nil)
|
||||||
|
assert.Success(t, err)
|
||||||
|
var httpClient = &http.Client{}
|
||||||
|
resp, err := httpClient.Do(req)
|
||||||
|
assert.Success(t, err)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
assert.Equal(t, 200, resp.StatusCode)
|
||||||
|
|
||||||
|
time.Sleep(1000)
|
||||||
|
spew.Dump(string(stderr.Bytes()))
|
||||||
|
|
||||||
|
_, _, err = c.Read(ctx)
|
||||||
|
spew.Dump(err)
|
||||||
|
|
||||||
|
defer c.Close(websocket.StatusNormalClosure, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
doneChan <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
<-doneChan
|
||||||
|
|
||||||
|
err := tms.Signal(ctx, os.Interrupt)
|
||||||
|
assert.Error(t, err)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
|
||||||
2
go.mod
generated
2
go.mod
generated
|
|
@ -27,7 +27,7 @@ require (
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
|
||||||
gonum.org/v1/plot v0.12.0
|
gonum.org/v1/plot v0.12.0
|
||||||
nhooyr.io/websocket v1.8.7
|
nhooyr.io/websocket v1.8.7
|
||||||
oss.terrastruct.com/util-go v0.0.0-20230604222829-11c3c60fec14
|
oss.terrastruct.com/util-go v0.0.0-20231101220827-55b3812542c2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
|
||||||
6
go.sum
generated
6
go.sum
generated
|
|
@ -331,4 +331,10 @@ nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||||
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||||
oss.terrastruct.com/util-go v0.0.0-20230604222829-11c3c60fec14 h1:oy5vtt6O2qYxeSpqWhyevrdUenFfuhphixozUlpL6qY=
|
oss.terrastruct.com/util-go v0.0.0-20230604222829-11c3c60fec14 h1:oy5vtt6O2qYxeSpqWhyevrdUenFfuhphixozUlpL6qY=
|
||||||
oss.terrastruct.com/util-go v0.0.0-20230604222829-11c3c60fec14/go.mod h1:eMWv0sOtD9T2RUl90DLWfuShZCYp4NrsqNpI8eqO6U4=
|
oss.terrastruct.com/util-go v0.0.0-20230604222829-11c3c60fec14/go.mod h1:eMWv0sOtD9T2RUl90DLWfuShZCYp4NrsqNpI8eqO6U4=
|
||||||
|
oss.terrastruct.com/util-go v0.0.0-20231101215508-f36525fd4280 h1:AoxRLGSofA+l7zYwwxzdQSqyEYPOq8GznZU1CXByxsQ=
|
||||||
|
oss.terrastruct.com/util-go v0.0.0-20231101215508-f36525fd4280/go.mod h1:eMWv0sOtD9T2RUl90DLWfuShZCYp4NrsqNpI8eqO6U4=
|
||||||
|
oss.terrastruct.com/util-go v0.0.0-20231101220527-f06cd5cb4db4 h1:trpfw07GR3LYlM/7MLMRM7y7o7H8e8PEF9XtVl5J6FE=
|
||||||
|
oss.terrastruct.com/util-go v0.0.0-20231101220527-f06cd5cb4db4/go.mod h1:eMWv0sOtD9T2RUl90DLWfuShZCYp4NrsqNpI8eqO6U4=
|
||||||
|
oss.terrastruct.com/util-go v0.0.0-20231101220827-55b3812542c2 h1:n6y6RoZCgZDchN4gLGlzNRO1Jdf9xOGGqohDBph5BG8=
|
||||||
|
oss.terrastruct.com/util-go v0.0.0-20231101220827-55b3812542c2/go.mod h1:eMWv0sOtD9T2RUl90DLWfuShZCYp4NrsqNpI8eqO6U4=
|
||||||
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
|
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue