Merge pull request #87 from terrastruct/releases-c9b3
ci/release: Implement
This commit is contained in:
commit
4ecd9d7eda
29 changed files with 2170 additions and 12 deletions
54
README.md
54
README.md
|
|
@ -42,27 +42,61 @@
|
||||||
|
|
||||||
## Quickstart (CLI)
|
## Quickstart (CLI)
|
||||||
|
|
||||||
|
To install:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# With --dryrun the install script will print the commands it will use
|
||||||
|
# to install without actually installing so you know what it's going to do.
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s -- --dryrun
|
||||||
|
# If things look good, install for real.
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s --
|
||||||
|
```
|
||||||
|
|
||||||
The most convenient way to use D2 is to just run it as a CLI executable to
|
The most convenient way to use D2 is to just run it as a CLI executable to
|
||||||
produce SVGs from `.d2` files.
|
produce SVGs from `.d2` files.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go install oss.terrastruct.com/d2
|
|
||||||
|
|
||||||
echo 'x -> y -> z' > in.d2
|
echo 'x -> y -> z' > in.d2
|
||||||
d2 --watch in.d2 out.svg
|
d2 --watch in.d2 out.svg
|
||||||
```
|
```
|
||||||
|
|
||||||
A browser window will open with `out.svg` and live-reload on changes to `in.d2`.
|
A browser window will open with `out.svg` and live-reload on changes to `in.d2`.
|
||||||
|
|
||||||
### MacOS
|
### Installing from source
|
||||||
|
|
||||||
Homebrew package coming soon.
|
```sh
|
||||||
|
go install oss.terrastruct.com/d2
|
||||||
|
```
|
||||||
|
|
||||||
### Linux/Windows
|
### Install
|
||||||
|
|
||||||
We have precompiled binaries on the [releases](https://github.com/terrastruct/d2/releases)
|
We have precompiled binaries on the [releases](https://github.com/terrastruct/d2/releases)
|
||||||
page. D2 will be added to OS-respective package managers soon.
|
page for macOS and Linux. For both amd64 and arm64. We will release package manager
|
||||||
|
distributions like .rpm, .deb soon. We also want to get D2 on Homebrew for macOS
|
||||||
|
and release a docker image
|
||||||
|
|
||||||
|
For now, if you don't want to install from source, just use our install script:
|
||||||
|
Pass `--tala` if you want to install our improved but closed source layout engine
|
||||||
|
tala. See the docs on [layout engine](#layout-engine) below.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# With --dryrun the install script will print the commands it will use
|
||||||
|
# to install without actually installing so you know what it's going to do.
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s -- --dryrun
|
||||||
|
# If things look good, install for real.
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s --
|
||||||
|
```
|
||||||
|
|
||||||
|
To uninstall:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s -- --uninstall --dryrun
|
||||||
|
# If things look good, install for real.
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s -- --uninstall
|
||||||
|
```
|
||||||
|
|
||||||
|
> warn: Our binary releases aren't fully portable like normal Go binaries due to the C
|
||||||
|
> dependency on v8go for executing dagre.
|
||||||
|
|
||||||
## Quickstart (library)
|
## Quickstart (library)
|
||||||
|
|
||||||
|
|
@ -155,6 +189,14 @@ any single type like "radial" or "tree" (as almost all layout engines are). For
|
||||||
information and to download & try TALA, see
|
information and to download & try TALA, see
|
||||||
[https://github.com/terrastruct/TALA](https://github.com/terrastruct/TALA).
|
[https://github.com/terrastruct/TALA](https://github.com/terrastruct/TALA).
|
||||||
|
|
||||||
|
You can just pass `--tala` to the install script to install tala as well:
|
||||||
|
|
||||||
|
```
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s -- --tala --dryrun
|
||||||
|
# If things look good, install for real.
|
||||||
|
curl -fsSL https://d2lang.com/install.sh | sh -s -- --tala
|
||||||
|
```
|
||||||
|
|
||||||
## Comparison
|
## Comparison
|
||||||
|
|
||||||
For a comparison against other popular text-to-diagram tools, see
|
For a comparison against other popular text-to-diagram tools, see
|
||||||
|
|
|
||||||
49
ci/release/README.md
Normal file
49
ci/release/README.md
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
# release
|
||||||
|
|
||||||
|
## _install.sh
|
||||||
|
|
||||||
|
The template for the install script in the root of the repository.
|
||||||
|
|
||||||
|
### gen_install.sh
|
||||||
|
|
||||||
|
Generates the install.sh script in the root of the repository by prepending the libraries
|
||||||
|
it depends on from ../sub/lib.
|
||||||
|
|
||||||
|
## release.sh
|
||||||
|
|
||||||
|
- ./release.sh is the top level script to generate a new release.
|
||||||
|
Run with --help for usage.
|
||||||
|
|
||||||
|
## build.sh
|
||||||
|
|
||||||
|
- ./build.sh builds the release archives for each platform into ./build/<VERSION>/*.tar.gz
|
||||||
|
Run with --help for usage.
|
||||||
|
|
||||||
|
> note: Remember for production releases you need to set the $TSTRUCT_OS_ARCH_BUILDER
|
||||||
|
> variables as we must compile d2 directly on each release target to include dagre.
|
||||||
|
> See https://github.com/terrastruct/d2/issues/31
|
||||||
|
|
||||||
|
Use `--host-only` to build only the release for the host's OS-ARCH pair.
|
||||||
|
|
||||||
|
### build_docker.sh
|
||||||
|
|
||||||
|
Helper script called by build.sh to build D2 on each linux runner inside Docker.
|
||||||
|
The Dockerfile is in ./builders/Dockerfile
|
||||||
|
|
||||||
|
### _build.sh
|
||||||
|
|
||||||
|
Called by build.sh (with --local or macOS) or build_docker.sh (on linux) to create the
|
||||||
|
release archive.
|
||||||
|
|
||||||
|
Do not invoke directly. If you want to produce a build for a single platform run build.sh
|
||||||
|
as so:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# To only build the linux-amd64 release.
|
||||||
|
./build.sh --run=linux-amd64
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# To only build the linux-amd64 release locally.
|
||||||
|
./build.sh --local --run=linux-amd64
|
||||||
|
```
|
||||||
22
ci/release/_build.sh
Executable file
22
ci/release/_build.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
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 {} \\\;
|
||||||
|
|
||||||
|
export GOOS=$(goos "$OS")
|
||||||
|
export GOARCH="$ARCH"
|
||||||
|
sh_c mkdir -p "$HW_BUILD_DIR/bin"
|
||||||
|
sh_c go build -ldflags "'-X oss.terrastruct.com/d2/lib/version.Version=$VERSION'" \
|
||||||
|
-o "$HW_BUILD_DIR/bin/d2" ./cmd/d2
|
||||||
|
|
||||||
|
ARCHIVE=$PWD/$ARCHIVE
|
||||||
|
cd "$(dirname "$HW_BUILD_DIR")"
|
||||||
|
sh_c tar -czf "$ARCHIVE" "$(basename "$HW_BUILD_DIR")"
|
||||||
|
cd ->/dev/null
|
||||||
377
ci/release/_install.sh
Executable file
377
ci/release/_install.sh
Executable file
|
|
@ -0,0 +1,377 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
cd -- "$(dirname "$0")/../sub/lib"
|
||||||
|
. ./log.sh
|
||||||
|
. ./flag.sh
|
||||||
|
. ./release.sh
|
||||||
|
cd - >/dev/null
|
||||||
|
|
||||||
|
help() {
|
||||||
|
arg0="$0"
|
||||||
|
if [ "$0" = sh ]; then
|
||||||
|
arg0="curl -fsSL https://d2lang.com/install.sh | sh -s --"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
usage: $arg0 [--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local]
|
||||||
|
[--tala latest] [--force] [--uninstall]
|
||||||
|
|
||||||
|
install.sh automates the installation of D2 onto your system. It currently only supports
|
||||||
|
the installation of standalone releases from GitHub. If you pass --edge, it will clone the
|
||||||
|
source, build a release and install from it.
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
|
||||||
|
--dry-run
|
||||||
|
Pass to have install.sh show the install method and flags that will be used to install
|
||||||
|
without executing them. Very useful to understand what changes it will make to your system.
|
||||||
|
|
||||||
|
--version vX.X.X
|
||||||
|
Pass to have install.sh install the given version instead of the latest version.
|
||||||
|
|
||||||
|
--edge
|
||||||
|
Pass to build and install D2 from source. This will still use --method if set to detect
|
||||||
|
to install the release archive for your OS, whether it's apt, yum, brew or standalone
|
||||||
|
if an unsupported package manager is used. To install from source like a dev would,
|
||||||
|
use go install oss.terrastruct.com/d2
|
||||||
|
note: currently unimplemented.
|
||||||
|
|
||||||
|
--method [detect | standalone]
|
||||||
|
Pass to control the method by which to install. Right now we only support standalone
|
||||||
|
releases from GitHub but later we'll add support for brew, rpm, deb and more.
|
||||||
|
note: currently unimplemented.
|
||||||
|
|
||||||
|
- detect is currently unimplemented but would use your OS's package manager
|
||||||
|
automatically.
|
||||||
|
- standalone installs a standalone release archive into the unix hierarchy path
|
||||||
|
specified by --prefix which defaults to /usr/local
|
||||||
|
Ensure /usr/local/bin is in your \$PATH to use it.
|
||||||
|
|
||||||
|
--prefix /usr/local
|
||||||
|
Controls the unix hierarchy path into which standalone releases are installed.
|
||||||
|
Defaults to /usr/local. You may also want to use ~/.local to avoid needing sudo.
|
||||||
|
Remember that whatever you use, you must have the bin directory of your prefix
|
||||||
|
path in \$PATH to execute the d2 binary. For example, if my prefix directory is
|
||||||
|
/usr/local then my \$PATH must contain /usr/local/bin.
|
||||||
|
|
||||||
|
--tala [latest]
|
||||||
|
Install Terrastruct's closed source TALA for improved layouts.
|
||||||
|
See https://github.com/terrastruct/TALA
|
||||||
|
It optionally takes an argument of the TALA version to install.
|
||||||
|
Installation obeys all other flags, just like the installation of d2. For example,
|
||||||
|
the d2plugin-tala binary will be installed into /usr/local/bin/d2plugin-tala
|
||||||
|
|
||||||
|
--force:
|
||||||
|
Force installation over the existing version even if they match. It will attempt a
|
||||||
|
uninstall first before installing the new version. The installed release tree
|
||||||
|
will be deleted from /usr/local/lib/d2/d2-<VERSION> but the release archive in
|
||||||
|
~/.cache/d2/release will remain.
|
||||||
|
|
||||||
|
--uninstall:
|
||||||
|
Uninstall the installed version of d2. The --method and --prefix flags must be the same
|
||||||
|
as for installation. i.e if you used --method standalone you must again use --method
|
||||||
|
standalone for uninstallation. With detect, the install script will try to use the OS
|
||||||
|
package manager to uninstall instead.
|
||||||
|
|
||||||
|
All downloaded archives are cached into ~/.cache/d2/release. use \$XDG_CACHE_HOME to change
|
||||||
|
path of the cached assets. Release archives are unarchived into /usr/local/lib/d2/d2-<VERSION>
|
||||||
|
|
||||||
|
note: Deleting the unarchived releases will cause --uninstall to stop working.
|
||||||
|
|
||||||
|
You can rerun install.sh to update your version of D2. install.sh will avoid reinstalling
|
||||||
|
if the installed version is the latest unless --force is passed.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [ -n "${DEBUG-}" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
METHOD=standalone
|
||||||
|
while :; do
|
||||||
|
flag_parse "$@"
|
||||||
|
case "$FLAG" in
|
||||||
|
h|help)
|
||||||
|
help
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
dry-run)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
DRY_RUN=1
|
||||||
|
;;
|
||||||
|
version)
|
||||||
|
flag_nonemptyarg && shift "$FLAGSHIFT"
|
||||||
|
VERSION=$FLAGARG
|
||||||
|
;;
|
||||||
|
tala)
|
||||||
|
shift "$FLAGSHIFT"
|
||||||
|
TALA=${FLAGARG:-latest}
|
||||||
|
;;
|
||||||
|
edge)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
EDGE=1
|
||||||
|
echoerr "$FLAGRAW is currently unimplemented"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
method)
|
||||||
|
flag_nonemptyarg && shift "$FLAGSHIFT"
|
||||||
|
METHOD=$FLAGARG
|
||||||
|
echoerr "$FLAGRAW is currently unimplemented"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
prefix)
|
||||||
|
flag_nonemptyarg && shift "$FLAGSHIFT"
|
||||||
|
export PREFIX=$FLAGARG
|
||||||
|
;;
|
||||||
|
force)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
FORCE=1
|
||||||
|
;;
|
||||||
|
uninstall)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
UNINSTALL=1
|
||||||
|
;;
|
||||||
|
'')
|
||||||
|
shift "$FLAGSHIFT"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
flag_errusage "unrecognized flag $FLAGRAW"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
flag_errusage "no arguments are accepted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO=${REPO:-terrastruct/d2}
|
||||||
|
PREFIX=${PREFIX:-/usr/local}
|
||||||
|
OS=$(os)
|
||||||
|
ARCH=$(arch)
|
||||||
|
CACHE_DIR=$(cache_dir)
|
||||||
|
mkdir -p "$CACHE_DIR"
|
||||||
|
INSTALL_DIR=$PREFIX/lib/d2
|
||||||
|
|
||||||
|
if [ -n "${UNINSTALL-}" ]; then
|
||||||
|
uninstall
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERSION=${VERSION:-latest}
|
||||||
|
if [ "$VERSION" = latest ]; then
|
||||||
|
header "fetching latest release info"
|
||||||
|
fetch_release_info
|
||||||
|
fi
|
||||||
|
|
||||||
|
install
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
install_d2
|
||||||
|
if [ "${TALA-}" ]; then
|
||||||
|
# Run in subshell to avoid overwriting VERSION.
|
||||||
|
( install_tala )
|
||||||
|
fi
|
||||||
|
|
||||||
|
COLOR=2 header success
|
||||||
|
log "d2-$VERSION-$OS-$ARCH has been successfully installed into $PREFIX"
|
||||||
|
if ! echo "$PATH" | grep -qF "$PREFIX/bin"; then
|
||||||
|
logcat >&2 <<EOF
|
||||||
|
Extend your path to use d2:
|
||||||
|
PATH=$PREFIX/bin:\$PATH
|
||||||
|
Then run:
|
||||||
|
d2 --help
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
log "You may now run d2 --help"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_d2() {
|
||||||
|
if command -v d2 >/dev/null; then
|
||||||
|
INSTALLED_VERSION="$(d2 version)"
|
||||||
|
if [ ! "${FORCE-}" -a "$VERSION" = "$INSTALLED_VERSION" ]; then
|
||||||
|
log "skipping installation as version $VERSION is already installed."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
log "uninstalling $INSTALLED_VERSION to install $VERSION"
|
||||||
|
if ! uninstall_d2; then
|
||||||
|
warn "failed to uninstall $INSTALLED_VERSION"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
header "installing d2-$VERSION"
|
||||||
|
install_standalone_d2
|
||||||
|
}
|
||||||
|
|
||||||
|
install_standalone_d2() {
|
||||||
|
ARCHIVE="d2-$VERSION-$OS-$ARCH.tar.gz"
|
||||||
|
log "installing standalone release $ARCHIVE from github"
|
||||||
|
|
||||||
|
fetch_release_info
|
||||||
|
asset_line=$(cat "$RELEASE_INFO" | grep -n "$ARCHIVE" | cut -d: -f1 | head -n1)
|
||||||
|
asset_url=$(sed -n $((asset_line-3))p "$RELEASE_INFO" | sed 's/^.*: "\(.*\)",$/\1/g')
|
||||||
|
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_tala() {
|
||||||
|
install_standalone_tala
|
||||||
|
}
|
||||||
|
|
||||||
|
install_standalone_tala() {
|
||||||
|
REPO="${REPO_TALA:-terrastruct/TALA}"
|
||||||
|
VERSION=$TALA
|
||||||
|
RELEASE_INFO=
|
||||||
|
fetch_release_info
|
||||||
|
|
||||||
|
ARCHIVE="tala-$VERSION-$OS-$ARCH.tar.gz"
|
||||||
|
log "installing standalone release $ARCHIVE from github"
|
||||||
|
|
||||||
|
asset_line=$(cat "$RELEASE_INFO" | grep -n "$ARCHIVE" | cut -d: -f1 | head -n1)
|
||||||
|
asset_url=$(sed -n $((asset_line-3))p "$RELEASE_INFO" | sed 's/^.*: "\(.*\)",$/\1/g')
|
||||||
|
|
||||||
|
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall() {
|
||||||
|
if ! command -v d2 >/dev/null; then
|
||||||
|
echoerr "no version of d2 installed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
INSTALLED_VERSION="$(d2 --version)"
|
||||||
|
if ! uninstall_d2; then
|
||||||
|
echoerr "failed to uninstall $INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "${TALA-}" ]; then
|
||||||
|
if ! command -v d2plugin-tala >/dev/null; then
|
||||||
|
echoerr "no version of tala installed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
INSTALLED_VERSION="$(d2plugin-tala --version)"
|
||||||
|
if ! uninstall_tala; then
|
||||||
|
echoerr "failed to uninstall tala $INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_d2() {
|
||||||
|
header "uninstalling d2-$INSTALLED_VERSION"
|
||||||
|
uninstall_standalone_d2
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_standalone_d2() {
|
||||||
|
log "uninstalling standalone release of d2-$INSTALLED_VERSION"
|
||||||
|
|
||||||
|
if [ ! -e "$INSTALL_DIR/d2-$INSTALLED_VERSION" ]; then
|
||||||
|
echoerr "missing standalone install release directory $INSTALL_DIR/d2-$INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
|
||||||
|
"$sh_c" rm -rf "$INSTALL_DIR/d2-$INSTALLED_VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_tala() {
|
||||||
|
uninstall_standalone_tala
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_standalone_tala() {
|
||||||
|
log "uninstalling standalone release tala-$INSTALLED_VERSION"
|
||||||
|
|
||||||
|
if [ ! -e "$INSTALL_DIR/tala-$INSTALLED_VERSION" ]; then
|
||||||
|
echoerr "missing standalone install release directory $INSTALL_DIR/tala-$INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
|
||||||
|
"$sh_c" rm -rf "$INSTALL_DIR/tala-$INSTALLED_VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_prefix_writable() {
|
||||||
|
sh_c "mkdir -p '$INSTALL_DIR' 2>/dev/null" || true
|
||||||
|
# The reason for checking whether bin is writable specifically is that on macOS you have
|
||||||
|
# /usr/local owned by root but you don't need root to write to its subdirectories which
|
||||||
|
# is all we want to do.
|
||||||
|
if [ ! -w "$PREFIX/bin" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_dir() {
|
||||||
|
if [ -n "${XDG_CACHE_HOME-}" ]; then
|
||||||
|
echo "$XDG_CACHE_HOME/d2/release"
|
||||||
|
elif [ -n "${HOME-}" ]; then
|
||||||
|
echo "$HOME/.cache/d2/release"
|
||||||
|
else
|
||||||
|
echo "/tmp/d2-cache/release"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_release_info() {
|
||||||
|
if [ -n "${RELEASE_INFO-}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "fetching info on $VERSION version of $REPO"
|
||||||
|
RELEASE_INFO=$(mktemp -d)/release-info.json
|
||||||
|
if [ "$VERSION" = latest ]; then
|
||||||
|
release_info_url="https://api.github.com/repos/$REPO/releases/$VERSION"
|
||||||
|
else
|
||||||
|
release_info_url="https://api.github.com/repos/$REPO/releases/tags/$VERSION"
|
||||||
|
fi
|
||||||
|
fetch_gh "$release_info_url" "$RELEASE_INFO" \
|
||||||
|
'application/json'
|
||||||
|
VERSION=$(cat "$RELEASE_INFO" | grep -m1 tag_name | sed 's/^.*: "\(.*\)",$/\1/g')
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_gh() {
|
||||||
|
sh_c curl -fL ${GITHUB_TOKEN+"-H \"Authorization: Bearer \$GITHUB_TOKEN\""} "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_gh() {
|
||||||
|
url=$1
|
||||||
|
file=$2
|
||||||
|
accept=$3
|
||||||
|
|
||||||
|
if [ -e "$file" ]; then
|
||||||
|
log "reusing $file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl_gh -#o "$file.inprogress" -C- -H "'Accept: $accept'" "$url"
|
||||||
|
sh_c mv "$file.inprogress" "$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
192
ci/release/build.sh
Executable file
192
ci/release/build.sh
Executable file
|
|
@ -0,0 +1,192 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/../.."
|
||||||
|
. ./ci/sub/lib.sh
|
||||||
|
|
||||||
|
help() {
|
||||||
|
cat <<EOF
|
||||||
|
usage: $0 [--rebuild] [--local] [--dry-run] [--run=regex] [--host-only]
|
||||||
|
|
||||||
|
$0 builds D2 release archives into ./ci/release/build/<version>/d2-<VERSION>-<OS>-<ARCH>.tar.gz
|
||||||
|
|
||||||
|
The version is detected via git describe which will use the git tag for the current
|
||||||
|
commit if available.
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
|
||||||
|
--rebuild
|
||||||
|
By default build.sh will avoid rebuilding finished assets if they already exist but if you
|
||||||
|
changed something and need to force rebuild, use this flag.
|
||||||
|
|
||||||
|
--local
|
||||||
|
By default build.sh uses \$TSTRUCT_MACOS_AMD64_BUILDER, \$TSTRUCT_MACOS_ARM64_BUILDER,
|
||||||
|
\$TSTRUCT_LINUX_AMD64_BUILDER and \$TSTRUCT_LINUX_ARM64_BUILDER to build the release
|
||||||
|
archives. It's required for now due to the following issue:
|
||||||
|
https://github.com/terrastruct/d2/issues/31 With --local, build.sh will cross compile
|
||||||
|
locally. warning: This is only for testing purposes, do not use in production!
|
||||||
|
|
||||||
|
--host-only
|
||||||
|
Use to build the release archive for the host OS-ARCH only. All logging is done to stderr
|
||||||
|
so in a script you can read from stdout to get the path to the release archive.
|
||||||
|
|
||||||
|
--run=regex
|
||||||
|
Use to run only the OS-ARCH jobs that match the given regex. e.g. --run=linux only runs
|
||||||
|
the linux jobs. --run=linux-amd64 only runs the linux-amd64 job.
|
||||||
|
|
||||||
|
--version vX.X.X
|
||||||
|
Use to overwrite the version detected from git.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
while :; do
|
||||||
|
flag_parse "$@"
|
||||||
|
case "$FLAG" in
|
||||||
|
h|help)
|
||||||
|
help
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
rebuild)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
REBUILD=1
|
||||||
|
;;
|
||||||
|
local)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
LOCAL=1
|
||||||
|
;;
|
||||||
|
dry-run)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
DRY_RUN=1
|
||||||
|
;;
|
||||||
|
run)
|
||||||
|
flag_reqarg && shift "$FLAGSHIFT"
|
||||||
|
JOBFILTER="$FLAGARG"
|
||||||
|
;;
|
||||||
|
host-only)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
HOST_ONLY=1
|
||||||
|
LOCAL=1
|
||||||
|
;;
|
||||||
|
version)
|
||||||
|
flag_nonemptyarg && shift "$FLAGSHIFT"
|
||||||
|
VERSION=$FLAGARG
|
||||||
|
;;
|
||||||
|
'')
|
||||||
|
shift "$FLAGSHIFT"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
flag_errusage "unrecognized flag $FLAGRAW"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
flag_errusage "no arguments are accepted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERSION=${VERSION:-$(git_describe_ref)}
|
||||||
|
BUILD_DIR=ci/release/build/$VERSION
|
||||||
|
if [ -n "${HOST_ONLY-}" ]; then
|
||||||
|
runjob $(os)-$(arch) "OS=$(os) ARCH=$(arch) build" &
|
||||||
|
waitjobs
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
runjob linux-amd64 'OS=linux ARCH=amd64 build' &
|
||||||
|
runjob linux-arm64 'OS=linux ARCH=arm64 build' &
|
||||||
|
runjob macos-amd64 'OS=macos ARCH=amd64 build' &
|
||||||
|
runjob macos-arm64 'OS=macos ARCH=arm64 build' &
|
||||||
|
waitjobs
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
HW_BUILD_DIR="$BUILD_DIR/$OS-$ARCH/d2-$VERSION"
|
||||||
|
ARCHIVE="$BUILD_DIR/d2-$VERSION-$OS-$ARCH.tar.gz"
|
||||||
|
|
||||||
|
if [ -e "$ARCHIVE" -a -z "${REBUILD-}" ]; then
|
||||||
|
log "skipping as already built at $ARCHIVE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${LOCAL-}" ]; then
|
||||||
|
build_local
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $OS in
|
||||||
|
macos)
|
||||||
|
case $ARCH in
|
||||||
|
amd64)
|
||||||
|
RHOST=$TSTRUCT_MACOS_AMD64_BUILDER build_rhost_macos
|
||||||
|
;;
|
||||||
|
arm64)
|
||||||
|
RHOST=$TSTRUCT_MACOS_ARM64_BUILDER build_rhost_macos
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
warn "no builder for OS=$OS ARCH=$ARCH, building locally..."
|
||||||
|
build_local
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
linux)
|
||||||
|
case $ARCH in
|
||||||
|
amd64)
|
||||||
|
RHOST=$TSTRUCT_LINUX_AMD64_BUILDER build_rhost_linux
|
||||||
|
;;
|
||||||
|
arm64)
|
||||||
|
RHOST=$TSTRUCT_LINUX_ARM64_BUILDER build_rhost_linux
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
warn "no builder for OS=$OS ARCH=$ARCH, building locally..."
|
||||||
|
build_local
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
warn "no builder for OS=$OS, building locally..."
|
||||||
|
build_local
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
build_local() {
|
||||||
|
export DRY_RUN \
|
||||||
|
HW_BUILD_DIR \
|
||||||
|
VERSION \
|
||||||
|
OS \
|
||||||
|
ARCH \
|
||||||
|
ARCHIVE
|
||||||
|
sh_c ./ci/release/_build.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
build_rhost_macos() {
|
||||||
|
sh_c ssh "$RHOST" mkdir -p src
|
||||||
|
sh_c rsync --archive --human-readable --delete ./ "$RHOST:src/d2/"
|
||||||
|
sh_c ssh -tttt "$RHOST" "DRY_RUN=${DRY_RUN-} \
|
||||||
|
HW_BUILD_DIR=$HW_BUILD_DIR \
|
||||||
|
VERSION=$VERSION \
|
||||||
|
OS=$OS \
|
||||||
|
ARCH=$ARCH \
|
||||||
|
ARCHIVE=$ARCHIVE \
|
||||||
|
TERM=$TERM \
|
||||||
|
PATH=\"/usr/local/bin:/usr/local/sbin\${PATH+:\$PATH}\" \
|
||||||
|
./src/d2/ci/release/_build.sh"
|
||||||
|
sh_c rsync --archive --human-readable "$RHOST:src/d2/$ARCHIVE" "$ARCHIVE"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_rhost_linux() {
|
||||||
|
sh_c ssh "$RHOST" mkdir -p src
|
||||||
|
sh_c rsync --archive --human-readable --delete ./ "$RHOST:src/d2/"
|
||||||
|
sh_c ssh -tttt "$RHOST" "DRY_RUN=${DRY_RUN-} \
|
||||||
|
HW_BUILD_DIR=$HW_BUILD_DIR \
|
||||||
|
VERSION=$VERSION \
|
||||||
|
OS=$OS \
|
||||||
|
ARCH=$ARCH \
|
||||||
|
ARCHIVE=$ARCHIVE \
|
||||||
|
TERM=$TERM \
|
||||||
|
./src/d2/ci/release/build_docker.sh"
|
||||||
|
sh_c rsync --archive --human-readable "$RHOST:src/d2/$ARCHIVE" "$ARCHIVE"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
1
ci/release/build/.gitignore
vendored
Normal file
1
ci/release/build/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
*
|
||||||
17
ci/release/build_docker.sh
Executable file
17
ci/release/build_docker.sh
Executable file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/../.."
|
||||||
|
. ./ci/sub/lib.sh
|
||||||
|
|
||||||
|
tag="$(sh_c docker build \
|
||||||
|
--build-arg GOVERSION="1.19.3.linux-$ARCH" \
|
||||||
|
-qf ./ci/release/builders/Dockerfile ./ci/release/builders)"
|
||||||
|
docker_run \
|
||||||
|
-e DRY_RUN \
|
||||||
|
-e HW_BUILD_DIR \
|
||||||
|
-e VERSION \
|
||||||
|
-e OS \
|
||||||
|
-e ARCH \
|
||||||
|
-e ARCHIVE \
|
||||||
|
-e TERM \
|
||||||
|
"$tag" ./src/d2/ci/release/_build.sh
|
||||||
12
ci/release/builders/Dockerfile
Normal file
12
ci/release/builders/Dockerfile
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
FROM debian:10
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y curl
|
||||||
|
|
||||||
|
ARG GOVERSION=
|
||||||
|
RUN curl -fsSL "https://go.dev/dl/go$GOVERSION.tar.gz" >/tmp/go.tar.gz
|
||||||
|
RUN tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||||
|
ENV PATH="/usr/local/go/bin:$PATH"
|
||||||
|
|
||||||
|
RUN apt-get install -y build-essential
|
||||||
|
RUN apt-get install -y rsync
|
||||||
16
ci/release/builders/Dockerfile-centos
Normal file
16
ci/release/builders/Dockerfile-centos
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
FROM centos:7
|
||||||
|
|
||||||
|
ARG GOVERSION=
|
||||||
|
|
||||||
|
RUN curl -fsSL "https://go.dev/dl/go$GOVERSION.tar.gz" >/tmp/go.tar.gz
|
||||||
|
RUN tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||||
|
|
||||||
|
ENV PATH="/usr/local/go/bin:$PATH"
|
||||||
|
|
||||||
|
RUN yum install -y rsync wget
|
||||||
|
RUN yum groupinstall -y 'Development Tools'
|
||||||
|
|
||||||
|
RUN curl -fsSL https://ftp.gnu.org/gnu/gcc/gcc-5.2.0/gcc-5.2.0.tar.gz >/tmp/gcc.tar.gz
|
||||||
|
RUN tar -C /usr/local -xzf /tmp/gcc.tar.gz
|
||||||
|
RUN cd /usr/local/gcc-5.2.0 && ./contrib/download_prerequisites && mkdir -p build \
|
||||||
|
&& cd build && ../configure --disable-multilib && make && make install
|
||||||
236
ci/release/builders/aws_ensure.sh
Executable file
236
ci/release/builders/aws_ensure.sh
Executable file
|
|
@ -0,0 +1,236 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/../../.."
|
||||||
|
. ./ci/sub/lib.sh
|
||||||
|
|
||||||
|
help() {
|
||||||
|
cat <<EOF
|
||||||
|
usage: $0 [--dry-run]
|
||||||
|
|
||||||
|
$0 creates and ensures the d2 builders in AWS.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
while :; do
|
||||||
|
flag_parse "$@"
|
||||||
|
case "$FLAG" in
|
||||||
|
h|help)
|
||||||
|
help
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
dry-run)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
DRY_RUN=1
|
||||||
|
;;
|
||||||
|
'')
|
||||||
|
shift "$FLAGSHIFT"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
flag_errusage "unrecognized flag $FLAGRAW"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
flag_errusage "no arguments are accepted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
create_rhosts
|
||||||
|
init_rhosts
|
||||||
|
}
|
||||||
|
|
||||||
|
create_rhosts() {
|
||||||
|
KEY_NAME=$(aws ec2 describe-key-pairs | jq -r .KeyPairs[0].KeyName)
|
||||||
|
VPC_ID=$(aws ec2 describe-vpcs | jq -r .Vpcs[0].VpcId)
|
||||||
|
|
||||||
|
header security-group
|
||||||
|
SG_ID=$(aws ec2 describe-security-groups --group-names ssh 2>/dev/null \
|
||||||
|
| jq -r .SecurityGroups[0].GroupId)
|
||||||
|
if [ -z "$SG_ID" ]; then
|
||||||
|
SG_ID=$(sh_c aws ec2 create-security-group \
|
||||||
|
--group-name ssh \
|
||||||
|
--description ssh \
|
||||||
|
--vpc-id "$VPC_ID" | jq -r .GroupId)
|
||||||
|
fi
|
||||||
|
|
||||||
|
header security-group-ingress
|
||||||
|
SG_RULES_COUNT=$(aws ec2 describe-security-groups --group-names ssh \
|
||||||
|
| jq -r '.SecurityGroups[0].IpPermissions | length')
|
||||||
|
if [ "$SG_RULES_COUNT" -eq 0 ]; then
|
||||||
|
sh_c aws ec2 authorize-security-group-ingress \
|
||||||
|
--group-id "$SG_ID" \
|
||||||
|
--protocol tcp \
|
||||||
|
--port 22 \
|
||||||
|
--cidr 0.0.0.0/0 >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
header linux-amd64
|
||||||
|
state=$(aws ec2 describe-instances --filters \
|
||||||
|
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-amd64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].State.Name')
|
||||||
|
if [ -z "$state" ]; then
|
||||||
|
sh_c aws ec2 run-instances \
|
||||||
|
--image-id=ami-0d593311db5abb72b \
|
||||||
|
--count=1 \
|
||||||
|
--instance-type=t2.small \
|
||||||
|
--security-groups=ssh \
|
||||||
|
"--key-name=$KEY_NAME" \
|
||||||
|
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-linux-amd64}]"' \
|
||||||
|
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-linux-amd64}]"' >/dev/null
|
||||||
|
fi
|
||||||
|
while true; do
|
||||||
|
dnsname=$(sh_c aws ec2 describe-instances \
|
||||||
|
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-amd64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].PublicDnsName')
|
||||||
|
if [ -n "$dnsname" ]; then
|
||||||
|
log "TSTRUCT_LINUX_AMD64_BUILDER=ec2-user@$dnsname"
|
||||||
|
export TSTRUCT_LINUX_AMD64_BUILDER=ec2-user@$dnsname
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
header linux-arm64
|
||||||
|
state=$(aws ec2 describe-instances --filters \
|
||||||
|
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-arm64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].State.Name')
|
||||||
|
if [ -z "$state" ]; then
|
||||||
|
sh_c aws ec2 run-instances \
|
||||||
|
--image-id=ami-0efabcf945ffd8831 \
|
||||||
|
--count=1 \
|
||||||
|
--instance-type=t4g.small \
|
||||||
|
--security-groups=ssh \
|
||||||
|
"--key-name=$KEY_NAME" \
|
||||||
|
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-linux-arm64}]"' \
|
||||||
|
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-linux-arm64}]"' >/dev/null
|
||||||
|
fi
|
||||||
|
while true; do
|
||||||
|
dnsname=$(sh_c aws ec2 describe-instances \
|
||||||
|
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-linux-arm64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].PublicDnsName')
|
||||||
|
if [ -n "$dnsname" ]; then
|
||||||
|
log "TSTRUCT_LINUX_ARM64_BUILDER=ec2-user@$dnsname"
|
||||||
|
export TSTRUCT_LINUX_ARM64_BUILDER=ec2-user@$dnsname
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
header "macos-amd64-host"
|
||||||
|
MACOS_AMD64_HOST_ID=$(aws ec2 describe-hosts --filter 'Name=state,Values=pending,available' 'Name=tag:Name,Values=d2-builder-macos-amd64' | jq -r '.Hosts[].HostId')
|
||||||
|
if [ -z "$MACOS_AMD64_HOST_ID" ]; then
|
||||||
|
MACOS_AMD64_HOST_ID=$(sh_c aws ec2 allocate-hosts --instance-type mac1.metal --quantity 1 --availability-zone us-west-2a \
|
||||||
|
--tag-specifications '"ResourceType=dedicated-host,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' \
|
||||||
|
| jq -r .HostIds[0])
|
||||||
|
fi
|
||||||
|
|
||||||
|
header "macos-arm64-host"
|
||||||
|
MACOS_ARM64_HOST_ID=$(aws ec2 describe-hosts --filter 'Name=state,Values=pending,available' 'Name=tag:Name,Values=d2-builder-macos-arm64' | jq -r '.Hosts[].HostId')
|
||||||
|
if [ -z "$MACOS_ARM64_HOST_ID" ]; then
|
||||||
|
MACOS_ARM64_HOST_ID=$(sh_c aws ec2 allocate-hosts --instance-type mac2.metal --quantity 1 --availability-zone us-west-2a \
|
||||||
|
--tag-specifications '"ResourceType=dedicated-host,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' \
|
||||||
|
| jq -r .HostIds[0])
|
||||||
|
fi
|
||||||
|
|
||||||
|
header macos-amd64
|
||||||
|
state=$(aws ec2 describe-instances --filters \
|
||||||
|
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-amd64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].State.Name')
|
||||||
|
if [ -z "$state" ]; then
|
||||||
|
sh_c aws ec2 run-instances \
|
||||||
|
--image-id=ami-0dd2ded7568750663 \
|
||||||
|
--count=1 \
|
||||||
|
--instance-type=mac1.metal \
|
||||||
|
--security-groups=ssh \
|
||||||
|
"--key-name=$KEY_NAME" \
|
||||||
|
--placement "Tenancy=host,HostId=$MACOS_AMD64_HOST_ID" \
|
||||||
|
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' \
|
||||||
|
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-macos-amd64}]"' >/dev/null
|
||||||
|
fi
|
||||||
|
while true; do
|
||||||
|
dnsname=$(sh_c aws ec2 describe-instances \
|
||||||
|
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-amd64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].PublicDnsName')
|
||||||
|
if [ -n "$dnsname" ]; then
|
||||||
|
log "TSTRUCT_MACOS_AMD64_BUILDER=ec2-user@$dnsname"
|
||||||
|
export TSTRUCT_MACOS_AMD64_BUILDER=ec2-user@$dnsname
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
header macos-arm64
|
||||||
|
state=$(aws ec2 describe-instances --filters \
|
||||||
|
'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-arm64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].State.Name')
|
||||||
|
if [ -z "$state" ]; then
|
||||||
|
sh_c aws ec2 run-instances \
|
||||||
|
--image-id=ami-0af0516ff2c43dbbe \
|
||||||
|
--count=1 \
|
||||||
|
--instance-type=mac2.metal \
|
||||||
|
--security-groups=ssh \
|
||||||
|
"--key-name=$KEY_NAME" \
|
||||||
|
--placement "Tenancy=host,HostId=$MACOS_ARM64_HOST_ID" \
|
||||||
|
--tag-specifications '"ResourceType=instance,Tags=[{Key=Name,Value=d2-builder-macos-arm64}]"' \
|
||||||
|
'"ResourceType=volume,Tags=[{Key=Name,Value=d2-builder-macos-arm64}]"' >/dev/null
|
||||||
|
fi
|
||||||
|
while true; do
|
||||||
|
dnsname=$(sh_c aws ec2 describe-instances \
|
||||||
|
--filters 'Name=instance-state-name,Values=pending,running,stopping,stopped' 'Name=tag:Name,Values=d2-builder-macos-arm64' \
|
||||||
|
| jq -r '.Reservations[].Instances[].PublicDnsName')
|
||||||
|
if [ -n "$dnsname" ]; then
|
||||||
|
log "TSTRUCT_MACOS_ARM64_BUILDER=ec2-user@$dnsname"
|
||||||
|
export TSTRUCT_MACOS_ARM64_BUILDER=ec2-user@$dnsname
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
init_rhosts() {
|
||||||
|
header linux-amd64
|
||||||
|
RHOST=$TSTRUCT_LINUX_AMD64_BUILDER init_rhost_linux
|
||||||
|
header linux-arm64
|
||||||
|
RHOST=$TSTRUCT_LINUX_ARM64_BUILDER init_rhost_linux
|
||||||
|
header macos-amd64
|
||||||
|
RHOST=$TSTRUCT_MACOS_AMD64_BUILDER init_rhost_macos
|
||||||
|
header macos-arm64
|
||||||
|
RHOST=$TSTRUCT_MACOS_ARM64_BUILDER init_rhost_macos
|
||||||
|
|
||||||
|
COLOR=2 header summary
|
||||||
|
log "export TSTRUCT_LINUX_AMD64_BUILDER=$TSTRUCT_LINUX_AMD64_BUILDER"
|
||||||
|
log "export TSTRUCT_LINUX_ARM64_BUILDER=$TSTRUCT_LINUX_ARM64_BUILDER"
|
||||||
|
log "export TSTRUCT_MACOS_AMD64_BUILDER=$TSTRUCT_MACOS_AMD64_BUILDER"
|
||||||
|
log "export TSTRUCT_MACOS_ARM64_BUILDER=$TSTRUCT_MACOS_ARM64_BUILDER"
|
||||||
|
}
|
||||||
|
|
||||||
|
init_rhost_linux() {
|
||||||
|
while true; do
|
||||||
|
if sh_c ssh "$RHOST" :; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
sh_c ssh "$RHOST" 'sudo yum upgrade -y'
|
||||||
|
sh_c ssh "$RHOST" 'sudo yum install -y docker'
|
||||||
|
sh_c ssh "$RHOST" 'sudo systemctl start docker'
|
||||||
|
sh_c ssh "$RHOST" 'sudo systemctl enable docker'
|
||||||
|
sh_c ssh "$RHOST" 'sudo usermod -a -G docker ec2-user'
|
||||||
|
sh_c ssh "$RHOST" 'sudo reboot' || true
|
||||||
|
}
|
||||||
|
|
||||||
|
init_rhost_macos() {
|
||||||
|
while true; do
|
||||||
|
if sh_c ssh "$RHOST" :; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
sh_c ssh "$RHOST" '": | /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""'
|
||||||
|
sh_c ssh "$RHOST" '/usr/local/bin/brew update'
|
||||||
|
sh_c ssh "$RHOST" '/usr/local/bin/brew upgrade'
|
||||||
|
sh_c ssh "$RHOST" '/usr/local/bin/brew install go'
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
43
ci/release/builders/aws_ssh_copy_id.sh
Executable file
43
ci/release/builders/aws_ssh_copy_id.sh
Executable file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/../../.."
|
||||||
|
. ./ci/sub/lib.sh
|
||||||
|
|
||||||
|
help() {
|
||||||
|
cat <<EOF
|
||||||
|
usage: $0 [--dry-run] [...args]
|
||||||
|
|
||||||
|
$0 runs ssh-copy-id on each builder.
|
||||||
|
args are passed to ssh-copy-id directly.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
while :; do
|
||||||
|
flag_parse "$@"
|
||||||
|
case "$FLAG" in
|
||||||
|
h|help)
|
||||||
|
help
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
dry-run)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
DRY_RUN=1
|
||||||
|
;;
|
||||||
|
'')
|
||||||
|
shift "$FLAGSHIFT"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
flag_errusage "unrecognized flag $FLAGRAW"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
sh_c ssh-copy-id "$@" "\$TSTRUCT_LINUX_AMD64_BUILDER"
|
||||||
|
sh_c ssh-copy-id "$@" "\$TSTRUCT_LINUX_ARM64_BUILDER"
|
||||||
|
sh_c ssh-copy-id "$@" "\$TSTRUCT_MACOS_AMD64_BUILDER"
|
||||||
|
sh_c ssh-copy-id "$@" "\$TSTRUCT_MACOS_ARM64_BUILDER"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
13
ci/release/changelogs/next.md
Normal file
13
ci/release/changelogs/next.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
For v0.0.99 we focused on X, Y and Z. Enjoy!
|
||||||
|
|
||||||
|
#### Features 💸
|
||||||
|
|
||||||
|
- Now you can easily do x, y and z #9999
|
||||||
|
|
||||||
|
#### Improvements 🔧
|
||||||
|
|
||||||
|
- Improves something or the other #9999
|
||||||
|
|
||||||
|
#### Bugfixes 🔴
|
||||||
|
|
||||||
|
- Fixes something or the other #9999
|
||||||
13
ci/release/changelogs/template.md
Normal file
13
ci/release/changelogs/template.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
For v0.0.99 we focused on X, Y and Z. Enjoy!
|
||||||
|
|
||||||
|
#### Features 💸
|
||||||
|
|
||||||
|
- Now you can easily do x, y and z #9999
|
||||||
|
|
||||||
|
#### Improvements 🔧
|
||||||
|
|
||||||
|
- Improves something or the other #9999
|
||||||
|
|
||||||
|
#### Bugfixes 🔴
|
||||||
|
|
||||||
|
- Fixes something or the other #9999
|
||||||
13
ci/release/changelogs/v0.0.99.md
Normal file
13
ci/release/changelogs/v0.0.99.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
For v0.0.99 we focused on X, Y and Z. Enjoy!
|
||||||
|
|
||||||
|
#### Features 💸
|
||||||
|
|
||||||
|
- Now you can easily do x, y and z #9999
|
||||||
|
|
||||||
|
#### Improvements 🔧
|
||||||
|
|
||||||
|
- Improves something or the other #9999
|
||||||
|
|
||||||
|
#### Bugfixes 🔴
|
||||||
|
|
||||||
|
- Fixes something or the other #9999
|
||||||
37
ci/release/gen_install.sh
Executable file
37
ci/release/gen_install.sh
Executable file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/../.."
|
||||||
|
. ./ci/sub/lib.sh
|
||||||
|
|
||||||
|
cat >./install.sh <<EOF
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# *************
|
||||||
|
# DO NOT EDIT
|
||||||
|
#
|
||||||
|
# install.sh was bundled together from
|
||||||
|
#
|
||||||
|
# - ./ci/sub/lib/rand.sh
|
||||||
|
# - ./ci/sub/lib/log.sh
|
||||||
|
# - ./ci/sub/lib/flag.sh
|
||||||
|
# - ./ci/sub/lib/release.sh
|
||||||
|
# - ./ci/release/_install.sh
|
||||||
|
#
|
||||||
|
# The last of which implements the installation logic.
|
||||||
|
#
|
||||||
|
# Generated by ./ci/release/gen_install.sh.
|
||||||
|
# *************
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# sed removes the sourcing dependency lines as we're bundled everything into a single
|
||||||
|
# script.
|
||||||
|
sh_c cat \
|
||||||
|
./ci/sub/lib/rand.sh \
|
||||||
|
./ci/sub/lib/log.sh \
|
||||||
|
./ci/sub/lib/flag.sh \
|
||||||
|
./ci/sub/lib/release.sh \
|
||||||
|
\| sed "-e'/^\. /d'" \>\> ./install.sh
|
||||||
|
sh_c cat ./ci/release/_install.sh \
|
||||||
|
\| sed -n "'/cd -- \"\$(dirname/,/cd -/!p'" \>\> install.sh
|
||||||
5
ci/release/release.sh
Executable file
5
ci/release/release.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/../.."
|
||||||
|
|
||||||
|
./ci/sub/release/release.sh "$@"
|
||||||
1
ci/release/template/LICENSE.txt
Symbolic link
1
ci/release/template/LICENSE.txt
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../../LICENSE.txt
|
||||||
12
ci/release/template/Makefile
Normal file
12
ci/release/template/Makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
.POSIX:
|
||||||
|
.SILENT:
|
||||||
|
|
||||||
|
PREFIX = $(DESTDIR)/usr/local
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install:
|
||||||
|
PREFIX='$(PREFIX)' ./scripts/install.sh
|
||||||
|
|
||||||
|
.PHONY: uninstall
|
||||||
|
uninstall:
|
||||||
|
PREFIX='$(PREFIX)' ./scripts/uninstall.sh
|
||||||
28
ci/release/template/README.md.sh
Executable file
28
ci/release/template/README.md.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
# d2
|
||||||
|
|
||||||
|
For docs, more installation options and the source code see https://oss.terrastruct.com/d2
|
||||||
|
|
||||||
|
version: $VERSION
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
\`\`\`sh
|
||||||
|
make install DRY_RUN=1
|
||||||
|
# If it looks right, run:
|
||||||
|
make install
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
Pass \`PREFIX=whatever\` to change the installation prefix.
|
||||||
|
|
||||||
|
## Uninstall
|
||||||
|
|
||||||
|
\`\`\`sh
|
||||||
|
make uninstall DRY_RUN=1
|
||||||
|
# If it looks right, run:
|
||||||
|
make uninstall
|
||||||
|
\`\`\`
|
||||||
|
EOF
|
||||||
62
ci/release/template/man/d2.1
Normal file
62
ci/release/template/man/d2.1
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
.Dd $Mdocdate$
|
||||||
|
.Dt d2 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm d2
|
||||||
|
.Nd compiles and renders d2 diagrams into svgs.
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm d2
|
||||||
|
.Op Fl -watch Ar false
|
||||||
|
.Op Fl -theme Em 0
|
||||||
|
.Ar file.d2
|
||||||
|
.Op Ar file.svg
|
||||||
|
.Nm d2
|
||||||
|
.Op Fl -watch Ar false
|
||||||
|
.Op Fl -theme Em 0
|
||||||
|
.Ar file.d2
|
||||||
|
.Op Ar ...
|
||||||
|
.Nm d2
|
||||||
|
.Ar layout Op Ar name
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
compiles and renders
|
||||||
|
.Ar file.d2
|
||||||
|
to
|
||||||
|
.Ar file.svg
|
||||||
|
.Ns .
|
||||||
|
.Pp
|
||||||
|
Pass - to have
|
||||||
|
.Nm
|
||||||
|
read from stdin or write to stdout.
|
||||||
|
.Pp
|
||||||
|
See more docs, the source code and license at
|
||||||
|
.Lk https://oss.terrastruct.com/d2
|
||||||
|
.Sh OPTIONS
|
||||||
|
.Bl -tag -width Fl
|
||||||
|
.It Fl w , -watch Ar false
|
||||||
|
Watch for changes to input and live reload. Use
|
||||||
|
.Ev $PORT and Ev $HOST to specify the listening address.
|
||||||
|
.Ev $D2_PORT and $D2_HOST are also accepted and take priority. Default is localhost:0
|
||||||
|
.It Fl t , -theme Ar 0
|
||||||
|
Set the diagram theme to the passed integer. For a list of available options, see
|
||||||
|
.Lk https://oss.terrastruct.com/d2
|
||||||
|
.It Fl b , -bundle Ar true
|
||||||
|
Bundle all assets and layers into the output svg.
|
||||||
|
.It Fl d , -debug
|
||||||
|
Print debug logs.
|
||||||
|
.It Fl h , -help
|
||||||
|
Print usage information and exit.
|
||||||
|
.It Fl v , -version
|
||||||
|
Print version information and exit.
|
||||||
|
.El
|
||||||
|
.Sh SUBCOMMANDS
|
||||||
|
.Bl -tag -width Fl
|
||||||
|
.It Ar layout
|
||||||
|
Lists available layout engine options with short help.
|
||||||
|
.It Ar layout Op Ar name
|
||||||
|
Display long help for a particular layout engine.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr d2plugin-tala 1
|
||||||
|
.Sh AUTHORS
|
||||||
|
Terrastruct Inc.
|
||||||
17
ci/release/template/scripts/install.sh
Executable file
17
ci/release/template/scripts/install.sh
Executable file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/.."
|
||||||
|
. ./scripts/lib.sh
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [ ! -e "${PREFIX-}" ]; then
|
||||||
|
echoerr "\$PREFIX must be set to a unix prefix directory in which to install d2 like /usr/local"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sh_c mkdir -p "$PREFIX"
|
||||||
|
sh_c install ./bin/d2 "$PREFIX/bin/d2"
|
||||||
|
sh_c install ./man/d2.1 "$PREFIX/share/man/man1"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
137
ci/release/template/scripts/lib.sh
Normal file
137
ci/release/template/scripts/lib.sh
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
rand() {
|
||||||
|
seed="$1"
|
||||||
|
range="$2"
|
||||||
|
|
||||||
|
seed_file="$(mktemp)"
|
||||||
|
_echo "$seed" | md5sum > "$seed_file"
|
||||||
|
shuf -i "$range" -n 1 --random-source="$seed_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
pick() {
|
||||||
|
seed="$1"
|
||||||
|
shift
|
||||||
|
i="$(rand "$seed" "1-$#")"
|
||||||
|
eval "_echo \"\$$i\""
|
||||||
|
}
|
||||||
|
|
||||||
|
tput() {
|
||||||
|
if [ -n "$TERM" ]; then
|
||||||
|
command tput "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
setaf() {
|
||||||
|
tput setaf "$1"
|
||||||
|
shift
|
||||||
|
printf '%s' "$*"
|
||||||
|
tput sgr0
|
||||||
|
}
|
||||||
|
|
||||||
|
_echo() {
|
||||||
|
printf '%s\n' "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_rand_color() {
|
||||||
|
# 1-6 are regular and 9-14 are bright.
|
||||||
|
# 1,2 and 9,10 are red and green but we use those for success and failure.
|
||||||
|
pick "$*" 3 4 5 6 11 12 13 14
|
||||||
|
}
|
||||||
|
|
||||||
|
echop() {
|
||||||
|
prefix="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ "$#" -gt 0 ]; then
|
||||||
|
printfp "$prefix" "%s\n" "$*"
|
||||||
|
else
|
||||||
|
printfp "$prefix"
|
||||||
|
printf '\n'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
printfp() {(
|
||||||
|
prefix="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ -z "${COLOR:-}" ]; then
|
||||||
|
COLOR="$(get_rand_color "$prefix")"
|
||||||
|
fi
|
||||||
|
printf '%s' "$(setaf "$COLOR" "$prefix")"
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
printf ': '
|
||||||
|
printf "$@"
|
||||||
|
fi
|
||||||
|
)}
|
||||||
|
|
||||||
|
catp() {
|
||||||
|
prefix="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
printfp "$prefix"
|
||||||
|
printf ': '
|
||||||
|
read -r line
|
||||||
|
_echo "$line"
|
||||||
|
|
||||||
|
indent=$(repeat ' ' 2)
|
||||||
|
sed "s/^/$indent/"
|
||||||
|
}
|
||||||
|
|
||||||
|
repeat() {
|
||||||
|
char="$1"
|
||||||
|
times="$2"
|
||||||
|
seq -s "$char" "$times" | tr -d '[:digit:]'
|
||||||
|
}
|
||||||
|
|
||||||
|
strlen() {
|
||||||
|
printf %s "$1" | wc -c
|
||||||
|
}
|
||||||
|
|
||||||
|
echoerr() {
|
||||||
|
COLOR=1 echop err "$*" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
caterr() {
|
||||||
|
COLOR=1 catp err "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
printferr() {
|
||||||
|
COLOR=1 printfp err "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
logp() {
|
||||||
|
echop "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
logfp() {
|
||||||
|
printfp "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
logpcat() {
|
||||||
|
catp "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
COLOR=5 logp log "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
logf() {
|
||||||
|
COLOR=5 logfp log "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
logcat() {
|
||||||
|
COLOR=5 catp log "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
sh_c() {
|
||||||
|
COLOR=3 logp exec "$*"
|
||||||
|
if [ -z "${DRY_RUN-}" ]; then
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
header() {
|
||||||
|
logp "/* $1 */"
|
||||||
|
}
|
||||||
16
ci/release/template/scripts/uninstall.sh
Executable file
16
ci/release/template/scripts/uninstall.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
cd -- "$(dirname "$0")/.."
|
||||||
|
. ./scripts/lib.sh
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [ ! -e "${PREFIX-}" ]; then
|
||||||
|
echoerr "\$PREFIX must be set to a unix prefix directory from which to uninstall d2 like /usr/local"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sh_c rm -f "$PREFIX/bin/d2"
|
||||||
|
sh_c rm -f "$PREFIX/share/man/man1"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
2
ci/sub
2
ci/sub
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7ff8380897435e73d53e329a7cd39dc38c7ad227
|
Subproject commit be28ce747b280c59b8fe89e6b29bb0637984985d
|
||||||
|
|
@ -27,7 +27,7 @@ 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 [layout name] - Display long help for a particular layout engine
|
||||||
|
|
||||||
See more docs at https://oss.terrastruct.com/d2
|
See more docs and the source code at https://oss.terrastruct.com/d2
|
||||||
`, ms.Name, ms.FlagHelp())
|
`, ms.Name, ms.FlagHelp())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -28,7 +28,7 @@ require (
|
||||||
oss.terrastruct.com/xjson v0.0.0-20221018000420-4986731c4c4a
|
oss.terrastruct.com/xjson v0.0.0-20221018000420-4986731c4c4a
|
||||||
oss.terrastruct.com/xos v0.0.0-20221018030138-c96e7ae96e5d
|
oss.terrastruct.com/xos v0.0.0-20221018030138-c96e7ae96e5d
|
||||||
oss.terrastruct.com/xrand v0.0.0-20221020211818-4ac08e618333
|
oss.terrastruct.com/xrand v0.0.0-20221020211818-4ac08e618333
|
||||||
rogchap.com/v8go v0.7.0
|
rogchap.com/v8go v0.7.1-0.20221102201510-1f00b5007d95
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -786,8 +786,8 @@ oss.terrastruct.com/xos v0.0.0-20221018030138-c96e7ae96e5d h1:rrPTkbAfsRTW1WLoTz
|
||||||
oss.terrastruct.com/xos v0.0.0-20221018030138-c96e7ae96e5d/go.mod h1:uSONPDInIwglnC+0zYs8YOjiUD8ZUSnqDTTI82j7Oro=
|
oss.terrastruct.com/xos v0.0.0-20221018030138-c96e7ae96e5d/go.mod h1:uSONPDInIwglnC+0zYs8YOjiUD8ZUSnqDTTI82j7Oro=
|
||||||
oss.terrastruct.com/xrand v0.0.0-20221020211818-4ac08e618333 h1:7EdxwXM75Id1VIN71QbE8bLzZRMs0qD7olnDw5gbI7w=
|
oss.terrastruct.com/xrand v0.0.0-20221020211818-4ac08e618333 h1:7EdxwXM75Id1VIN71QbE8bLzZRMs0qD7olnDw5gbI7w=
|
||||||
oss.terrastruct.com/xrand v0.0.0-20221020211818-4ac08e618333/go.mod h1:O7TAoBmlQhoi46RdgVikDcoLRb/vLflhkXCAd+nO4SM=
|
oss.terrastruct.com/xrand v0.0.0-20221020211818-4ac08e618333/go.mod h1:O7TAoBmlQhoi46RdgVikDcoLRb/vLflhkXCAd+nO4SM=
|
||||||
rogchap.com/v8go v0.7.0 h1:kgjbiO4zE5itA962ze6Hqmbs4HgZbGzmueCXsZtremg=
|
rogchap.com/v8go v0.7.1-0.20221102201510-1f00b5007d95 h1:r89YHVIWeQj/A3Nu6462eqARUECJlJkLRk36pfML1xA=
|
||||||
rogchap.com/v8go v0.7.0/go.mod h1:MxgP3pL2MW4dpme/72QRs8sgNMmM0pRc8DPhcuLWPAs=
|
rogchap.com/v8go v0.7.1-0.20221102201510-1f00b5007d95/go.mod h1:MxgP3pL2MW4dpme/72QRs8sgNMmM0pRc8DPhcuLWPAs=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
|
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
|
|
|
||||||
791
install.sh
Executable file
791
install.sh
Executable file
|
|
@ -0,0 +1,791 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# *************
|
||||||
|
# DO NOT EDIT
|
||||||
|
#
|
||||||
|
# install.sh was bundled together from
|
||||||
|
#
|
||||||
|
# - ./ci/sub/lib/rand.sh
|
||||||
|
# - ./ci/sub/lib/log.sh
|
||||||
|
# - ./ci/sub/lib/flag.sh
|
||||||
|
# - ./ci/sub/lib/release.sh
|
||||||
|
# - ./ci/release/_install.sh
|
||||||
|
#
|
||||||
|
# The last of which implements the installation logic.
|
||||||
|
#
|
||||||
|
# Generated by ./ci/release/gen_install.sh.
|
||||||
|
# *************
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
if [ "${LIB_RAND-}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
LIB_RAND=1
|
||||||
|
|
||||||
|
rand() {
|
||||||
|
seed="$1"
|
||||||
|
range="$2"
|
||||||
|
|
||||||
|
seed_file="$(mktemp)"
|
||||||
|
_echo "$seed" | md5sum > "$seed_file"
|
||||||
|
shuf -i "$range" -n 1 --random-source="$seed_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
pick() {
|
||||||
|
seed="$1"
|
||||||
|
shift
|
||||||
|
i="$(rand "$seed" "1-$#")"
|
||||||
|
eval "_echo \"\$$i\""
|
||||||
|
}
|
||||||
|
#!/bin/sh
|
||||||
|
if [ "${LIB_LOG-}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
LIB_LOG=1
|
||||||
|
|
||||||
|
tput() {
|
||||||
|
if [ -n "$TERM" ]; then
|
||||||
|
command tput "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
setaf() {
|
||||||
|
tput setaf "$1"
|
||||||
|
shift
|
||||||
|
printf '%s' "$*"
|
||||||
|
tput sgr0
|
||||||
|
}
|
||||||
|
|
||||||
|
_echo() {
|
||||||
|
printf '%s\n' "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_rand_color() {
|
||||||
|
# 1-6 are regular and 9-14 are bright.
|
||||||
|
# 1,2 and 9,10 are red and green but we use those for success and failure.
|
||||||
|
pick "$*" 3 4 5 6 11 12 13 14
|
||||||
|
}
|
||||||
|
|
||||||
|
echop() {
|
||||||
|
prefix="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ "$#" -gt 0 ]; then
|
||||||
|
printfp "$prefix" "%s\n" "$*"
|
||||||
|
else
|
||||||
|
printfp "$prefix"
|
||||||
|
printf '\n'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
printfp() {(
|
||||||
|
prefix="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ -z "${COLOR:-}" ]; then
|
||||||
|
COLOR="$(get_rand_color "$prefix")"
|
||||||
|
fi
|
||||||
|
printf '%s' "$(setaf "$COLOR" "$prefix")"
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
printf ': '
|
||||||
|
printf "$@"
|
||||||
|
fi
|
||||||
|
)}
|
||||||
|
|
||||||
|
catp() {
|
||||||
|
prefix="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
sed "s/^/$(printfp "$prefix" '')/"
|
||||||
|
}
|
||||||
|
|
||||||
|
repeat() {
|
||||||
|
char="$1"
|
||||||
|
times="$2"
|
||||||
|
seq -s "$char" "$times" | tr -d '[:digit:]'
|
||||||
|
}
|
||||||
|
|
||||||
|
strlen() {
|
||||||
|
printf %s "$1" | wc -c
|
||||||
|
}
|
||||||
|
|
||||||
|
echoerr() {
|
||||||
|
COLOR=1 echop err "$*" | humanpath>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
caterr() {
|
||||||
|
COLOR=1 catp err "$@" | humanpath >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
printferr() {
|
||||||
|
COLOR=1 printfp err "$@" | humanpath >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
logp() {
|
||||||
|
echop "$@" | humanpath >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
logfp() {
|
||||||
|
printfp "$@" | humanpath >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
logpcat() {
|
||||||
|
catp "$@" | humanpath >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
COLOR=5 logp log "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
logf() {
|
||||||
|
COLOR=5 logfp log "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
logcat() {
|
||||||
|
COLOR=5 catp log "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
COLOR=3 logp warn "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
warnf() {
|
||||||
|
COLOR=3 logfp warn "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
sh_c() {
|
||||||
|
COLOR=3 logp exec "$*"
|
||||||
|
if [ -z "${DRY_RUN-}" ]; then
|
||||||
|
eval "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
sudo_sh_c() {
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
sh_c "$@"
|
||||||
|
elif command -v doas >/dev/null; then
|
||||||
|
sh_c "doas $*"
|
||||||
|
elif command -v sudo >/dev/null; then
|
||||||
|
sh_c "sudo $*"
|
||||||
|
elif command -v su >/dev/null; then
|
||||||
|
sh_c "su root -c '$*'"
|
||||||
|
else
|
||||||
|
caterr <<EOF
|
||||||
|
This script needs to run the following command as root:
|
||||||
|
$*
|
||||||
|
Please install doas, sudo, or su.
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
header() {
|
||||||
|
logp "/* $1 */"
|
||||||
|
}
|
||||||
|
|
||||||
|
# humanpath replaces all occurrences of $HOME with ~
|
||||||
|
humanpath() {
|
||||||
|
if [ -z "${HOME-}" ]; then
|
||||||
|
cat
|
||||||
|
else
|
||||||
|
sed "s#$HOME#~#g"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
out="$(mktemp)"
|
||||||
|
set +e
|
||||||
|
"$@" >"$out" 2>&1
|
||||||
|
code="$?"
|
||||||
|
set -e
|
||||||
|
if [ "$code" -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
cat "$out" >&2
|
||||||
|
exit "$code"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo_dur() {
|
||||||
|
local dur=$1
|
||||||
|
local h=$((dur/60/60))
|
||||||
|
local m=$((dur/60%60))
|
||||||
|
local s=$((dur%60))
|
||||||
|
printf '%dh%dm%ds' "$h" "$m" "$s"
|
||||||
|
}
|
||||||
|
|
||||||
|
sponge() {
|
||||||
|
dst="$1"
|
||||||
|
tmp="$(mktemp)"
|
||||||
|
cat > "$tmp"
|
||||||
|
cat "$tmp" > "$dst"
|
||||||
|
}
|
||||||
|
|
||||||
|
stripansi() {
|
||||||
|
# First regex gets rid of standard xterm escape sequences for controlling
|
||||||
|
# visual attributes.
|
||||||
|
# The second regex I'm not 100% sure, the reference says it selects the US
|
||||||
|
# encoding but I'm not sure why that's necessary or why it always occurs
|
||||||
|
# in tput sgr0 before the standard escape sequence.
|
||||||
|
# See tput sgr0 | xxd
|
||||||
|
sed -e $'s/\x1b\[[0-9;]*m//g' -e $'s/\x1b(.//g'
|
||||||
|
}
|
||||||
|
|
||||||
|
runtty() {
|
||||||
|
case "$(uname)" in
|
||||||
|
Darwin)
|
||||||
|
script -q /dev/null "$@"
|
||||||
|
;;
|
||||||
|
Linux)
|
||||||
|
script -eqc "$*"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echoerr "runtty: unsupported OS $(uname)"
|
||||||
|
return 1
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
#!/bin/sh
|
||||||
|
if [ "${LIB_FLAG-}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
LIB_FLAG=1
|
||||||
|
|
||||||
|
# flag_parse implements a robust flag parser.
|
||||||
|
#
|
||||||
|
# For a full fledge example see ../examples/date.sh
|
||||||
|
#
|
||||||
|
# It differs from getopts(1) in that long form options are supported. Currently the only
|
||||||
|
# deficiency is that short combined options are not supported like -xyzq. That would be
|
||||||
|
# interpreted as a single -xyzq flag. The other deficiency is lack of support for short
|
||||||
|
# flag syntax like -carg where the arg is not separated from the flag. This one is
|
||||||
|
# unfixable I believe unfortunately but for combined short flags I have opened
|
||||||
|
# https://github.com/terrastruct/ci/issues/6
|
||||||
|
#
|
||||||
|
# flag_parse stores state in $FLAG, $FLAGRAW, $FLAGARG and $FLAGSHIFT.
|
||||||
|
# FLAG contains the name of the flag without hyphens.
|
||||||
|
# FLAGRAW contains the name of the flag as passed in with hyphens.
|
||||||
|
# FLAGARG contains the argument for the flag if there was any.
|
||||||
|
# If there was none, it will not be set.
|
||||||
|
# FLAGSHIFT contains the number by which the arguments should be shifted to
|
||||||
|
# start at the next flag/argument
|
||||||
|
#
|
||||||
|
# After each call check $FLAG for the name of the parsed flag.
|
||||||
|
# If empty, then no more flags are left.
|
||||||
|
# Still, call shift "$FLAGSHIFT" in case there was a --
|
||||||
|
#
|
||||||
|
# If the argument for the flag is optional, then use ${FLAGARG-} to access
|
||||||
|
# the argument if one was passed. Use ${FLAGARG+x} = x to check if it was set.
|
||||||
|
# You only need to explicitly check if the flag was set if you care whether the user
|
||||||
|
# explicitly passed the empty string as the argument.
|
||||||
|
#
|
||||||
|
# Otherwise, call one of the flag_*arg functions:
|
||||||
|
#
|
||||||
|
# If a flag requires an argument, call flag_reqarg
|
||||||
|
# - $FLAGARG is guaranteed to be set after.
|
||||||
|
# If a flag requires a non empty argument, call flag_nonemptyarg
|
||||||
|
# - $FLAGARG is guaranteed to be set to a non empty string after.
|
||||||
|
# If a flag should not be passed an argument, call flag_noarg
|
||||||
|
# - $FLAGARG is guaranteed to be unset after.
|
||||||
|
#
|
||||||
|
# And then shift "$FLAGSHIFT"
|
||||||
|
flag_parse() {
|
||||||
|
case "${1-}" in
|
||||||
|
-*=*)
|
||||||
|
# Remove everything after first equal sign.
|
||||||
|
FLAG="${1%%=*}"
|
||||||
|
# Remove leading hyphens.
|
||||||
|
FLAG="${FLAG#-}"; FLAG="${FLAG#-}"
|
||||||
|
FLAGRAW="$(flag_fmt)"
|
||||||
|
# Remove everything before first equal sign.
|
||||||
|
FLAGARG="${1#*=}"
|
||||||
|
FLAGSHIFT=1
|
||||||
|
;;
|
||||||
|
-)
|
||||||
|
FLAG=
|
||||||
|
FLAGRAW=
|
||||||
|
unset FLAGARG
|
||||||
|
FLAGSHIFT=0
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
FLAG=
|
||||||
|
FLAGRAW=
|
||||||
|
unset FLAGARG
|
||||||
|
FLAGSHIFT=1
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
# Remove leading hyphens.
|
||||||
|
FLAG="${1#-}"; FLAG="${FLAG#-}"
|
||||||
|
FLAGRAW=$(flag_fmt)
|
||||||
|
unset FLAGARG
|
||||||
|
FLAGSHIFT=1
|
||||||
|
if [ $# -gt 1 ]; then
|
||||||
|
case "$2" in
|
||||||
|
-)
|
||||||
|
FLAGARG="$2"
|
||||||
|
FLAGSHIFT=2
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
FLAGARG="$2"
|
||||||
|
FLAGSHIFT=2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
FLAG=
|
||||||
|
FLAGRAW=
|
||||||
|
unset FLAGARG
|
||||||
|
FLAGSHIFT=0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_reqarg() {
|
||||||
|
if [ "${FLAGARG+x}" != x ]; then
|
||||||
|
flag_errusage "flag $FLAGRAW requires an argument"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_nonemptyarg() {
|
||||||
|
flag_reqarg
|
||||||
|
if [ -z "$FLAGARG" ]; then
|
||||||
|
flag_errusage "flag $FLAGRAW requires a non-empty argument"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_noarg() {
|
||||||
|
if [ "$FLAGSHIFT" -eq 2 ]; then
|
||||||
|
unset FLAGARG
|
||||||
|
FLAGSHIFT=1
|
||||||
|
elif [ "${FLAGARG+x}" = x ]; then
|
||||||
|
# Means an argument was passed via equal sign as in -$FLAG=$FLAGARG
|
||||||
|
flag_errusage "flag $FLAGRAW does not accept an argument"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_errusage() {
|
||||||
|
caterr <<EOF
|
||||||
|
$1
|
||||||
|
Run with --help for usage.
|
||||||
|
EOF
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_fmt() {
|
||||||
|
if [ "$(printf %s "$FLAG" | wc -c)" -eq 1 ]; then
|
||||||
|
echo "-$FLAG"
|
||||||
|
else
|
||||||
|
echo "--$FLAG"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
#!/bin/sh
|
||||||
|
if [ "${LIB_RELEASE-}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
LIB_RELEASE=1
|
||||||
|
|
||||||
|
goos() {
|
||||||
|
case $1 in
|
||||||
|
macos) echo darwin ;;
|
||||||
|
*) echo $1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
os() {
|
||||||
|
uname=$(uname)
|
||||||
|
case $uname in
|
||||||
|
Linux) echo linux ;;
|
||||||
|
Darwin) echo macos ;;
|
||||||
|
FreeBSD) echo freebsd ;;
|
||||||
|
*) echo "$uname" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
arch() {
|
||||||
|
uname_m=$(uname -m)
|
||||||
|
case $uname_m in
|
||||||
|
aarch64) echo arm64 ;;
|
||||||
|
x86_64) echo amd64 ;;
|
||||||
|
*) echo "$uname_m" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
gh_repo() {
|
||||||
|
gh repo view --json nameWithOwner --template '{{ .nameWithOwner }}'
|
||||||
|
}
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
|
||||||
|
help() {
|
||||||
|
arg0="$0"
|
||||||
|
if [ "$0" = sh ]; then
|
||||||
|
arg0="curl -fsSL https://d2lang.com/install.sh | sh -s --"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
usage: $arg0 [--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local]
|
||||||
|
[--tala latest] [--force] [--uninstall]
|
||||||
|
|
||||||
|
install.sh automates the installation of D2 onto your system. It currently only supports
|
||||||
|
the installation of standalone releases from GitHub. If you pass --edge, it will clone the
|
||||||
|
source, build a release and install from it.
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
|
||||||
|
--dry-run
|
||||||
|
Pass to have install.sh show the install method and flags that will be used to install
|
||||||
|
without executing them. Very useful to understand what changes it will make to your system.
|
||||||
|
|
||||||
|
--version vX.X.X
|
||||||
|
Pass to have install.sh install the given version instead of the latest version.
|
||||||
|
|
||||||
|
--edge
|
||||||
|
Pass to build and install D2 from source. This will still use --method if set to detect
|
||||||
|
to install the release archive for your OS, whether it's apt, yum, brew or standalone
|
||||||
|
if an unsupported package manager is used. To install from source like a dev would,
|
||||||
|
use go install oss.terrastruct.com/d2
|
||||||
|
note: currently unimplemented.
|
||||||
|
|
||||||
|
--method [detect | standalone]
|
||||||
|
Pass to control the method by which to install. Right now we only support standalone
|
||||||
|
releases from GitHub but later we'll add support for brew, rpm, deb and more.
|
||||||
|
note: currently unimplemented.
|
||||||
|
|
||||||
|
- detect is currently unimplemented but would use your OS's package manager
|
||||||
|
automatically.
|
||||||
|
- standalone installs a standalone release archive into the unix hierarchy path
|
||||||
|
specified by --prefix which defaults to /usr/local
|
||||||
|
Ensure /usr/local/bin is in your \$PATH to use it.
|
||||||
|
|
||||||
|
--prefix /usr/local
|
||||||
|
Controls the unix hierarchy path into which standalone releases are installed.
|
||||||
|
Defaults to /usr/local. You may also want to use ~/.local to avoid needing sudo.
|
||||||
|
Remember that whatever you use, you must have the bin directory of your prefix
|
||||||
|
path in \$PATH to execute the d2 binary. For example, if my prefix directory is
|
||||||
|
/usr/local then my \$PATH must contain /usr/local/bin.
|
||||||
|
|
||||||
|
--tala [latest]
|
||||||
|
Install Terrastruct's closed source TALA for improved layouts.
|
||||||
|
See https://github.com/terrastruct/TALA
|
||||||
|
It optionally takes an argument of the TALA version to install.
|
||||||
|
Installation obeys all other flags, just like the installation of d2. For example,
|
||||||
|
the d2plugin-tala binary will be installed into /usr/local/bin/d2plugin-tala
|
||||||
|
|
||||||
|
--force:
|
||||||
|
Force installation over the existing version even if they match. It will attempt a
|
||||||
|
uninstall first before installing the new version. The installed release tree
|
||||||
|
will be deleted from /usr/local/lib/d2/d2-<VERSION> but the release archive in
|
||||||
|
~/.cache/d2/release will remain.
|
||||||
|
|
||||||
|
--uninstall:
|
||||||
|
Uninstall the installed version of d2. The --method and --prefix flags must be the same
|
||||||
|
as for installation. i.e if you used --method standalone you must again use --method
|
||||||
|
standalone for uninstallation. With detect, the install script will try to use the OS
|
||||||
|
package manager to uninstall instead.
|
||||||
|
|
||||||
|
All downloaded archives are cached into ~/.cache/d2/release. use \$XDG_CACHE_HOME to change
|
||||||
|
path of the cached assets. Release archives are unarchived into /usr/local/lib/d2/d2-<VERSION>
|
||||||
|
|
||||||
|
note: Deleting the unarchived releases will cause --uninstall to stop working.
|
||||||
|
|
||||||
|
You can rerun install.sh to update your version of D2. install.sh will avoid reinstalling
|
||||||
|
if the installed version is the latest unless --force is passed.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
if [ -n "${DEBUG-}" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
METHOD=standalone
|
||||||
|
while :; do
|
||||||
|
flag_parse "$@"
|
||||||
|
case "$FLAG" in
|
||||||
|
h|help)
|
||||||
|
help
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
dry-run)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
DRY_RUN=1
|
||||||
|
;;
|
||||||
|
version)
|
||||||
|
flag_nonemptyarg && shift "$FLAGSHIFT"
|
||||||
|
VERSION=$FLAGARG
|
||||||
|
;;
|
||||||
|
tala)
|
||||||
|
shift "$FLAGSHIFT"
|
||||||
|
TALA=${FLAGARG:-latest}
|
||||||
|
;;
|
||||||
|
edge)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
EDGE=1
|
||||||
|
echoerr "$FLAGRAW is currently unimplemented"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
method)
|
||||||
|
flag_nonemptyarg && shift "$FLAGSHIFT"
|
||||||
|
METHOD=$FLAGARG
|
||||||
|
echoerr "$FLAGRAW is currently unimplemented"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
prefix)
|
||||||
|
flag_nonemptyarg && shift "$FLAGSHIFT"
|
||||||
|
export PREFIX=$FLAGARG
|
||||||
|
;;
|
||||||
|
force)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
FORCE=1
|
||||||
|
;;
|
||||||
|
uninstall)
|
||||||
|
flag_noarg && shift "$FLAGSHIFT"
|
||||||
|
UNINSTALL=1
|
||||||
|
;;
|
||||||
|
'')
|
||||||
|
shift "$FLAGSHIFT"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
flag_errusage "unrecognized flag $FLAGRAW"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
flag_errusage "no arguments are accepted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO=${REPO:-terrastruct/d2}
|
||||||
|
PREFIX=${PREFIX:-/usr/local}
|
||||||
|
OS=$(os)
|
||||||
|
ARCH=$(arch)
|
||||||
|
CACHE_DIR=$(cache_dir)
|
||||||
|
mkdir -p "$CACHE_DIR"
|
||||||
|
INSTALL_DIR=$PREFIX/lib/d2
|
||||||
|
|
||||||
|
if [ -n "${UNINSTALL-}" ]; then
|
||||||
|
uninstall
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERSION=${VERSION:-latest}
|
||||||
|
if [ "$VERSION" = latest ]; then
|
||||||
|
header "fetching latest release info"
|
||||||
|
fetch_release_info
|
||||||
|
fi
|
||||||
|
|
||||||
|
install
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
install_d2
|
||||||
|
if [ "${TALA-}" ]; then
|
||||||
|
# Run in subshell to avoid overwriting VERSION.
|
||||||
|
( install_tala )
|
||||||
|
fi
|
||||||
|
|
||||||
|
COLOR=2 header success
|
||||||
|
log "d2-$VERSION-$OS-$ARCH has been successfully installed into $PREFIX"
|
||||||
|
if ! echo "$PATH" | grep -qF "$PREFIX/bin"; then
|
||||||
|
logcat >&2 <<EOF
|
||||||
|
Extend your path to use d2:
|
||||||
|
PATH=$PREFIX/bin:\$PATH
|
||||||
|
Then run:
|
||||||
|
d2 --help
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
log "You may now run d2 --help"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_d2() {
|
||||||
|
if command -v d2 >/dev/null; then
|
||||||
|
INSTALLED_VERSION="$(d2 version)"
|
||||||
|
if [ ! "${FORCE-}" -a "$VERSION" = "$INSTALLED_VERSION" ]; then
|
||||||
|
log "skipping installation as version $VERSION is already installed."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
log "uninstalling $INSTALLED_VERSION to install $VERSION"
|
||||||
|
if ! uninstall_d2; then
|
||||||
|
warn "failed to uninstall $INSTALLED_VERSION"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
header "installing d2-$VERSION"
|
||||||
|
install_standalone_d2
|
||||||
|
}
|
||||||
|
|
||||||
|
install_standalone_d2() {
|
||||||
|
ARCHIVE="d2-$VERSION-$OS-$ARCH.tar.gz"
|
||||||
|
log "installing standalone release $ARCHIVE from github"
|
||||||
|
|
||||||
|
fetch_release_info
|
||||||
|
asset_line=$(cat "$RELEASE_INFO" | grep -n "$ARCHIVE" | cut -d: -f1 | head -n1)
|
||||||
|
asset_url=$(sed -n $((asset_line-3))p "$RELEASE_INFO" | sed 's/^.*: "\(.*\)",$/\1/g')
|
||||||
|
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_tala() {
|
||||||
|
install_standalone_tala
|
||||||
|
}
|
||||||
|
|
||||||
|
install_standalone_tala() {
|
||||||
|
REPO="${REPO_TALA:-terrastruct/TALA}"
|
||||||
|
VERSION=$TALA
|
||||||
|
RELEASE_INFO=
|
||||||
|
fetch_release_info
|
||||||
|
|
||||||
|
ARCHIVE="tala-$VERSION-$OS-$ARCH.tar.gz"
|
||||||
|
log "installing standalone release $ARCHIVE from github"
|
||||||
|
|
||||||
|
asset_line=$(cat "$RELEASE_INFO" | grep -n "$ARCHIVE" | cut -d: -f1 | head -n1)
|
||||||
|
asset_url=$(sed -n $((asset_line-3))p "$RELEASE_INFO" | sed 's/^.*: "\(.*\)",$/\1/g')
|
||||||
|
|
||||||
|
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall() {
|
||||||
|
if ! command -v d2 >/dev/null; then
|
||||||
|
echoerr "no version of d2 installed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
INSTALLED_VERSION="$(d2 --version)"
|
||||||
|
if ! uninstall_d2; then
|
||||||
|
echoerr "failed to uninstall $INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "${TALA-}" ]; then
|
||||||
|
if ! command -v d2plugin-tala >/dev/null; then
|
||||||
|
echoerr "no version of tala installed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
INSTALLED_VERSION="$(d2plugin-tala --version)"
|
||||||
|
if ! uninstall_tala; then
|
||||||
|
echoerr "failed to uninstall tala $INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_d2() {
|
||||||
|
header "uninstalling d2-$INSTALLED_VERSION"
|
||||||
|
uninstall_standalone_d2
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_standalone_d2() {
|
||||||
|
log "uninstalling standalone release of d2-$INSTALLED_VERSION"
|
||||||
|
|
||||||
|
if [ ! -e "$INSTALL_DIR/d2-$INSTALLED_VERSION" ]; then
|
||||||
|
echoerr "missing standalone install release directory $INSTALL_DIR/d2-$INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
|
||||||
|
"$sh_c" rm -rf "$INSTALL_DIR/d2-$INSTALLED_VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_tala() {
|
||||||
|
uninstall_standalone_tala
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_standalone_tala() {
|
||||||
|
log "uninstalling standalone release tala-$INSTALLED_VERSION"
|
||||||
|
|
||||||
|
if [ ! -e "$INSTALL_DIR/tala-$INSTALLED_VERSION" ]; then
|
||||||
|
echoerr "missing standalone install release directory $INSTALL_DIR/tala-$INSTALLED_VERSION"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sh_c="sh_c"
|
||||||
|
if ! is_prefix_writable; then
|
||||||
|
sh_c="sudo_sh_c"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
|
||||||
|
"$sh_c" rm -rf "$INSTALL_DIR/tala-$INSTALLED_VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_prefix_writable() {
|
||||||
|
sh_c "mkdir -p '$INSTALL_DIR' 2>/dev/null" || true
|
||||||
|
# The reason for checking whether bin is writable specifically is that on macOS you have
|
||||||
|
# /usr/local owned by root but you don't need root to write to its subdirectories which
|
||||||
|
# is all we want to do.
|
||||||
|
if [ ! -w "$PREFIX/bin" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_dir() {
|
||||||
|
if [ -n "${XDG_CACHE_HOME-}" ]; then
|
||||||
|
echo "$XDG_CACHE_HOME/d2/release"
|
||||||
|
elif [ -n "${HOME-}" ]; then
|
||||||
|
echo "$HOME/.cache/d2/release"
|
||||||
|
else
|
||||||
|
echo "/tmp/d2-cache/release"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_release_info() {
|
||||||
|
if [ -n "${RELEASE_INFO-}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "fetching info on $VERSION version of $REPO"
|
||||||
|
RELEASE_INFO=$(mktemp -d)/release-info.json
|
||||||
|
if [ "$VERSION" = latest ]; then
|
||||||
|
release_info_url="https://api.github.com/repos/$REPO/releases/$VERSION"
|
||||||
|
else
|
||||||
|
release_info_url="https://api.github.com/repos/$REPO/releases/tags/$VERSION"
|
||||||
|
fi
|
||||||
|
fetch_gh "$release_info_url" "$RELEASE_INFO" \
|
||||||
|
'application/json'
|
||||||
|
VERSION=$(cat "$RELEASE_INFO" | grep -m1 tag_name | sed 's/^.*: "\(.*\)",$/\1/g')
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_gh() {
|
||||||
|
sh_c curl -fL ${GITHUB_TOKEN+"-H \"Authorization: Bearer \$GITHUB_TOKEN\""} "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_gh() {
|
||||||
|
url=$1
|
||||||
|
file=$2
|
||||||
|
accept=$3
|
||||||
|
|
||||||
|
if [ -e "$file" ]; then
|
||||||
|
log "reusing $file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl_gh -#o "$file.inprogress" -C- -H "'Accept: $accept'" "$url"
|
||||||
|
sh_c mv "$file.inprogress" "$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|
@ -2,6 +2,7 @@ package version
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/google/go-github/github"
|
"github.com/google/go-github/github"
|
||||||
"oss.terrastruct.com/cmdlog"
|
"oss.terrastruct.com/cmdlog"
|
||||||
|
|
@ -11,12 +12,17 @@ import (
|
||||||
var Version = "master (built from source)"
|
var Version = "master (built from source)"
|
||||||
|
|
||||||
func CheckVersion(ctx context.Context, logger *cmdlog.Logger) {
|
func CheckVersion(ctx context.Context, logger *cmdlog.Logger) {
|
||||||
logger.Info.Printf("D2 version: %s\n", Version)
|
fmt.Println(Version)
|
||||||
|
|
||||||
if Version == "master (built from source)" {
|
if Version == "master (built from source)" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Install script uses -v to check the version, we shouldn't be checking for
|
||||||
|
// updates here...
|
||||||
|
// https://github.com/terrastruct/d2/issues/49#issuecomment-1313229683
|
||||||
|
return
|
||||||
|
|
||||||
logger.Info.Printf("Checking for updates...")
|
logger.Info.Printf("Checking for updates...")
|
||||||
latest, err := getLatestVersion(ctx)
|
latest, err := getLatestVersion(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue