diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..d7226ae8f --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +d2layouts/d2dagrelayout/dagre.js +d2layouts/d2elklayout/setup.js +d2renderers/d2latex/mathjax.js +d2renderers/d2latex/polyfills.js +d2renderers/d2latex/setup.js +lib/png/generate_png.js diff --git a/Makefile b/Makefile index fdc039a33..8fd431900 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ all: fmt gen lint build test .PHONY: fmt fmt: - prefix "$@" ./ci/fmt.sh + prefix "$@" ./ci/sub/bin/fmt.sh .PHONY: gen gen: prefix "$@" ./ci/gen.sh diff --git a/README.md b/README.md index 03bd040c1..31152515b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [Language docs](https://d2lang.com) | [Cheat sheet](./docs/assets/cheat_sheet.pdf) | [Comparisons](https://text-to-diagram.com) [![ci](https://github.com/terrastruct/d2/actions/workflows/ci.yml/badge.svg)](https://github.com/terrastruct/d2/actions/workflows/ci.yml) +[![daily](https://github.com/terrastruct/d2/actions/workflows/daily.yml/badge.svg)](https://github.com/terrastruct/d2/actions/workflows/daily.yml) [![release](https://img.shields.io/github/v/release/terrastruct/d2)](https://github.com/terrastruct/d2/releases) [![discord](https://img.shields.io/discord/1039184639652265985?label=discord)](https://discord.gg/NF6X8K4eDq) [![twitter](https://img.shields.io/twitter/follow/terrastruct?style=social)](https://twitter.com/terrastruct) diff --git a/ci/fmt.sh b/ci/fmt.sh deleted file mode 100755 index 4fb39da34..000000000 --- a/ci/fmt.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -set -eu -. "$(dirname "$0")/sub/lib.sh" -cd -- "$(dirname "$0")/.." - -if is_changed README.md; then - sh_c tocsubst --skip 1 README.md -fi -if is_changed docs/INSTALL.md; then - sh_c tocsubst --skip 1 docs/INSTALL.md -fi -./ci/sub/fmt/make.sh diff --git a/ci/release/_build.sh b/ci/release/_build.sh index 3f8b1663d..02c58f9db 100755 --- a/ci/release/_build.sh +++ b/ci/release/_build.sh @@ -4,19 +4,23 @@ cd -- "$(dirname "$0")/../.." . ./ci/sub/lib.sh sh_c mkdir -p "$HW_BUILD_DIR" -sh_c rsync --recursive --perms --delete \ - --human-readable --copy-links ./ci/release/template/ "$HW_BUILD_DIR/" -VERSION=$VERSION sh_c eval "'$HW_BUILD_DIR/README.md.sh'" \> "'$HW_BUILD_DIR/README.md'" -sh_c rm -f "$HW_BUILD_DIR/README.md.sh" -sh_c find "$HW_BUILD_DIR" -exec touch {} \\\; +sh_c cp ./ci/release/template/LICENSE.txt "$HW_BUILD_DIR" +sh_c cp ./ci/release/template/Makefile "$HW_BUILD_DIR" +sh_c cp -R ./ci/release/template/man "$HW_BUILD_DIR" +sh_c cp -Rf ./ci/release/template/scripts "$HW_BUILD_DIR" +sh_c VERSION="$VERSION" ./ci/release/template/README.md.sh \> "'$HW_BUILD_DIR/README.md'" ensure_goos ensure_goarch sh_c mkdir -p "$HW_BUILD_DIR/bin" -sh_c CGO_ENABLED=0 go build -trimpath \ +sh_c GOOS="$GOOS" GOARCH="$GOARCH" CGO_ENABLED=0 go build -trimpath \ -ldflags "'-X oss.terrastruct.com/d2/lib/version.Version=$VERSION'" \ -o "$HW_BUILD_DIR/bin/d2" . +if [ "$GOOS" = windows ]; then + sh_c mv "$HW_BUILD_DIR/bin/d2" "$HW_BUILD_DIR/bin/d2.exe" +fi + ARCHIVE=$PWD/$ARCHIVE cd "$(dirname "$HW_BUILD_DIR")" sh_c tar -czf "$ARCHIVE" "$(basename "$HW_BUILD_DIR")" diff --git a/ci/release/_install.sh b/ci/release/_install.sh index 6428f432b..f0c653312 100755 --- a/ci/release/_install.sh +++ b/ci/release/_install.sh @@ -347,7 +347,7 @@ install_d2_standalone() { install_d2_brew() { header "installing d2 with homebrew" - sh_c brew tap terrastruct/d2 + sh_c brew update sh_c brew install d2 } @@ -390,8 +390,8 @@ install_tala_standalone() { install_tala_brew() { header "installing tala with homebrew" - sh_c brew tap terrastruct/d2 - sh_c brew install tala + sh_c brew update + sh_c brew install terrastruct/tap/tala } uninstall() { @@ -502,11 +502,6 @@ fetch_gh() { sh_c mv "$file.inprogress" "$file" } -brew() { - # Makes brew sane. - HOMEBREW_NO_INSTALL_CLEANUP=1 HOMEBREW_NO_AUTO_UPDATE=1 command brew "$@" -} - # The main function does more than provide organization. It provides robustness in that if # the install script was to only partial download into sh, sh will not execute it because # main is not invoked until the very last byte. diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f3c0d2a77..3fadfa006 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -2,4 +2,8 @@ #### Improvements 🧹 +- The Windows release binary is now suffixed correctly with `.exe` [#388](https://github.com/terrastruct/d2/issues/388) + #### Bugfixes ⛑️ + +- Fixed sequence diagram span size for self-edges [#397](https://github.com/terrastruct/d2/pull/397) diff --git a/ci/release/template/README.md.sh b/ci/release/template/README.md.sh index 2c0cdfb35..d52d96716 100755 --- a/ci/release/template/README.md.sh +++ b/ci/release/template/README.md.sh @@ -1,5 +1,7 @@ #!/bin/sh set -eu +cd -- "$(dirname "$0")/../../.." +. ./ci/sub/lib.sh cat <\` + +For installation you'll have to add the \`./bin/d2.exe\` binary to your \`\$PATH\`. Or add +the \`./bin\` directory of this release to your \`\$PATH\`. + +See https://www.wikihow.com/Change-the-PATH-Environment-Variable-on-Windows + +Then you'll be able to call \`d2\` from the commandline in \`cmd.exe\` or \`pwsh.exe\`. + +We intend to have a \`.msi\` release installer sometime soon that handles putting \`d2\` into +your \`\$PATH\` for you. + +You can also use \`make install\` to install on Windows after first installing +[MSYS2](https://www.msys2.org/) which emulates a Linux shell for Windows. Its terminal +also enables d2 to show colors in its output. The manpage will also become accessible +with \`man d2\`. + +See https://github.com/terrastruct/d2/blob/master/docs/INSTALL.md#windows +EOF +fi + +cat < The install script above does this automatically if you have `brew` installed and > are running it on macOS. +You can also install from source with: + +```d2 +brew install d2 --HEAD +``` + ## Linux The following distributions have packages for d2: @@ -154,7 +159,7 @@ go install oss.terrastruct.com/d2@latest ### Source Release -To install a proper release from source clone the repository and then: +To install a release from source clone the repository and then: ```sh ./ci/release/build.sh --install @@ -163,17 +168,22 @@ To install a proper release from source clone the repository and then: ``` Installing a real release will also install manpages and in the future other assets like -fonts and icons. Furthermore, when installing a non versioned commit, installing a proper -release will ensure that `d2 --version` works correctly by embedding the commit hash into -the `d2` binary. +fonts and icons. Furthermore, when installing a non versioned commit, installing a release +will ensure that `d2 --version` works correctly by embedding the commit hash into the `d2` +binary. ## Windows d2 builds and runs on Windows: We have prebuilt standalone releases for Windows though they're structured in the same way -as our Unix releases. So after extracting a release, you'll have to manually put the d2 -binary into your `$PATH` or add the `bin` directory of the release into your `$PATH`. +as our Unix releases. + +Easiest way to use d2 on Windows is to just `chdir` into the bin directory of the release +and invoke d2 like `./d2 ` + +For installation, you'll have to put the `bin/d2.exe` binary into your `$PATH` or add the +`bin` directory of the release into your `$PATH`. See https://www.wikihow.com/Change-the-PATH-Environment-Variable-on-Windows @@ -191,7 +201,7 @@ Bash](https://gitforwindows.org/#bash) (Git Bash is based on MSYS2) for an impro terminal experience. MSYS2 provides a unix style shell environment that is native to Windows (unlike -[Cygwin](https://www.cygwin.com/)). MSYS2 allows `install.sh` to work, enables proper +[Cygwin](https://www.cygwin.com/)). MSYS2 allows `install.sh` to work, enables automatic installation of our standalone releases via `make install` and makes the manpage accessible via `man d2`. diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index 373ee5acd..a7eef68c1 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -28,8 +28,12 @@ B: goodbye { shape: sequence_diagram } -A->B -`, +A->B`, + }, { + name: "sequence_diagram_span_cover", + script: `shape: sequence_diagram +b.1 -> b.1 +b.1 -> b.1`, }, } diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/board.exp.json b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/board.exp.json new file mode 100644 index 000000000..8966eb315 --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/board.exp.json @@ -0,0 +1,219 @@ +{ + "name": "", + "shapes": [ + { + "id": "b", + "type": "", + "pos": { + "x": 24, + "y": 74 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b.1", + "type": "rectangle", + "pos": { + "x": 93, + "y": 314 + }, + "width": 12, + "height": 242, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 26, + "zIndex": 2, + "level": 2 + } + ], + "connections": [ + { + "id": "b.(1 -> 1)[0]", + "src": "b.1", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.1", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 105, + "y": 330 + }, + { + "x": 199, + "y": 330 + }, + { + "x": 199, + "y": 410 + }, + { + "x": 105, + "y": 410 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "b.(1 -> 1)[1]", + "src": "b.1", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.1", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 105, + "y": 460 + }, + { + "x": 199, + "y": 460 + }, + { + "x": 199, + "y": 540 + }, + { + "x": 105, + "y": 540 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(b -- )[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "b-lifeline-end-668380428", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 99, + "y": 200 + }, + { + "x": 99, + "y": 670 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ] +} diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/sketch.exp.svg new file mode 100644 index 000000000..b1b935e3c --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_span_cover/dagre/sketch.exp.svg @@ -0,0 +1,28 @@ + +b \ No newline at end of file diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/elk/board.exp.json b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/board.exp.json new file mode 100644 index 000000000..8966eb315 --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/board.exp.json @@ -0,0 +1,219 @@ +{ + "name": "", + "shapes": [ + { + "id": "b", + "type": "", + "pos": { + "x": 24, + "y": 74 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#EDF0FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b.1", + "type": "rectangle", + "pos": { + "x": 93, + "y": 314 + }, + "width": 12, + "height": 242, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#E3E9FD", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 26, + "zIndex": 2, + "level": 2 + } + ], + "connections": [ + { + "id": "b.(1 -> 1)[0]", + "src": "b.1", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.1", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 105, + "y": 330 + }, + { + "x": 199, + "y": 330 + }, + { + "x": 199, + "y": 410 + }, + { + "x": 105, + "y": 410 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "b.(1 -> 1)[1]", + "src": "b.1", + "srcArrow": "none", + "srcLabel": "", + "dst": "b.1", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 105, + "y": 460 + }, + { + "x": 199, + "y": 460 + }, + { + "x": 199, + "y": 540 + }, + { + "x": 105, + "y": 540 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(b -- )[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "b-lifeline-end-668380428", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 99, + "y": 200 + }, + { + "x": 99, + "y": 670 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ] +} diff --git a/e2etests/testdata/regression/sequence_diagram_span_cover/elk/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/sketch.exp.svg new file mode 100644 index 000000000..b1b935e3c --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_span_cover/elk/sketch.exp.svg @@ -0,0 +1,28 @@ + +b \ No newline at end of file diff --git a/install.sh b/install.sh index 07425ca70..37f4fbcbb 100755 --- a/install.sh +++ b/install.sh @@ -930,7 +930,7 @@ install_d2_standalone() { install_d2_brew() { header "installing d2 with homebrew" - sh_c brew tap terrastruct/d2 + sh_c brew update sh_c brew install d2 } @@ -973,8 +973,8 @@ install_tala_standalone() { install_tala_brew() { header "installing tala with homebrew" - sh_c brew tap terrastruct/d2 - sh_c brew install tala + sh_c brew update + sh_c brew install terrastruct/tap/tala } uninstall() { @@ -1085,11 +1085,6 @@ fetch_gh() { sh_c mv "$file.inprogress" "$file" } -brew() { - # Makes brew sane. - HOMEBREW_NO_INSTALL_CLEANUP=1 HOMEBREW_NO_AUTO_UPDATE=1 command brew "$@" -} - # The main function does more than provide organization. It provides robustness in that if # the install script was to only partial download into sh, sh will not execute it because # main is not invoked until the very last byte. diff --git a/lib/imgbundler/imgbundler.go b/lib/imgbundler/imgbundler.go index 14ff92cd8..e1b719687 100644 --- a/lib/imgbundler/imgbundler.go +++ b/lib/imgbundler/imgbundler.go @@ -17,8 +17,8 @@ import ( "time" "golang.org/x/xerrors" - "oss.terrastruct.com/util-go/xdefer" + "oss.terrastruct.com/util-go/xdefer" "oss.terrastruct.com/util-go/xmain" )