Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

install.sh: Improve default $PREFIX behaviour #372

Merged
merged 6 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions ci/release/_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 find "$HW_BUILD_DIR" -exec touch {} \\\;

export GOOS=$(goos "$OS")
export GOARCH="$ARCH"
ensure_goos
ensure_goarch
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" .

ARCHIVE=$PWD/$ARCHIVE
Expand Down
71 changes: 24 additions & 47 deletions ci/release/_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ help() {
fi

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]

install.sh automates the installation of D2 onto your system. It currently only supports
Expand All @@ -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.
--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:

-d, --dry-run
Expand Down Expand Up @@ -51,30 +54,31 @@ Flags:
So far it only detects macOS and automatically uses homebrew.
- homebrew uses https://brew.sh/ which is a macOS and Linux package manager.
- 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.
specified by --prefix

--prefix /usr/local
--prefix path
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.
We use ~/.local by default on arm64 macOS machines as SIP now disables access to
/usr/local. 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.
Defaults to /usr/local or ~/.local if /usr/local is not writable by the current user.
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.
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]
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
the d2plugin-tala binary will be installed into \$PREFIX/bin/d2plugin-tala
warn: The version may not be obeyed with package manager installations. Use
--method=standalone to enforce the version.

--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
will be deleted from \$PREFIX/lib/d2/d2-<VERSION> but the release archive in
~/.cache/d2/release will remain.

--uninstall:
Expand All @@ -85,7 +89,7 @@ Flags:
note: tala will also be uninstalled if installed.

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.

