#!/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 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