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

feat: boltup installer + script #422

Merged
merged 5 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
9 changes: 9 additions & 0 deletions boltup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# boltup

A simple installer script for the [bolt CLI](../bolt-cli).

## Usage

```sh
curl -L https://raw.githubusercontent.com/chainbound/bolt/unstable/boltup/boltup.sh | bash
```
216 changes: 216 additions & 0 deletions boltup/boltup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#!/usr/bin/env bash
set -eo pipefail

# 'boltup' script for installing and managing the bolt CLI tool.
#
# This script is a heavily inspired by 'foundryup' (https://github.com/foundry-rs/foundry/blob/master/foundryup/foundryup)
# since it is a great way to install CLI tools. Kudos to the Foundry team :)

BASE_DIR=${XDG_CONFIG_HOME:-$HOME}
BOLT_DIR=${BOLT_DIR:-"$BASE_DIR/.bolt"}
BOLT_BIN_DIR="$BOLT_DIR/bin"

export RUSTFLAGS="${RUSTFLAGS:--C target-cpu=native}"
merklefruit marked this conversation as resolved.
Show resolved Hide resolved

main() {
need_cmd git
need_cmd curl

while [[ -n $1 ]]; do
case $1 in
--) shift; break;;

-t|--tag) shift; BOLTUP_TAG=$1;;
--arch) shift; BOLTUP_ARCH=$1;;
--platform) shift; BOLTUP_PLATFORM=$1;;
-h|--help)
usage
exit 0
;;
*)
warn "unknown option: $1"
usage
exit 1
esac; shift
done
Comment on lines +20 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be moved to a separate, documented function?
By documentation I mean something like:

"This function loops as long as $1 (the first positional argument) is not empty, and matches its value against flags. If a flag is found, the argument is discarded (via shift) and the value for the flag is read."

I know, I should RTFM but having gently reminders of bash syntax is nice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't move it but I added the comment, as I don't want to introduce untested behaviour in a script that is battle tested (this is what foundry has been using for 2+ years)


CARGO_BUILD_ARGS=(--release)
merklefruit marked this conversation as resolved.
Show resolved Hide resolved

# Print the banner after successfully parsing args
banner

BOLTUP_REPO="chainbound/bolt"

# Install by downloading binaries (default: "latest" tag)
BOLTUP_TAG=${BOLTUP_TAG:-latest}

# Normalize versions (handle channels, versions without v prefix
if [[ "$BOLTUP_TAG" == [[:digit:]]* ]]; then
# Add v prefix
BOLTUP_TAG="v${BOLTUP_TAG}"
fi

say "installing bolt (tag ${BOLTUP_TAG})"

# Figure out the platform: one of "linux", "darwin" or "win32"
uname_s=$(uname -s)
PLATFORM=$(tolower "${BOLTUP_PLATFORM:-$uname_s}")
EXT="tar.gz"
case $PLATFORM in
linux) ;;
darwin | mac*)
PLATFORM="darwin"
;;
mingw* | win*)
# revert, as Windows is not supported currently
# TODO: add Windows binaries and support
err "Windows is not supported yet!"

EXT="zip"
PLATFORM="win32"
;;
*)
err "unsupported platform: $PLATFORM"
;;
esac

# Figure out the architecture: one of "amd64" or "arm64"
uname_m=$(uname -m)
ARCHITECTURE=$(tolower "${BOLTUP_ARCH:-$uname_m}")
if [ "${ARCHITECTURE}" = "x86_64" ]; then
# Redirect stderr to /dev/null to avoid printing errors if non Rosetta.
if [ "$(sysctl -n sysctl.proc_translated 2>/dev/null)" = "1" ]; then
ARCHITECTURE="arm64" # Rosetta.
else
ARCHITECTURE="amd64" # Intel.
fi
elif [ "${ARCHITECTURE}" = "arm64" ] || [ "${ARCHITECTURE}" = "aarch64" ]; then
ARCHITECTURE="arm64" # Arm.
else
ARCHITECTURE="amd64" # Amd.
fi

# Compute the URL of the release tarball in the Bolt repository.
RELEASE_URL="https://github.com/${BOLTUP_REPO}/releases/download/${BOLTUP_TAG}/"
# Examples: "bolt-cli-amd64-darwin.tar.gz" or "bolt-cli-arm64-linux.tar.gz"
BIN_FILENAME="bolt-cli-${ARCHITECTURE}-${PLATFORM}.$EXT"
BIN_ARCHIVE_URL="${RELEASE_URL}${BIN_FILENAME}"

# Download and extract the binaries archive
say "downloading latest binary"
if [ "$PLATFORM" = "win32" ]; then
tmp="$(mktemp -d 2>/dev/null || echo ".")/bolt.zip"
ensure download "$BIN_ARCHIVE_URL" "$tmp"
ensure unzip "$tmp" -d "$BOLT_BIN_DIR"
rm -f "$tmp"
else
ensure download "$BIN_ARCHIVE_URL" | ensure tar -xzC "$BOLT_BIN_DIR"
fi

bin_path="$BOLT_BIN_DIR/bolt"

# Print installed msg
say "installed - $(ensure "$bin_path" --version)"