Expand Down Expand Up @@ -150,13 +154,9 @@ main() {
fi

REPO=${REPO:-terrastruct/d2}
OS=$(os)
ARCH=$(arch)
if [ -z "${PREFIX-}" -a "$OS" = macos -a "$ARCH" = arm64 ]; then
# M1 Mac's do not allow modifications to /usr/local even with sudo.
PREFIX=$HOME/.local
fi
PREFIX=${PREFIX:-/usr/local}
ensure_os
ensure_arch
ensure_prefix
CACHE_DIR=$(cache_dir)
mkdir -p "$CACHE_DIR"
METHOD=${METHOD:-detect}
Expand Down Expand Up @@ -318,11 +318,7 @@ install_d2_standalone() {
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'

sh_c="sh_c"
if ! is_prefix_writable; then
sh_c="sudo_sh_c"
fi

ensure_prefix_sh_c
"$sh_c" mkdir -p "'$INSTALL_DIR'"
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
Expand Down Expand Up @@ -365,11 +361,7 @@ install_tala_standalone() {

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

ensure_prefix_sh_c
"$sh_c" mkdir -p "'$INSTALL_DIR'"
"$sh_c" tar -C "$INSTALL_DIR" -xzf "$CACHE_DIR/$ARCHIVE"
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$VERSION\" && make install PREFIX=\"$PREFIX\"'"
Expand Down Expand Up @@ -417,11 +409,7 @@ uninstall_d2_standalone() {
return 1
fi

sh_c="sh_c"
if ! is_prefix_writable; then
sh_c="sudo_sh_c"
fi

ensure_prefix_sh_c
"$sh_c" sh -c "'cd \"$INSTALL_DIR/d2-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
"$sh_c" rm -rf "$INSTALL_DIR/d2-$INSTALLED_VERSION"
}
Expand All @@ -439,11 +427,7 @@ uninstall_tala_standalone() {
return 1
fi

sh_c="sh_c"
if ! is_prefix_writable; then
sh_c="sudo_sh_c"
fi

ensure_prefix_sh_c
"$sh_c" sh -c "'cd \"$INSTALL_DIR/tala-$INSTALLED_VERSION\" && make uninstall PREFIX=\"$PREFIX\"'"
"$sh_c" rm -rf "$INSTALL_DIR/tala-$INSTALLED_VERSION"
}
Expand All @@ -452,13 +436,6 @@ uninstall_tala_brew() {
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() {
if [ -n "${XDG_CACHE_HOME-}" ]; then
echo "$XDG_CACHE_HOME/d2/release"
Expand All @@ -475,7 +452,7 @@ fetch_release_info() {
fi

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
release_info_url="https://api.github.com/repos/$REPO/releases/$VERSION"
else
Expand Down
17 changes: 9 additions & 8 deletions ci/release/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,14 @@ main() {
VERSION=${VERSION:-$(git_describe_ref)}
BUILD_DIR=ci/release/build/$VERSION
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
( 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
( 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
return 0
fi
Expand All @@ -123,7 +126,7 @@ main() {
runjob macos-amd64 'OS=macos ARCH=amd64 build' &
runjob macos-arm64 'OS=macos ARCH=arm64 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
}

Expand Down Expand Up @@ -189,8 +192,7 @@ build_local() {

build_remote_macos() {
sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock
sh_c ssh "$REMOTE_HOST" mkdir -p src
sh_c rsync --archive --human-readable --delete ./ "$REMOTE_HOST:src/d2/"
sh_c gitsync "$REMOTE_HOST" src/d2
sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \
TERM=${TERM-} \
DRY_RUN=${DRY_RUN-} \
Expand All @@ -207,8 +209,7 @@ PATH=\\\"/usr/local/bin:/usr/local/sbin:/opt/homebrew/bin:/opt/homebrew/sbin\\\$

build_remote_linux() {
sh_c lockfile_ssh "$REMOTE_HOST" .d2-build-lock
sh_c ssh "$REMOTE_HOST" mkdir -p src
sh_c rsync --archive --human-readable --delete ./ "$REMOTE_HOST:src/d2/"
sh_c gitsync "$REMOTE_HOST" src/d2
sh_c ssh "$REMOTE_HOST" "COLOR=${COLOR-} \
TERM=${TERM-} \
DRY_RUN=${DRY_RUN-} \
Expand Down
25 changes: 22 additions & 3 deletions ci/release/builders/aws_ensure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,29 @@ init_remote_macos() {
fi
sleep 5
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" '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'
sh_c ssh "$REMOTE_HOST" 'PATH="/usr/local/bin:/opt/homebrew/bin:\$PATH" brew install go'

if sh_c ssh "$REMOTE_HOST" uname -m | grep -qF arm64; then
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 "$@"
5 changes: 5 additions & 0 deletions ci/release/changelogs/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
can now run `go install oss.terrastruct.com/d2@latest` to install from source.
[#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 ⛑️

Expand Down
2 changes: 2 additions & 0 deletions ci/release/gen_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set -eu
# install.sh was bundled together from
#
# - ./ci/sub/lib/rand.sh
# - ./ci/sub/lib/temp.sh
# - ./ci/sub/lib/log.sh
# - ./ci/sub/lib/flag.sh
# - ./ci/sub/lib/release.sh
Expand All @@ -30,6 +31,7 @@ EOF
# script.
sh_c cat \
./ci/sub/lib/rand.sh \
./ci/sub/lib/temp.sh \
./ci/sub/lib/log.sh \
./ci/sub/lib/flag.sh \
./ci/sub/lib/release.sh \
Expand Down
2 changes: 2 additions & 0 deletions ci/release/gen_template_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ sh_c cat >./ci/release/template/scripts/lib.sh <<EOF
# lib.sh was bundled together from
#
# - ./ci/sub/lib/rand.sh
# - ./ci/sub/lib/temp.sh
# - ./ci/sub/lib/log.sh
# - ./ci/sub/lib/release.sh
#
Expand All @@ -25,6 +26,7 @@ EOF
# script.
sh_c cat \
./ci/sub/lib/rand.sh \
./ci/sub/lib/temp.sh \
./ci/sub/lib/log.sh \
./ci/sub/lib/release.sh \
\| sed "-e'/^\. /d'" \>\>./ci/release/template/scripts/lib.sh
Expand Down
8 changes: 3 additions & 5 deletions ci/release/template/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@

.PHONY: 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

PREFIX = $(DESTDIR)/usr/local

.PHONY: install
install:
PREFIX='$(PREFIX)' ./scripts/install.sh
./scripts/install.sh

.PHONY: uninstall
uninstall:
PREFIX='$(PREFIX)' ./scripts/uninstall.sh
./scripts/uninstall.sh
7 changes: 4 additions & 3 deletions ci/release/template/README.md.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ version: $VERSION
\`\`\`sh
make install DRY_RUN=1
# 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

\`\`\`sh
make uninstall DRY_RUN=1
# If it looks right, run:
make uninstall
# make uninstall
\`\`\`
EOF
11 changes: 1 addition & 10 deletions ci/release/template/scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,7 @@ cd -- "$(dirname "$0")/.."
. ./scripts/lib.sh

main() {
if [ -z "${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="sh_c"
if ! is_writable_dir "$PREFIX/bin"; then
sh_c="sudo_sh_c"
fi

ensure_prefix_sh_c
"$sh_c" mkdir -p "$PREFIX/bin"
"$sh_c" install ./bin/d2 "$PREFIX/bin/d2"
"$sh_c" mkdir -p "$PREFIX/share/man/man1"
Expand Down
Loading