Files
core/install
T
2026-11-03 03:32:07 +00:00

121 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# 先安装 Dever 本体,再后台准备私有编译环境;--wait 用于同步安装。
set -euo pipefail
version=${DEVER_VERSION:-@DEVER_VERSION@}
install_root=${DEVER_INSTALL_DIR:-"$HOME/.dever"}
release_url=
modify_path=true
wait_for_environment=false
while (( $# )); do
case "$1" in
--version) version=${2:?--version requires a value}; shift 2 ;;
--prefix) install_root=${2:?--prefix requires a value}; shift 2 ;;
--release-url) release_url=${2:?--release-url requires a value}; shift 2 ;;
--no-modify-path) modify_path=false; shift ;;
--wait) wait_for_environment=true; shift ;;
--help|-h)
echo 'Usage: bash install [--version VERSION] [--prefix DIRECTORY] [--release-url URL] [--no-modify-path] [--wait]'
exit 0 ;;
*) echo "Unknown option: $1" >&2; exit 1 ;;
esac
done
if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo 'Specify --version, or use the installer attached to a Dever release.' >&2
exit 1
fi
if [[ $(uname -s) != Linux || $(uname -m) != x86_64 ]]; then
echo 'This release supports Linux x86_64 only.' >&2
exit 1
fi
for tool in curl tar xz sha256sum flock getconf nohup; do
command -v "$tool" >/dev/null || { echo "Required installer tool: $tool" >&2; exit 1; }
done
glibc=$(getconf GNU_LIBC_VERSION)
glibc=${glibc#glibc }
if [[ $(printf '%s\n' 2.41 "$glibc" | sort -V | head -n 1) != 2.41 ]]; then
echo 'This release requires glibc 2.41 or newer; Debian 13 is validated.' >&2
exit 1
fi
mkdir -p "$install_root"
install_root=$(cd "$install_root" && pwd -P)
exec 9>"$install_root/.install.lock"
flock -n 9 || { echo 'Another Dever installation is running.' >&2; exit 1; }
mkdir -p "$install_root/bin" "$install_root/versions" "$install_root/toolchains" "$install_root/cache/cargo"
stage=$(mktemp -d "$install_root/.install.XXXXXX")
trap 'rm -rf -- "$stage"' EXIT
release_url=${release_url:-"https://git.dever.cc/dever/core/releases/download/v$version"}
release_url=${release_url%/}
triple=x86_64-unknown-linux-gnu
download() {
local url=$1 file=$2
curl --fail --location --show-error --progress-bar --retry 2 "$url" --output "$file"
}
verified_download() {
local url=$1 file=$2
download "$url" "$file"
download "$url.sha256" "$file.sha256"
(cd "$(dirname "$file")" && sha256sum --check "$(basename "$file").sha256")
}
destination="$install_root/versions/$version"
if [[ -d $destination ]]; then
package=$destination
echo "Reusing Dever $version."
else
echo "Downloading Dever $version."
archive="dever-$version-linux-x86_64.tar.xz"
verified_download "$release_url/$archive" "$stage/$archive"
tar -xJf "$stage/$archive" -C "$stage"
package="$stage/dever"
fi
read -r rust_version native_id < "$package/toolchain/online"
if [[ ! $rust_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ || ! $native_id =~ ^[a-f0-9]{64}$ ]]; then
echo 'Invalid toolchain metadata in the downloaded release.' >&2
exit 1
fi
if [[ $package != "$destination" ]]; then
# 暂存包与正式版本目录深度一致,使用相对链接共享工具和依赖缓存。
ln -s "../../../toolchains/rust-$rust_version-$triple" "$package/toolchain/rust"
ln -s "../../../toolchains/native-$native_id/native" "$package/toolchain/native"
ln -s "../../../toolchains/native-$native_id/lib" "$package/toolchain/lib"
ln -s ../../../cache/cargo "$package/toolchain/cache"
fi
"$package/bin/dever" skill path >/dev/null
printf '%s\n%s\n' "$release_url" "${RUSTUP_DIST_SERVER:-https://static.rust-lang.org}" > "$package/toolchain/sources.new"
mv "$package/toolchain/sources.new" "$package/toolchain/sources"
if [[ $package != "$destination" ]]; then
mv "$package" "$destination"
fi
# 本体验证成功即可使用源码工具;编译命令等待后台环境准备完成。
ln -s "../versions/$version/bin/dever" "$stage/command"
mv -Tf "$stage/command" "$install_root/bin/dever"
printf 'export PATH=%q/bin:$PATH\n' "$install_root" > "$install_root/env"
if $modify_path; then
shell_name=${SHELL:-/bin/sh}
case "${shell_name##*/}" in
zsh) profile="$HOME/.zshrc" ;;
bash) profile="$HOME/.bashrc" ;;
*) profile="$HOME/.profile" ;;
esac
printf -v path_line '. %q' "$install_root/env"
if [[ ! -f $profile ]] || ! grep -Fqx "$path_line" "$profile"; then
printf '\n%s\n' "$path_line" >> "$profile"
fi
fi
"$install_root/bin/dever" --version
printf 'Dever installed. Open a new terminal, or run: . %q\n' "$install_root/env"
echo 'Start a project: dever new hello'
flock -u 9
if $wait_for_environment; then
bash "$destination/toolchain/prepare"
elif [[ ! -f $destination/toolchain/ready ]]; then
nohup bash "$destination/toolchain/prepare" </dev/null >/dev/null 2>&1 9>&- &
echo 'The build environment is preparing in the background. You can create, edit and check projects now.'
echo 'run/test/build will wait automatically if preparation is still in progress.'
else
echo 'Dever build environment is ready.'
fi