# Check if the default path of the binary is not in BOLT_BIN_DIR
which_path="$(command -v "$bin" || true)"
if [ -n "$which_path" ] && [ "$which_path" != "$bin_path" ]; then
warn ""
cat 1>&2 <<EOF
There are multiple binaries with the name 'bolt' present in your 'PATH'.
This may be the result of installing 'bolt' using another method,
like Cargo or other package managers.
You may need to run 'rm $which_path' or move '$BOLT_BIN_DIR'
in your 'PATH' to allow the newly installed version to take precedence!

EOF
fi

say "done!"
}

usage() {
cat 1>&2 <<EOF
The installer for bolt CLI.

Update or revert to a specific bolt version with ease.

By default, the latest unstable version is installed from built binaries.

USAGE:
boltup <OPTIONS>

OPTIONS:
-h, --help Print help information
-t, --tag Install a specific version from built binaries (default: latest)
--arch Install a specific architecture (supports amd64 and arm64)
--platform Install a specific platform (supports linux, and darwin)
EOF
}

say() {
printf "boltup: %s\n" "$1"
}

warn() {
say "warning: ${1}" >&2
}

err() {
say "$1" >&2
exit 1
}

tolower() {
echo "$1" | awk '{print tolower($0)}'
}

need_cmd() {
if ! check_cmd "$1"; then
err "need '$1' (command not found)"
fi
}

check_cmd() {
command -v "$1" &>/dev/null
}

# Run a command that should never fail. If the command fails execution
# will immediately terminate with an error showing the failing command.
ensure() {
if ! "$@"; then err "command failed: $*"; fi
}

# Downloads $1 into $2 or stdout
download() {
if [ -n "$2" ]; then
# output into $2
if check_cmd curl; then
curl -#o "$2" -L "$1"
else
wget --show-progress -qO "$2" "$1"
fi
else
# output to stdout
if check_cmd curl; then
curl -#L "$1"
else
wget --show-progress -qO- "$1"
fi
fi
}

# Banner Function for Bolt
banner() {
printf '

.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx

Bolt: Permissionless proposr commitments on Ethereum.

.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx

'
}

main "$@"
67 changes: 67 additions & 0 deletions boltup/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
set -eo pipefail

# 'boltup' installation script.
#
# This script is a carbon copy of 'foundryup' (https://github.com/foundry-rs/foundry/blob/master/foundryup/README.md)
# since it is a great way to install CLI tools. The only difference is the URL and the binary name.

echo "Installing boltup..."

BASE_DIR="${XDG_CONFIG_HOME:-$HOME}"
BOLT_DIR="${BOLT_DIR:-"$BASE_DIR/.bolt"}"
BOLT_BIN_DIR="$BOLT_DIR/bin"

DEFAULT_BRANCH="unstable"
BIN_URL="https://raw.githubusercontent.com/chainbound/bolt/$DEFAULT_BRANCH/boltup/boltup.sh"
BIN_PATH="$BOLT_BIN_DIR/boltup"

# Create the .bolt bin directory and boltup binary if it doesn't exist.
mkdir -p "$BOLT_BIN_DIR"
curl -sSf -L "$BIN_URL" -o "$BIN_PATH"
chmod +x "$BIN_PATH"

# Store the correct profile file (i.e. .profile for bash or .zshenv for ZSH).
case $SHELL in
*/zsh)
PROFILE="${ZDOTDIR-"$HOME"}/.zshenv"
PREF_SHELL=zsh
;;
*/bash)
PROFILE=$HOME/.bashrc
PREF_SHELL=bash
;;
*/fish)
PROFILE=$HOME/.config/fish/config.fish
PREF_SHELL=fish
;;
*/ash)
PROFILE=$HOME/.profile
PREF_SHELL=ash
;;
*)
echo "boltup: could not detect shell, manually add ${BOLT_BIN_DIR} to your PATH."
exit 1
;;
esac

# Only add boltup if it isn't already in PATH.
if [[ ":$PATH:" != *":${BOLT_BIN_DIR}:"* ]]; then
# Add the boltup directory to the path and ensure the old PATH variables remain.
# If the shell is fish, echo fish_add_path instead of export.
if [[ "$PREF_SHELL" == "fish" ]]; then
echo >>"$PROFILE" && echo "fish_add_path -a $BOLT_BIN_DIR" >>"$PROFILE"
else
echo >>"$PROFILE" && echo "export PATH=\"\$PATH:$BOLT_BIN_DIR\"" >>"$PROFILE"
fi
fi

# Warn MacOS users that they may need to manually install libusb via Homebrew:
if [[ "$OSTYPE" =~ ^darwin ]] && [[ ! -f /usr/local/opt/libusb/lib/libusb-1.0.0.dylib && ! -f /opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib ]]; then
echo && echo "warning: libusb not found. You may need to install it manually on MacOS via Homebrew (brew install libusb)."
fi

echo
echo "Detected your preferred shell is $PREF_SHELL and added boltup to PATH."
echo "Run 'source $PROFILE' or start a new terminal session to use boltup."
echo "Then, simply run 'boltup' to install the bolt CLI."