Merge pull request #372 from nhooyr/fix-sudo-86ee

install.sh: Improve default $PREFIX behaviour
This commit is contained in:
Anmol Sethi 2022-12-06 00:22:35 -08:00 committed by GitHub
commit 030f95441d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 372 additions and 228 deletions

View file

@ -10,10 +10,11 @@ VERSION=$VERSION sh_c eval "'$HW_BUILD_DIR/README.md.sh'" \> "'$HW_BUILD_DIR/REA
sh_c rm -f "$HW_BUILD_DIR/README.md.sh" sh_c rm -f "$HW_BUILD_DIR/README.md.sh"
sh_c find "$HW_BUILD_DIR" -exec touch {} \\\; sh_c find "$HW_BUILD_DIR" -exec touch {} \\\;
export GOOS=$(goos "$OS") ensure_goos
export GOARCH="$ARCH" ensure_goarch
sh_c mkdir -p "$HW_BUILD_DIR/bin" sh_c mkdir -p "$HW_BUILD_DIR/bin"
sh_c go build -ldflags "'-X oss.terrastruct.com/d2/lib/version.Version=$VERSION'" \ sh_c CGO_ENABLED=0 go build \
-ldflags "'-X oss.terrastruct.com/d2/lib/version.Version=$VERSION'" \
-o "$HW_BUILD_DIR/bin/d2" . -o "$HW_BUILD_DIR/bin/d2" .
ARCHIVE=$PWD/$ARCHIVE ARCHIVE=$PWD/$ARCHIVE

View file

