221 lines
6.6 KiB
Bash
221 lines
6.6 KiB
Bash
#!/bin/bash
|
|
|
|
# Path: Scripts/r.sh
|
|
set -e
|
|
|
|
BLUE='\033[1;34m'
|
|
YELLOW='\033[1;33m'
|
|
GREEN='\033[1;32m'
|
|
RED='\033[1;31m'
|
|
NC='\033[0m'
|
|
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
source "$SCRIPT_DIR/lib/distro.sh"
|
|
|
|
PROG_DIR="$HOME/.programming"
|
|
R_ROOT="$PROG_DIR/r"
|
|
R_BIN_DIR="$R_ROOT/bin"
|
|
R_LIB_DIR="$R_ROOT/library"
|
|
|
|
mkdir -p "$R_BIN_DIR" "$R_LIB_DIR"
|
|
|
|
write_r_wrapper() {
|
|
local target_name="$1"
|
|
local command_body="$2"
|
|
|
|
cat > "$R_BIN_DIR/$target_name" <<EOF
|
|
#!/bin/bash
|
|
set -e
|
|
export R_LIBS_USER="$R_LIB_DIR"
|
|
$command_body "\$@"
|
|
EOF
|
|
|
|
chmod +x "$R_BIN_DIR/$target_name"
|
|
}
|
|
|
|
resolve_non_wrapper_command() {
|
|
local target_name="$1"
|
|
local original_path="$PATH"
|
|
local filtered_parts=()
|
|
local filtered_path=""
|
|
local resolved_path=""
|
|
local part
|
|
|
|
IFS=':' read -r -a filtered_parts <<< "$PATH"
|
|
|
|
local kept_parts=()
|
|
for part in "${filtered_parts[@]}"; do
|
|
if [ -n "$part" ] && [ "$part" != "$R_BIN_DIR" ]; then
|
|
kept_parts+=("$part")
|
|
fi
|
|
done
|
|
|
|
filtered_path=$(IFS=:; printf '%s' "${kept_parts[*]}")
|
|
resolved_path=$(PATH="$filtered_path" command -v "$target_name" 2>/dev/null || true)
|
|
|
|
PATH="$original_path"
|
|
|
|
if [ -z "$resolved_path" ]; then
|
|
echo -e "${RED} ERROR:${NC} Could not resolve system command for $target_name outside $R_BIN_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
printf '%s\n' "$resolved_path"
|
|
}
|
|
|
|
echo -e "${BLUE} LOG:${YELLOW} Detecting R installation strategy for $OS...${NC}"
|
|
|
|
if is_arch_family; then
|
|
|
|
echo -e "${BLUE} LOG:${YELLOW} Arch Linux detected. Using system R (Pacman)...${NC}"
|
|
|
|
# Install R + Build Tools
|
|
install_status=0
|
|
install_packages r gcc-fortran curl tar || install_status=$?
|
|
if [ "$install_status" -eq 42 ]; then
|
|
exit 0
|
|
elif [ "$install_status" -ne 0 ]; then
|
|
exit "$install_status"
|
|
fi
|
|
|
|
echo -e "${GREEN} SUCCESS:${NC} R installed via Pacman."
|
|
|
|
R_BIN="R"
|
|
SYSTEM_R_BIN="$(resolve_non_wrapper_command R)"
|
|
SYSTEM_RSCRIPT_BIN="$(resolve_non_wrapper_command Rscript)"
|
|
write_r_wrapper "R" "exec \"$SYSTEM_R_BIN\""
|
|
write_r_wrapper "Rscript" "exec \"$SYSTEM_RSCRIPT_BIN\""
|
|
|
|
elif is_debian_family; then
|
|
|
|
echo -e "${BLUE} LOG:${YELLOW} Installing Debian build dependencies...${NC}"
|
|
install_status=0
|
|
install_packages gfortran curl tar ca-certificates || install_status=$?
|
|
if [ "$install_status" -eq 42 ]; then
|
|
exit 0
|
|
elif [ "$install_status" -ne 0 ]; then
|
|
exit "$install_status"
|
|
fi
|
|
|
|
if ! command -v rig >/dev/null 2>&1; then
|
|
echo -e "${BLUE} LOG:${YELLOW} Installing Rig for Debian/Ubuntu...${NC}"
|
|
|
|
DEB_ARCH=$(dpkg --print-architecture)
|
|
case "$DEB_ARCH" in
|
|
amd64|arm64)
|
|
;;
|
|
*)
|
|
echo -e "${RED} ERROR:${NC} Unsupported Debian architecture for Rig: $DEB_ARCH"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
LATEST_REL_DATA=$(curl -fsSL https://api.github.com/repos/r-lib/rig/releases/latest)
|
|
RIG_URL=$(echo "$LATEST_REL_DATA" | grep -o "https://[^\"]*r-rig_[^\"]*_${DEB_ARCH}\.deb" | head -n 1)
|
|
|
|
if [ -z "$RIG_URL" ]; then
|
|
echo -e "${RED} ERROR:${NC} Could not find Rig .deb download URL for architecture: $DEB_ARCH"
|
|
exit 1
|
|
fi
|
|
|
|
TEMP_DEB=$(mktemp --suffix=.deb)
|
|
curl -fLsS "$RIG_URL" -o "$TEMP_DEB"
|
|
sudo apt-get install -y "$TEMP_DEB"
|
|
rm -f "$TEMP_DEB"
|
|
fi
|
|
|
|
TARGET_VER="release"
|
|
if ! rig list | grep -q "release"; then
|
|
echo -e "${BLUE} LOG:${YELLOW} Installing R (${TARGET_VER})...${NC}"
|
|
sudo rig add "$TARGET_VER" --without-cran-mirror
|
|
sudo rig default "$TARGET_VER"
|
|
fi
|
|
|
|
R_BIN="R"
|
|
SYSTEM_R_BIN="$(resolve_non_wrapper_command R)"
|
|
SYSTEM_RSCRIPT_BIN="$(resolve_non_wrapper_command Rscript)"
|
|
write_r_wrapper "R" "exec \"$SYSTEM_R_BIN\""
|
|
write_r_wrapper "Rscript" "exec \"$SYSTEM_RSCRIPT_BIN\""
|
|
|
|
elif is_fedora_family; then
|
|
|
|
echo -e "${BLUE} LOG:${YELLOW} Fedora detected. Using system R...${NC}"
|
|
install_status=0
|
|
install_packages R-core R-core-devel gcc-gfortran curl tar || install_status=$?
|
|
if [ "$install_status" -eq 42 ]; then
|
|
exit 0
|
|
elif [ "$install_status" -ne 0 ]; then
|
|
exit "$install_status"
|
|
fi
|
|
|
|
R_BIN="R"
|
|
SYSTEM_R_BIN="$(resolve_non_wrapper_command R)"
|
|
SYSTEM_RSCRIPT_BIN="$(resolve_non_wrapper_command Rscript)"
|
|
write_r_wrapper "R" "exec \"$SYSTEM_R_BIN\""
|
|
write_r_wrapper "Rscript" "exec \"$SYSTEM_RSCRIPT_BIN\""
|
|
|
|
elif is_macos; then
|
|
|
|
echo -e "${BLUE} LOG:${YELLOW} macOS detected. Using Homebrew R...${NC}"
|
|
install_status=0
|
|
install_packages r || install_status=$?
|
|
if [ "$install_status" -ne 0 ]; then
|
|
exit "$install_status"
|
|
fi
|
|
|
|
R_BIN="R"
|
|
SYSTEM_R_BIN="$(resolve_non_wrapper_command R)"
|
|
SYSTEM_RSCRIPT_BIN="$(resolve_non_wrapper_command Rscript)"
|
|
write_r_wrapper "R" "exec \"$SYSTEM_R_BIN\""
|
|
write_r_wrapper "Rscript" "exec \"$SYSTEM_RSCRIPT_BIN\""
|
|
|
|
else
|
|
echo -e "${RED} ERROR:${NC} Unsupported OS: $OS"
|
|
exit 1
|
|
fi
|
|
|
|
export R_LIBS_USER="$R_LIB_DIR"
|
|
|
|
if compgen -G "$R_LIB_DIR/00LOCK*" >/dev/null 2>&1; then
|
|
echo -e "${RED} ERROR:${NC} Detected existing R package lock(s) in $R_LIB_DIR"
|
|
find "$R_LIB_DIR" -maxdepth 1 -type d -name '00LOCK*' -print | sed 's/^/ - /'
|
|
echo -e "${YELLOW} LOG:${NC} This usually means a previous R package install was interrupted."
|
|
echo -e "${YELLOW} LOG:${NC} Remove the stale lock directory/directories above, then rerun the command."
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${BLUE} LOG:${YELLOW} Installing 'renv' package in the user R library...${NC}"
|
|
echo -e "${BLUE} LOG:${YELLOW} R user library: $R_LIB_DIR${NC}"
|
|
echo -e "${BLUE} LOG:${YELLOW} R executable: $R_BIN_DIR/Rscript${NC}"
|
|
|
|
"$R_BIN_DIR/Rscript" --vanilla - <<'EOF'
|
|
user_lib <- path.expand(Sys.getenv("R_LIBS_USER", unset = "~/.programming/r/library"))
|
|
dir.create(user_lib, recursive = TRUE, showWarnings = FALSE)
|
|
.libPaths(c(user_lib, .libPaths()))
|
|
|
|
cat("R user library:", user_lib, "\n")
|
|
cat("R library paths:", paste(.libPaths(), collapse = " | "), "\n")
|
|
|
|
if (requireNamespace("renv", quietly = TRUE)) {
|
|
cat("renv is already installed.\n")
|
|
quit(save = "no", status = 0)
|
|
}
|
|
|
|
cat("Installing renv from CRAN...\n")
|
|
install.packages(
|
|
"renv",
|
|
lib = user_lib,
|
|
repos = "https://cloud.r-project.org",
|
|
quiet = FALSE
|
|
)
|
|
|
|
cat("Verifying renv installation...\n")
|
|
if (!requireNamespace("renv", quietly = TRUE)) {
|
|
stop("renv install finished but the package is still unavailable.")
|
|
}
|
|
|
|
cat("renv installation verified.\n")
|
|
EOF
|
|
|
|
echo -e "${GREEN} SUCCESS:${NC} R setup completed."
|