@ -14,7 +14,7 @@ help() {
fi fi
cat <<EOF cat <<EOF
usage: $arg0 [-d|--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local] usage: $arg0 [-d|--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix path]
[--tala latest] [--force] [--uninstall] [--tala latest] [--force] [--uninstall]
install.sh automates the installation of D2 onto your system. It currently only supports install.sh automates the installation of D2 onto your system. It currently only supports
@ -24,6 +24,9 @@ docs for --detect below for more information
If you pass --edge, it will clone the source, build a release and install from it. If you pass --edge, it will clone the source, build a release and install from it.
--edge is incompatible with --tala and currently unimplemented. --edge is incompatible with --tala and currently unimplemented.
\$PREFIX in the docs below refers to the path set by --prefix. See docs on the --prefix
flag below for the default.
Flags: Flags:
-d, --dry-run -d, --dry-run
@ -51,30 +54,31 @@ Flags:
So far it only detects macOS and automatically uses homebrew. So far it only detects macOS and automatically uses homebrew.
- homebrew uses https://brew.sh/ which is a macOS and Linux package manager. - homebrew uses https://brew.sh/ which is a macOS and Linux package manager.
- standalone installs a standalone release archive into the unix hierarchy path - standalone installs a standalone release archive into the unix hierarchy path
specified by --prefix which defaults to /usr/local specified by --prefix
Ensure /usr/local/bin is in your \$PATH to use it.
--prefix /usr/local --prefix path
Controls the unix hierarchy path into which standalone releases are installed. 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. Defaults to /usr/local or ~/.local if /usr/local is not writable by the current user.
We use ~/.local by default on arm64 macOS machines as SIP now disables access to Remember that whatever you use, you must have the bin directory of your prefix path in
/usr/local. Remember that whatever you use, you must have the bin directory of your \$PATH to execute the d2 binary. For example, if my prefix directory is /usr/local then
prefix path in \$PATH to execute the d2 binary. For example, if my prefix directory is my \$PATH must contain /usr/local/bin.
/usr/local then my \$PATH must contain /usr/local/bin. You may also need to include \$PREFIX/share/man into \$MANPATH.
install.sh will tell you whether \$PATH or \$MANPATH need to be updated after successful
installation.
--tala [latest] --tala [latest]
Install Terrastruct's closed source TALA for improved layouts. Install Terrastruct's closed source TALA for improved layouts.
See https://github.com/terrastruct/tala See https://github.com/terrastruct/tala
It optionally takes an argument of the TALA version to install. It optionally takes an argument of the TALA version to install.
Installation obeys all other flags, just like the installation of d2. For example, 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 the d2plugin-tala binary will be installed into \$PREFIX/bin/d2plugin-tala
warn: The version may not be obeyed with package manager installations. Use warn: The version may not be obeyed with package manager installations. Use
--method=standalone to enforce the version. --method=standalone to enforce the version.
--force: --force:
Force installation over the existing version even if they match. It will attempt a 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 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 will be deleted from \$PREFIX/lib/d2/d2-<VERSION> but the release archive in
~/.cache/d2/release will remain. ~/.cache/d2/release will remain.
--uninstall: --uninstall:
@ -85,7 +89,7 @@ Flags:
note: tala will also be uninstalled if installed. note: tala will also be uninstalled if installed.
All downloaded archives are cached into ~/.cache/d2/release. use \$XDG_CACHE_HOME to change 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> path of the cached assets. Release archives are unarchived into \$PREFIX/lib/d2/d2-<VERSION>
note: Deleting the unarchived releases will cause --uninstall to stop working. note: Deleting the unarchived releases will cause --uninstall to stop working.
@ -150,13 +154,9 @@ main() {
fi fi
REPO=${REPO:-terrastruct/d2} REPO=${REPO:-terrastruct/d2}
OS=$(os) ensure_os
ARCH=$(arch) ensure_arch
if [ -z "${PREFIX-}" -a "$OS" = macos -a "$ARCH" = arm64 ]; then ensure_prefix
# M1 Mac's do not allow modifications to /usr/local even with sudo.
PREFIX=$HOME/.local
fi
PREFIX=${PREFIX:-/usr/local}
CACHE_DIR=$(cache_dir) CACHE_DIR=$(cache_dir)
mkdir -p "$CACHE_DIR" mkdir -p "$CACHE_DIR"
METHOD=${METHOD:-detect} METHOD=${METHOD:-detect}
@ -318,11 +318,7 @@ install_d2_standalone() {
asset_url=$(sh_c 'sed -n $((asset_line-3))p "$RELEASE_INFO" | sed "s/^.*: \"\(.*\)\",$/\1/g"') asset_url=$(sh_c 'sed -n $((asset_line-3))p "$RELEASE_INFO" | sed "s/^.*: \"\(.*\)\",$/\1/g"')
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream' fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
sh_c="sh_c" ensure_prefix_sh_c
if ! is_prefix_writable; then
sh_c="sudo_sh_c"
fi
"$sh_c" mkdir -p "'$INSTALL_DIR'" "$sh_c" mkdir -p "'$INSTALL_DIR'"
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE" "$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$VERSION\" && make install PREFIX=\"$PREFIX\"'" "$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
@ -365,11 +361,7 @@ install_tala_standalone() {
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream' fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
sh_c="sh_c" ensure_prefix_sh_c
if ! is_prefix_writable; then
sh_c="sudo_sh_c"
fi
"$sh_c" mkdir -p "'$INSTALL_DIR'" "$sh_c" mkdir -p "'$INSTALL_DIR'"
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE" "$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$VERSION\" && make install PREFIX=\"$PREFIX\"'" "$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
@ -417,11 +409,7 @@ uninstall_d2_standalone() {
return 1 return 1
fi fi
sh_c="sh_c" ensure_prefix_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" sh -c "'cd \"$INSTALL_DIR/d2-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
"$sh_c" rm -rf "$INSTALL_DIR/d2-$INSTALLED_VERSION" "$sh_c" rm -rf "$INSTALL_DIR/d2-$INSTALLED_VERSION"
} }
@ -439,11 +427,7 @@ uninstall_tala_standalone() {
return 1 return 1
fi fi
sh_c="sh_c" ensure_prefix_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" sh -c "'cd \"$INSTALL_DIR/tala-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
"$sh_c" rm -rf "$INSTALL_DIR/tala-$INSTALLED_VERSION" "$sh_c" rm -rf "$INSTALL_DIR/tala-$INSTALLED_VERSION"
} }
@ -452,13 +436,6 @@ uninstall_tala_brew() {
sh_c brew remove tala sh_c brew remove tala
} }
is_prefix_writable() {
# The reason for checking whether $INSTALL_DIR is writable 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.
is_writable_dir "$INSTALL_DIR"
}
cache_dir() { cache_dir() {
if [ -n "${XDG_CACHE_HOME-}" ]; then if [ -n "${XDG_CACHE_HOME-}" ]; then
echo "$XDG_CACHE_HOME/d2/release" echo "$XDG_CACHE_HOME/d2/release"
@ -475,7 +452,7 @@ fetch_release_info() {
fi fi
log "fetching info on $VERSION version of $REPO" log "fetching info on $VERSION version of $REPO"
RELEASE_INFO=$(mktemp -d)/release-info.json RELEASE_INFO=$(mktempd)/release-info.json
if [ "$VERSION" = latest ]; then if [ "$VERSION" = latest ]; then
release_info_url="https://api.github.com/repos/$REPO/releases/$VERSION" release_info_url="https://api.github.com/repos/$REPO/releases/$VERSION"
else else

View file

@ -109,11 +109,14 @@ main() {
VERSION=${VERSION:-$(git_describe_ref)} VERSION=${VERSION:-$(git_describe_ref)}
BUILD_DIR=ci/release/build/$VERSION BUILD_DIR=ci/release/build/$VERSION
if [ -n "${HOST_ONLY-}" ]; then if [ -n "${HOST_ONLY-}" ]; then
runjob $(os)-$(arch) "OS=$(os) ARCH=$(arch) build" OS=$(os)
ARCH=$(arch)
runjob "$OS-$ARCH" "build"
if [ -n "${INSTALL-}" ]; then if [ -n "${INSTALL-}" ]; then
( sh_c make -sC "ci/release/build/$VERSION/$(os)-$(arch)/d2-$VERSION" install) sh_c make -sC "ci/release/build/$VERSION/$(os)-$(arch)/d2-$VERSION" install
elif [ -n "${UNINSTALL-}" ]; then elif [ -n "${UNINSTALL-}" ]; then
( sh_c make -sC "ci/release/build/$VERSION/$(os)-$(arch)/d2-$VERSION" uninstall) sh_c make -sC "ci/release/build/$VERSION/$(os)-$(arch)/d2-$VERSION" uninstall
fi fi
return 0 return 0
fi fi
@ -123,7 +126,7 @@ main() {
runjob macos-amd64 'OS=macos ARCH=amd64 build' & runjob macos-amd64 'OS=macos ARCH=amd64 build' &
runjob macos-arm64 'OS=macos ARCH=arm64 build' & runjob macos-arm64 'OS=macos ARCH=arm64 build' &
runjob windows-amd64 'OS=windows ARCH=amd64 build' & runjob windows-amd64 'OS=windows ARCH=amd64 build' &
runjob windows-arm64 'OS=macos ARCH=arm64 build' & runjob windows-arm64 'OS=windows ARCH=arm64 build' &
waitjobs waitjobs
} }
@ -189,8 +192,7 @@ build_local() {
build_remote_macos() { build_remote_macos() {
sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock
sh_c ssh "$REMOTE_HOST" mkdir -p src sh_c gitsync "$REMOTE_HOST" src/d2
sh_c rsync --archive --human-readable --delete ./ "$REMOTE_HOST:src/d2/"
sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \ sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \
TERM=${TERM-} \ TERM=${TERM-} \
DRY_RUN=${DRY_RUN-} \ DRY_RUN=${DRY_RUN-} \
@ -207,8 +209,7 @@ PATH=\\\"/usr/local/bin:/usr/local/sbin:/opt/homebrew/bin:/opt/homebrew/sbin\\\$
build_remote_linux() { build_remote_linux() {
sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock
sh_c ssh "$REMOTE_HOST" mkdir -p src sh_c gitsync "$REMOTE_HOST" src/d2
sh_c rsync --archive --human-readable --delete ./ "$REMOTE_HOST:src/d2/"
sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \ sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \
TERM=${TERM-} \ TERM=${TERM-} \
DRY_RUN=${DRY_RUN-} \ DRY_RUN=${DRY_RUN-} \

View file

@ -250,10 +250,29 @@ init_remote_macos() {
fi fi
sleep 5 sleep 5
done done
sh_c ssh "$REMOTE_HOST" '"/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""' sh_c ssh "$REMOTE_HOST" '"/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""'
sh_c ssh "$REMOTE_HOST" 'PATH="/usr/local/bin:/opt/homebrew/bin:\$PATH" brew update'
sh_c ssh "$REMOTE_HOST" 'PATH="/usr/local/bin:/opt/homebrew/bin:\$PATH" brew upgrade' if sh_c ssh "$REMOTE_HOST" uname -m | grep -qF arm64; then
sh_c ssh "$REMOTE_HOST" 'PATH="/usr/local/bin:/opt/homebrew/bin:\$PATH" brew install go' shellenv=$(sh_c ssh "$REMOTE_HOST" /opt/homebrew/bin/brew shellenv)
else
shellenv=$(sh_c ssh "$REMOTE_HOST" /usr/local/bin/brew shellenv)
fi
if ! echo "$shellenv" | sh_c ssh "$REMOTE_HOST" "IFS= read -r regex\; \"grep -qF \\\"\\\$regex\\\" ~/.zshrc\""; then
echo "$shellenv" | sh_c ssh "$REMOTE_HOST" "\"(echo && cat) >> ~/.zshrc\""
fi
# macOS is a joke.
sh_c ssh "$REMOTE_HOST" '"rm -f ~/.ssh/environment"'
sh_c ssh "$REMOTE_HOST" '"echo PATH=\$HOME/.local/bin:\$(. ~/.zshrc && echo "\$PATH") >\$HOME/.ssh/environment"'
sh_c ssh "$REMOTE_HOST" '"echo MANPATH=\$HOME/.local/share/man:\$(. ~/.zshrc && echo "\$MANPATH") >>\$HOME/.ssh/environment"'
sh_c ssh "$REMOTE_HOST" "sudo sed -i.bak '\"s/#PermitUserEnvironment no/PermitUserEnvironment yes/\"' /etc/ssh/sshd_config"
sh_c ssh "$REMOTE_HOST" "sudo launchctl stop com.openssh.sshd"
sh_c ssh "$REMOTE_HOST" brew update
sh_c ssh "$REMOTE_HOST" brew upgrade
sh_c ssh "$REMOTE_HOST" brew install go rsync
} }
main "$@" main "$@"

View file

@ -57,6 +57,11 @@ PRs when it's a visual change.
- `d2` now lives in the root folder of the repository instead of as a subcommand. So you - `d2` now lives in the root folder of the repository instead of as a subcommand. So you
can now run `go install oss.terrastruct.com/d2@latest` to install from source. can now run `go install oss.terrastruct.com/d2@latest` to install from source.
[#290](https://github.com/terrastruct/d2/pull/290) [#290](https://github.com/terrastruct/d2/pull/290)
- `install.sh` defaults to installation to `/usr/local` as before but now if
`/usr/local` is not accessible to the current user, it will use `~/.local`
instead of prompting for sudo. You can pass `--prefix /usr/local` to force
installation into `/usr/local` with a prompt for sudo.
[#372](https://github.com/terrastruct/d2/pull/372)
#### Bugfixes ⛑️ #### Bugfixes ⛑️

View file

@ -14,6 +14,7 @@ set -eu
# install.sh was bundled together from # install.sh was bundled together from
# #
# - ./ci/sub/lib/rand.sh # - ./ci/sub/lib/rand.sh
# - ./ci/sub/lib/temp.sh
# - ./ci/sub/lib/log.sh # - ./ci/sub/lib/log.sh
# - ./ci/sub/lib/flag.sh # - ./ci/sub/lib/flag.sh
# - ./ci/sub/lib/release.sh # - ./ci/sub/lib/release.sh
@ -30,6 +31,7 @@ EOF
# script. # script.
sh_c cat \ sh_c cat \
./ci/sub/lib/rand.sh \ ./ci/sub/lib/rand.sh \
./ci/sub/lib/temp.sh \
./ci/sub/lib/log.sh \ ./ci/sub/lib/log.sh \
./ci/sub/lib/flag.sh \ ./ci/sub/lib/flag.sh \
./ci/sub/lib/release.sh \ ./ci/sub/lib/release.sh \

View file

@ -13,6 +13,7 @@ sh_c cat >./ci/release/template/scripts/lib.sh <<EOF
# lib.sh was bundled together from # lib.sh was bundled together from
# #
# - ./ci/sub/lib/rand.sh # - ./ci/sub/lib/rand.sh
# - ./ci/sub/lib/temp.sh
# - ./ci/sub/lib/log.sh # - ./ci/sub/lib/log.sh
# - ./ci/sub/lib/release.sh # - ./ci/sub/lib/release.sh
# #
@ -25,6 +26,7 @@ EOF
# script. # script.
sh_c cat \ sh_c cat \
./ci/sub/lib/rand.sh \ ./ci/sub/lib/rand.sh \
./ci/sub/lib/temp.sh \
./ci/sub/lib/log.sh \ ./ci/sub/lib/log.sh \
./ci/sub/lib/release.sh \ ./ci/sub/lib/release.sh \
\| sed "-e'/^\. /d'" \>\>./ci/release/template/scripts/lib.sh \| sed "-e'/^\. /d'" \>\>./ci/release/template/scripts/lib.sh

View file

@ -3,15 +3,13 @@
.PHONY: all .PHONY: all
all: all:
(. ./scripts/lib.sh && echoerr "You must provide a target of install or uninstall for this Makefile") ( . ./scripts/lib.sh && echoerr "You must provide a target of install or uninstall for this Makefile" )
exit 1 exit 1
PREFIX = $(DESTDIR)/usr/local
.PHONY: install .PHONY: install
install: install:
PREFIX='$(PREFIX)' ./scripts/install.sh ./scripts/install.sh
.PHONY: uninstall .PHONY: uninstall
uninstall: uninstall:
PREFIX='$(PREFIX)' ./scripts/uninstall.sh ./scripts/uninstall.sh

View file

@ -13,16 +13,17 @@ version: $VERSION
\`\`\`sh \`\`\`sh
make install DRY_RUN=1 make install DRY_RUN=1
# If it looks right, run: # If it looks right, run:
make install # make install
\`\`\` \`\`\`
Pass \`PREFIX=whatever\` to change the installation prefix. Pass \`PREFIX=somepath\` to change the installation prefix from the default which is
\`/usr/local\` or \`~/.local\` if \`/usr/local\` is not writable with the current user.
## Uninstall ## Uninstall
\`\`\`sh \`\`\`sh
make uninstall DRY_RUN=1 make uninstall DRY_RUN=1
# If it looks right, run: # If it looks right, run:
make uninstall # make uninstall
\`\`\` \`\`\`
EOF EOF

View file

@ -4,16 +4,7 @@ cd -- "$(dirname "$0")/.."
. ./scripts/lib.sh . ./scripts/lib.sh
main() { main() {
if [ -z "${PREFIX-}" ]; then ensure_prefix_sh_c
echoerr "\$PREFIX must be set to a unix prefix directory in which to install d2 like /usr/local"
return 1
fi
sh_c="sh_c"
if ! is_writable_dir "$PREFIX/bin"; then
sh_c="sudo_sh_c"
fi
"$sh_c" mkdir -p "$PREFIX/bin" "$sh_c" mkdir -p "$PREFIX/bin"
"$sh_c" install ./bin/d2 "$PREFIX/bin/d2" "$sh_c" install ./bin/d2 "$PREFIX/bin/d2"
"$sh_c" mkdir -p "$PREFIX/share/man/man1" "$sh_c" mkdir -p "$PREFIX/share/man/man1"

View file

@ -6,6 +6,7 @@
# lib.sh was bundled together from # lib.sh was bundled together from
# #
# - ./ci/sub/lib/rand.sh # - ./ci/sub/lib/rand.sh
# - ./ci/sub/lib/temp.sh
# - ./ci/sub/lib/log.sh # - ./ci/sub/lib/log.sh
# - ./ci/sub/lib/release.sh # - ./ci/sub/lib/release.sh
# #
@ -22,12 +23,15 @@ pick() {
seed="$1" seed="$1"
shift shift
seed_file="$(mktemp)" seed_file="$(mktempd)/pickseed"
echo "$seed" >"$seed_file"
# We add 16 more bytes to the seed file for sufficient entropy. Otherwise both Cygwin's # We add 32 more bytes to the seed file for sufficient entropy. Otherwise both Cygwin's
# and MinGW's sort for example complains about the lack of entropy on stderr and writes # and MinGW's sort for example complains about the lack of entropy on stderr and writes
# nothing to stdout. I'm sure there are more platforms that would too. # nothing to stdout. I'm sure there are more platforms that would too.
echo "================" >"$seed_file" #
# We also limit to a max of 32 bytes as otherwise macOS's sort complains that the random
# seed is too large. Probably more platforms too.
(echo "$seed" && echo "================================") | head -c32 >"$seed_file"
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
echo "$1" echo "$1"
@ -37,6 +41,44 @@ pick() {
| head -n1 | head -n1
} }
#!/bin/sh #!/bin/sh
if [ "${LIB_TEMP-}" ]; then
return 0
fi
LIB_TEMP=1
ensure_tmpdir() {
if [ -n "${_TMPDIR-}" ]; then
return
fi
_TMPDIR=$(mktemp -d)
export _TMPDIR
trap temp_exittrap EXIT
}
temp_exittrap() {
if [ -n "${_TMPDIR-}" ]; then
rm -r "$_TMPDIR"
fi
}
temppath() {
ensure_tmpdir
while true; do
temppath=$_TMPDIR/$(</dev/urandom head -c8 | base64)
if [ ! -e "$temppath" ]; then
echo "$temppath"
return
fi
done
}
mktempd() {
tp=$(temppath)
mkdir -p "$tp"
echo "$tp"
}
#!/bin/sh
if [ "${LIB_LOG-}" ]; then if [ "${LIB_LOG-}" ]; then
return 0 return 0
fi fi
@ -89,16 +131,20 @@ _echo() {
printf '%s\n' "$*" printf '%s\n' "$*"
} }
# 1-6 are regular and 9-14 are bright.
get_rand_color() { get_rand_color() {
colors="" if [ "${TERM_COLORS+x}" != x ]; then
ncolors=$(command tput colors) TERM_COLORS=""
if [ "$ncolors" -ge 8 ]; then export TERM_COLORS
colors="$colors 1 2 3 4 5 6" ncolors=$(TERM=${TERM:-xterm-256color} command tput colors)
elif [ "$ncolors" -ge 16 ]; then if [ "$ncolors" -ge 8 ]; then
colors="$colors 9 10 11 12 13 14" # 1-6 are regular
TERM_COLORS="$TERM_COLORS 1 2 3 4 5 6"
elif [ "$ncolors" -ge 16 ]; then
# 9-14 are bright.
TERM_COLORS="$TERM_COLORS 9 10 11 12 13 14"
fi
fi fi
pick "$*" $colors pick "$*" $TERM_COLORS
} }
echop() { echop() {
@ -117,14 +163,12 @@ printfp() {(
prefix="$1" prefix="$1"
shift shift
if [ -z "${FGCOLOR-}" ]; then _FGCOLOR=${FGCOLOR:-$(get_rand_color "$prefix")}
FGCOLOR="$(get_rand_color "$prefix")"
fi
should_color || true should_color || true
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
printf '%s' "$(COLOR=$__COLOR setaf "$FGCOLOR" "$prefix")" printf '%s' "$(COLOR=$__COLOR setaf "$_FGCOLOR" "$prefix")"
else else
printf '%s: %s\n' "$(COLOR=$__COLOR setaf "$FGCOLOR" "$prefix")" "$(printf "$@")" printf '%s: %s\n' "$(COLOR=$__COLOR setaf "$_FGCOLOR" "$prefix")" "$(printf "$@")"
fi fi
)} )}
@ -215,7 +259,7 @@ sudo_sh_c() {
sh_c "su root -c '$*'" sh_c "su root -c '$*'"
else else
caterr <<EOF caterr <<EOF
This script needs to run the following command as root: Unable to run the following command as root:
$* $*
Please install doas, sudo, or su. Please install doas, sudo, or su.
EOF EOF
@ -245,11 +289,8 @@ humanpath() {
} }
hide() { hide() {
out="$(mktemp)" out="$(mktempd)/hideout"
set +e capcode "$@" >"$out" 2>&1
"$@" >"$out" 2>&1
code="$?"
set -e
if [ "$code" -eq 0 ]; then if [ "$code" -eq 0 ]; then
return return
fi fi
@ -267,7 +308,7 @@ echo_dur() {
sponge() { sponge() {
dst="$1" dst="$1"
tmp="$(mktemp)" tmp="$(mktempd)/sponge"
cat > "$tmp" cat > "$tmp"
cat "$tmp" > "$dst" cat "$tmp" > "$dst"
} }
@ -302,36 +343,60 @@ capcode() {
code=$? code=$?
set -e set -e
} }
strjoin() {
(IFS="$1"; shift; echo "$*")
}
#!/bin/sh #!/bin/sh
if [ "${LIB_RELEASE-}" ]; then if [ "${LIB_RELEASE-}" ]; then
return 0 return 0
fi fi
LIB_RELEASE=1 LIB_RELEASE=1
goos() { ensure_goos() {
case $1 in if [ -n "${GOOS-}" ]; then
macos) echo darwin;; return
*) echo $1;; fi
ensure_os
case "$OS" in
macos) export GOOS=darwin;;
*) export GOOS=$OS;;
esac esac
} }
os() { ensure_goarch() {
if [ -n "${GOARCH-}" ]; then
return
fi
ensure_arch
case "$ARCH" in
*) export GOARCH=$ARCH;;
esac
}
ensure_os() {
if [ -n "${OS-}" ]; then
return
fi
uname=$(uname) uname=$(uname)
case $uname in case $uname in
Linux) echo linux;; Linux) OS=linux;;
Darwin) echo macos;; Darwin) OS=macos;;
FreeBSD) echo freebsd;; FreeBSD) OS=freebsd;;
CYGWIN_NT*|MINGW32_NT*) echo windows;; CYGWIN_NT*|MINGW32_NT*) OS=windows;;
*) echo "$uname";; *) OS=$uname;;
esac esac
} }
arch() { ensure_arch() {
if [ -n "${ARCH-}" ]; then
return
fi
uname_m=$(uname -m) uname_m=$(uname -m)
case $uname_m in case $uname_m in
aarch64) echo arm64;; aarch64) ARCH=arm64;;
x86_64) echo amd64;; x86_64) ARCH=amd64;;
*) echo "$uname_m";; *) ARCH=$uname_m;;
esac esac
} }
@ -350,9 +415,34 @@ manpath() {
} }
is_writable_dir() { is_writable_dir() {
# The path has to exist for -w to succeed. # If it can be created, we can use it.
sh_c "mkdir -p '$1' 2>/dev/null" || true sh_c "mkdir -p '$1' 2>/dev/null"
if [ ! -w "$1" ]; then }
return 1
ensure_prefix() {
if [ -n "${PREFIX-}" ]; then
return
fi
# The reason for checking whether bin is writable 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
# need to do.
if ! is_writable_dir "/usr/local/bin"; then
# This also handles M1 Mac's which do not allow modifications to /usr/local even
# with sudo.
PREFIX=$HOME/.local
else
PREFIX=/usr/local
fi
}
ensure_prefix_sh_c() {
ensure_prefix
sh_c="sh_c"
# The reason for checking whether bin is writable 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
# need to do.
if ! is_writable_dir "$PREFIX/bin"; then
sh_c="sudo_sh_c"
fi fi
} }

View file

@ -4,16 +4,7 @@ cd -- "$(dirname "$0")/.."
. ./scripts/lib.sh . ./scripts/lib.sh
main() { main() {
if [ -z "${PREFIX-}" ]; then ensure_prefix_sh_c
echoerr "\$PREFIX must be set to a unix prefix directory from which to uninstall d2 like /usr/local"
return 1
fi
sh_c="sh_c"
if ! is_writable_dir "$PREFIX/bin"; then
sh_c="sudo_sh_c"
fi
"$sh_c" rm -f "$PREFIX/bin/d2" "$sh_c" rm -f "$PREFIX/bin/d2"
"$sh_c" rm -f "$PREFIX/share/man/man1/d2.1" "$sh_c" rm -f "$PREFIX/share/man/man1/d2.1"
} }

2
ci/sub

@ -1 +1 @@
Subproject commit ad50bf9f1e302bfb1a4d3c6bb821f90979083265 Subproject commit b29dc9d5bfce87576fd15b3cee2249762b7f0d3d

View file

@ -236,6 +236,9 @@ func (gs *dslGenState) randShape() string {
if s != "image" { if s != "image" {
return s return s
} }
if s != "sequence_diagram" {
return s
}
} }
} }

View file

@ -47,9 +47,9 @@ We're careful shell programmers and are aware of the many footguns of the Unix s
script was written carefully and with detail. For example, it is not vulnerable to partial script was written carefully and with detail. For example, it is not vulnerable to partial
execution and the entire script runs with `set -eu` and very meticulous quoting. execution and the entire script runs with `set -eu` and very meticulous quoting.
It follows the XDG standards, installs `d2` properly into a Unix hierarchy path (defaulting It follows the XDG standards, installs `d2` properly into a Unix hierarchy path
to /usr/local though you can use ~/.local to avoid sudo if you'd like) and allows for easy (`/usr/local` unless `/usr/local` requires sudo in which case `~/.local` is used) and
uninstall. allows for easy uninstall. You can easily adjust the used path with `--prefix`.
Some other niceties are that it'll tell you if you need to adjust `$PATH` or `$MANPATH` to Some other niceties are that it'll tell you if you need to adjust `$PATH` or `$MANPATH` to
access `d2` and its manpages. It can also install access `d2` and its manpages. It can also install
@ -126,10 +126,6 @@ The install script places the standalone release into `$PREFIX/lib/d2/d2-<versio
and we recommend doing the same with manually installed releases so that you and we recommend doing the same with manually installed releases so that you
know where the release directory is for easy uninstall. know where the release directory is for easy uninstall.
> warn: Our binary releases aren't fully static like normal Go binaries due to the C
> dependency on v8go for executing dagre. If you're on an older system with an old
> libc, you'll want to install from source.
## From source ## From source
You can always install from source: You can always install from source:

View file

@ -7,6 +7,7 @@ set -eu
# install.sh was bundled together from # install.sh was bundled together from
# #
# - ./ci/sub/lib/rand.sh # - ./ci/sub/lib/rand.sh
# - ./ci/sub/lib/temp.sh
# - ./ci/sub/lib/log.sh # - ./ci/sub/lib/log.sh
# - ./ci/sub/lib/flag.sh # - ./ci/sub/lib/flag.sh
# - ./ci/sub/lib/release.sh # - ./ci/sub/lib/release.sh
@ -27,12 +28,15 @@ pick() {
seed="$1" seed="$1"
shift shift
seed_file="$(mktemp)" seed_file="$(mktempd)/pickseed"
echo "$seed" >"$seed_file"
# We add 16 more bytes to the seed file for sufficient entropy. Otherwise both Cygwin's # We add 32 more bytes to the seed file for sufficient entropy. Otherwise both Cygwin's
# and MinGW's sort for example complains about the lack of entropy on stderr and writes # and MinGW's sort for example complains about the lack of entropy on stderr and writes
# nothing to stdout. I'm sure there are more platforms that would too. # nothing to stdout. I'm sure there are more platforms that would too.
echo "================" >"$seed_file" #
# We also limit to a max of 32 bytes as otherwise macOS's sort complains that the random
# seed is too large. Probably more platforms too.
(echo "$seed" && echo "================================") | head -c32 >"$seed_file"
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
echo "$1" echo "$1"
@ -42,6 +46,44 @@ pick() {
| head -n1 | head -n1
} }
#!/bin/sh #!/bin/sh
if [ "${LIB_TEMP-}" ]; then
return 0
fi
LIB_TEMP=1
ensure_tmpdir() {
if [ -n "${_TMPDIR-}" ]; then
return
fi
_TMPDIR=$(mktemp -d)
export _TMPDIR
trap temp_exittrap EXIT
}
temp_exittrap() {
if [ -n "${_TMPDIR-}" ]; then
rm -r "$_TMPDIR"
fi
}
temppath() {
ensure_tmpdir
while true; do
temppath=$_TMPDIR/$(</dev/urandom head -c8 | base64)
if [ ! -e "$temppath" ]; then
echo "$temppath"
return
fi
done
}
mktempd() {
tp=$(temppath)
mkdir -p "$tp"
echo "$tp"
}
#!/bin/sh
if [ "${LIB_LOG-}" ]; then if [ "${LIB_LOG-}" ]; then
return 0 return 0
fi fi
@ -94,16 +136,20 @@ _echo() {
printf '%s\n' "$*" printf '%s\n' "$*"
} }
# 1-6 are regular and 9-14 are bright.
get_rand_color() { get_rand_color() {
colors="" if [ "${TERM_COLORS+x}" != x ]; then
ncolors=$(command tput colors) TERM_COLORS=""
if [ "$ncolors" -ge 8 ]; then export TERM_COLORS
colors="$colors 1 2 3 4 5 6" ncolors=$(TERM=${TERM:-xterm-256color} command tput colors)
elif [ "$ncolors" -ge 16 ]; then if [ "$ncolors" -ge 8 ]; then
colors="$colors 9 10 11 12 13 14" # 1-6 are regular
TERM_COLORS="$TERM_COLORS 1 2 3 4 5 6"
elif [ "$ncolors" -ge 16 ]; then
# 9-14 are bright.
TERM_COLORS="$TERM_COLORS 9 10 11 12 13 14"
fi
fi fi
pick "$*" $colors pick "$*" $TERM_COLORS
} }
echop() { echop() {
@ -122,14 +168,12 @@ printfp() {(
prefix="$1" prefix="$1"
shift shift
if [ -z "${FGCOLOR-}" ]; then _FGCOLOR=${FGCOLOR:-$(get_rand_color "$prefix")}
FGCOLOR="$(get_rand_color "$prefix")"
fi
should_color || true should_color || true
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
printf '%s' "$(COLOR=$__COLOR setaf "$FGCOLOR" "$prefix")" printf '%s' "$(COLOR=$__COLOR setaf "$_FGCOLOR" "$prefix")"
else else
printf '%s: %s\n' "$(COLOR=$__COLOR setaf "$FGCOLOR" "$prefix")" "$(printf "$@")" printf '%s: %s\n' "$(COLOR=$__COLOR setaf "$_FGCOLOR" "$prefix")" "$(printf "$@")"
fi fi
)} )}
@ -220,7 +264,7 @@ sudo_sh_c() {
sh_c "su root -c '$*'" sh_c "su root -c '$*'"
else else
caterr <<EOF caterr <<EOF
This script needs to run the following command as root: Unable to run the following command as root:
$* $*
Please install doas, sudo, or su. Please install doas, sudo, or su.
EOF EOF
@ -250,11 +294,8 @@ humanpath() {
} }
hide() { hide() {
out="$(mktemp)" out="$(mktempd)/hideout"
set +e capcode "$@" >"$out" 2>&1
"$@" >"$out" 2>&1
code="$?"
set -e
if [ "$code" -eq 0 ]; then if [ "$code" -eq 0 ]; then
return return
fi fi
@ -272,7 +313,7 @@ echo_dur() {
sponge() { sponge() {
dst="$1" dst="$1"
tmp="$(mktemp)" tmp="$(mktempd)/sponge"
cat > "$tmp" cat > "$tmp"
cat "$tmp" > "$dst" cat "$tmp" > "$dst"
} }
@ -307,6 +348,10 @@ capcode() {
code=$? code=$?
set -e set -e
} }
strjoin() {
(IFS="$1"; shift; echo "$*")
}
#!/bin/sh #!/bin/sh
if [ "${LIB_FLAG-}" ]; then if [ "${LIB_FLAG-}" ]; then
return 0 return 0
@ -444,30 +489,50 @@ if [ "${LIB_RELEASE-}" ]; then
fi fi
LIB_RELEASE=1 LIB_RELEASE=1
goos() { ensure_goos() {
case $1 in if [ -n "${GOOS-}" ]; then
macos) echo darwin;; return
*) echo $1;; fi
ensure_os
case "$OS" in
macos) export GOOS=darwin;;
*) export GOOS=$OS;;
esac esac
} }
os() { ensure_goarch() {
if [ -n "${GOARCH-}" ]; then
return
fi
ensure_arch
case "$ARCH" in
*) export GOARCH=$ARCH;;
esac
}
ensure_os() {
if [ -n "${OS-}" ]; then
return
fi
uname=$(uname) uname=$(uname)
case $uname in case $uname in
Linux) echo linux;; Linux) OS=linux;;
Darwin) echo macos;; Darwin) OS=macos;;
FreeBSD) echo freebsd;; FreeBSD) OS=freebsd;;
CYGWIN_NT*|MINGW32_NT*) echo windows;; CYGWIN_NT*|MINGW32_NT*) OS=windows;;
*) echo "$uname";; *) OS=$uname;;
esac esac
} }
arch() { ensure_arch() {
if [ -n "${ARCH-}" ]; then
return
fi
uname_m=$(uname -m) uname_m=$(uname -m)
case $uname_m in case $uname_m in
aarch64) echo arm64;; aarch64) ARCH=arm64;;
x86_64) echo amd64;; x86_64) ARCH=amd64;;
*) echo "$uname_m";; *) ARCH=$uname_m;;
esac esac
} }
@ -486,10 +551,35 @@ manpath() {
} }
is_writable_dir() { is_writable_dir() {
# The path has to exist for -w to succeed. # If it can be created, we can use it.
sh_c "mkdir -p '$1' 2>/dev/null" || true sh_c "mkdir -p '$1' 2>/dev/null"
if [ ! -w "$1" ]; then }
return 1
ensure_prefix() {
if [ -n "${PREFIX-}" ]; then
return
fi
# The reason for checking whether bin is writable 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
# need to do.
if ! is_writable_dir "/usr/local/bin"; then
# This also handles M1 Mac's which do not allow modifications to /usr/local even
# with sudo.
PREFIX=$HOME/.local
else
PREFIX=/usr/local
fi
}
ensure_prefix_sh_c() {
ensure_prefix
sh_c="sh_c"
# The reason for checking whether bin is writable 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
# need to do.
if ! is_writable_dir "$PREFIX/bin"; then
sh_c="sudo_sh_c"
fi fi
} }
#!/bin/sh #!/bin/sh
@ -503,7 +593,7 @@ help() {
fi fi
cat <<EOF cat <<EOF
usage: $arg0 [-d|--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix /usr/local] usage: $arg0 [-d|--dry-run] [--version vX.X.X] [--edge] [--method detect] [--prefix path]
[--tala latest] [--force] [--uninstall] [--tala latest] [--force] [--uninstall]
install.sh automates the installation of D2 onto your system. It currently only supports install.sh automates the installation of D2 onto your system. It currently only supports
@ -513,6 +603,9 @@ docs for --detect below for more information
If you pass --edge, it will clone the source, build a release and install from it. If you pass --edge, it will clone the source, build a release and install from it.
--edge is incompatible with --tala and currently unimplemented. --edge is incompatible with --tala and currently unimplemented.
\$PREFIX in the docs below refers to the path set by --prefix. See docs on the --prefix
flag below for the default.
Flags: Flags:
-d, --dry-run -d, --dry-run
@ -540,30 +633,31 @@ Flags:
So far it only detects macOS and automatically uses homebrew. So far it only detects macOS and automatically uses homebrew.
- homebrew uses https://brew.sh/ which is a macOS and Linux package manager. - homebrew uses https://brew.sh/ which is a macOS and Linux package manager.
- standalone installs a standalone release archive into the unix hierarchy path - standalone installs a standalone release archive into the unix hierarchy path
specified by --prefix which defaults to /usr/local specified by --prefix
Ensure /usr/local/bin is in your \$PATH to use it.
--prefix /usr/local --prefix path
Controls the unix hierarchy path into which standalone releases are installed. 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. Defaults to /usr/local or ~/.local if /usr/local is not writable by the current user.
We use ~/.local by default on arm64 macOS machines as SIP now disables access to Remember that whatever you use, you must have the bin directory of your prefix path in
/usr/local. Remember that whatever you use, you must have the bin directory of your \$PATH to execute the d2 binary. For example, if my prefix directory is /usr/local then
prefix path in \$PATH to execute the d2 binary. For example, if my prefix directory is my \$PATH must contain /usr/local/bin.
/usr/local then my \$PATH must contain /usr/local/bin. You may also need to include \$PREFIX/share/man into \$MANPATH.
install.sh will tell you whether \$PATH or \$MANPATH need to be updated after successful
installation.
--tala [latest] --tala [latest]
Install Terrastruct's closed source TALA for improved layouts. Install Terrastruct's closed source TALA for improved layouts.
See https://github.com/terrastruct/tala See https://github.com/terrastruct/tala
It optionally takes an argument of the TALA version to install. It optionally takes an argument of the TALA version to install.
Installation obeys all other flags, just like the installation of d2. For example, 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 the d2plugin-tala binary will be installed into \$PREFIX/bin/d2plugin-tala
warn: The version may not be obeyed with package manager installations. Use warn: The version may not be obeyed with package manager installations. Use
--method=standalone to enforce the version. --method=standalone to enforce the version.
--force: --force:
Force installation over the existing version even if they match. It will attempt a 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 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 will be deleted from \$PREFIX/lib/d2/d2-<VERSION> but the release archive in
~/.cache/d2/release will remain. ~/.cache/d2/release will remain.
--uninstall: --uninstall:
@ -574,7 +668,7 @@ Flags:
note: tala will also be uninstalled if installed. note: tala will also be uninstalled if installed.
All downloaded archives are cached into ~/.cache/d2/release. use \$XDG_CACHE_HOME to change 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> path of the cached assets. Release archives are unarchived into \$PREFIX/lib/d2/d2-<VERSION>
note: Deleting the unarchived releases will cause --uninstall to stop working. note: Deleting the unarchived releases will cause --uninstall to stop working.
@ -639,13 +733,9 @@ main() {
fi fi
REPO=${REPO:-terrastruct/d2} REPO=${REPO:-terrastruct/d2}
OS=$(os) ensure_os
ARCH=$(arch) ensure_arch
if [ -z "${PREFIX-}" -a "$OS" = macos -a "$ARCH" = arm64 ]; then ensure_prefix
# M1 Mac's do not allow modifications to /usr/local even with sudo.
PREFIX=$HOME/.local
fi
PREFIX=${PREFIX:-/usr/local}
CACHE_DIR=$(cache_dir) CACHE_DIR=$(cache_dir)
mkdir -p "$CACHE_DIR" mkdir -p "$CACHE_DIR"
METHOD=${METHOD:-detect} METHOD=${METHOD:-detect}
@ -807,11 +897,7 @@ install_d2_standalone() {
asset_url=$(sh_c 'sed -n $((asset_line-3))p "$RELEASE_INFO" | sed "s/^.*: \"\(.*\)\",$/\1/g"') asset_url=$(sh_c 'sed -n $((asset_line-3))p "$RELEASE_INFO" | sed "s/^.*: \"\(.*\)\",$/\1/g"')
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream' fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
sh_c="sh_c" ensure_prefix_sh_c
if ! is_prefix_writable; then
sh_c="sudo_sh_c"
fi
"$sh_c" mkdir -p "'$INSTALL_DIR'" "$sh_c" mkdir -p "'$INSTALL_DIR'"
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE" "$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$VERSION\" && make install PREFIX=\"$PREFIX\"'" "$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
@ -854,11 +940,7 @@ install_tala_standalone() {
fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream' fetch_gh "$asset_url" "$CACHE_DIR/$ARCHIVE" 'application/octet-stream'
sh_c="sh_c" ensure_prefix_sh_c
if ! is_prefix_writable; then
sh_c="sudo_sh_c"
fi
"$sh_c" mkdir -p "'$INSTALL_DIR'" "$sh_c" mkdir -p "'$INSTALL_DIR'"
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE" "$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$VERSION\" && make install PREFIX=\"$PREFIX\"'" "$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
@ -906,11 +988,7 @@ uninstall_d2_standalone() {
return 1 return 1
fi fi
sh_c="sh_c" ensure_prefix_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" sh -c "'cd \"$INSTALL_DIR/d2-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
"$sh_c" rm -rf "$INSTALL_DIR/d2-$INSTALLED_VERSION" "$sh_c" rm -rf "$INSTALL_DIR/d2-$INSTALLED_VERSION"
} }
@ -928,11 +1006,7 @@ uninstall_tala_standalone() {
return 1 return 1
fi fi
sh_c="sh_c" ensure_prefix_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" sh -c "'cd \"$INSTALL_DIR/tala-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
"$sh_c" rm -rf "$INSTALL_DIR/tala-$INSTALLED_VERSION" "$sh_c" rm -rf "$INSTALL_DIR/tala-$INSTALLED_VERSION"
} }
@ -941,13 +1015,6 @@ uninstall_tala_brew() {
sh_c brew remove tala sh_c brew remove tala
} }
is_prefix_writable() {
# The reason for checking whether $INSTALL_DIR is writable 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.
is_writable_dir "$INSTALL_DIR"
}
cache_dir() { cache_dir() {
if [ -n "${XDG_CACHE_HOME-}" ]; then if [ -n "${XDG_CACHE_HOME-}" ]; then
echo "$XDG_CACHE_HOME/d2/release" echo "$XDG_CACHE_HOME/d2/release"
@ -964,7 +1031,7 @@ fetch_release_info() {
fi fi
log "fetching info on $VERSION version of $REPO" log "fetching info on $VERSION version of $REPO"
RELEASE_INFO=$(mktemp -d)/release-info.json RELEASE_INFO=$(mktempd)/release-info.json
if [ "$VERSION" = latest ]; then if [ "$VERSION" = latest ]; then
release_info_url="https://api.github.com/repos/$REPO/releases/$VERSION" release_info_url="https://api.github.com/repos/$REPO/releases/$VERSION"
else else