diff --git a/.cursor/environment.json b/.cursor/environment.json new file mode 100644 index 000000000..430b95905 --- /dev/null +++ b/.cursor/environment.json @@ -0,0 +1,5 @@ +{ + "name": "caret (R package)", + "user": "ubuntu", + "install": "bash .cursor/install.sh" +} diff --git a/.cursor/install.sh b/.cursor/install.sh new file mode 100755 index 000000000..08fe204ab --- /dev/null +++ b/.cursor/install.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +# +# Cloud Agent install script for the caret R package (source lives in pkg/caret). +# +# Idempotent: safe to run repeatedly. It (1) ensures the R toolchain and system +# libraries exist, (2) configures a fast binary CRAN mirror plus legacy-compat +# compiler flags, (3) installs caret's runtime + test dependencies, and +# (4) builds and installs the in-repo caret package. +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$REPO_ROOT" + +# --------------------------------------------------------------------------- +# 1. System toolchain (R + build deps). Only runs when R is not already present +# (e.g. a cold VM). On snapshot-backed builds R is baked in, so this is a +# fast no-op. +# --------------------------------------------------------------------------- +if ! command -v Rscript >/dev/null 2>&1; then + echo "==> Installing R and system build dependencies" + export DEBIAN_FRONTEND=noninteractive + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends \ + dirmngr gnupg ca-certificates curl + + sudo install -d -m 0755 /etc/apt/keyrings + curl -fsSL https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc \ + | sudo tee /etc/apt/keyrings/cran.asc >/dev/null + echo "deb [signed-by=/etc/apt/keyrings/cran.asc] https://cloud.r-project.org/bin/linux/ubuntu noble-cran40/" \ + | sudo tee /etc/apt/sources.list.d/cran.list >/dev/null + + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends \ + r-base-dev gfortran build-essential pandoc \ + libcurl4-openssl-dev libssl-dev libxml2-dev libgit2-dev \ + libfontconfig1-dev libharfbuzz-dev libfribidi-dev \ + libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev +fi + +echo "==> R version: $(R --version | head -1)" + +# --------------------------------------------------------------------------- +# 2. R configuration: fast binary mirror + legacy-compat build flags. +# --------------------------------------------------------------------------- +# Posit Public Package Manager serves precompiled binaries for Ubuntu 24.04 +# (noble), making dependency installs seconds instead of many minutes. +cat > "$HOME/.Rprofile" <<'EOF' +local({ + options( + repos = c(P3M = "https://packagemanager.posit.co/cran/__linux__/noble/latest"), + HTTPUserAgent = sprintf( + "R/%s R (%s)", + getRversion(), + paste(getRversion(), R.version["platform"], R.version["arch"], R.version["os"]) + ), + Ncpus = max(1L, parallel::detectCores()) + ) +}) +EOF + +# caret's src/caret.c derives from the legacy `class` package and relies on the +# `Sint` type and `DOUBLE_XMAX` constant, both removed from modern R headers. +# Restore their historical definitions (Sint == int, DOUBLE_XMAX == DBL_MAX) +# via compiler flags so the package builds without patching its source. +mkdir -p "$HOME/.R" +cat > "$HOME/.R/Makevars" <<'EOF' +CPPFLAGS += -DSint=int -DDOUBLE_XMAX=DBL_MAX +EOF + +# Ensure the standard site library is user-writable so install.packages() and +# R CMD INSTALL work without root. +SITE_LIB="$(Rscript -e 'cat(.Library.site[1])')" +if [ -n "$SITE_LIB" ] && [ ! -w "$SITE_LIB" ]; then + sudo mkdir -p "$SITE_LIB" + sudo chown -R "$(id -un):$(id -gn)" "$SITE_LIB" +fi + +# --------------------------------------------------------------------------- +# 3. R package dependencies (runtime Imports/Depends + packages exercised by +# the test suite). Only missing packages are installed, so reruns are fast. +# --------------------------------------------------------------------------- +echo "==> Installing R package dependencies" +Rscript - <<'EOF' +pkgs <- c( + # caret Depends / Imports + "lattice", "ggplot2", "foreach", "plyr", "ModelMetrics", "nlme", + "reshape2", "recipes", "withr", + # test harness + models exercised directly by the testthat suite + "testthat", "arm", "C50", "earth", "gam", "glmnet", "fastICA", + "rpart", "kernlab", "ipred", "mda", "MASS", "dplyr", "e1071", "pROC", + # additional dependencies declared by the project's CI (.travis.yml) + "MLmetrics", "mgcv", "klaR", "mlbench", "nnet", "party", "pls", + "proxy", "randomForest", "RANN", "ellipse", "data.table", "subselect", + "spls", "pamr", "superpc", "Cubist", "knitr" +) +missing <- setdiff(pkgs, rownames(installed.packages())) +if (length(missing)) { + cat("Installing:", paste(missing, collapse = ", "), "\n") + install.packages(missing) +} else { + cat("All R dependencies already present.\n") +} +still_missing <- setdiff(pkgs, rownames(installed.packages())) +if (length(still_missing)) { + stop("Failed to install: ", paste(still_missing, collapse = ", ")) +} +EOF + +# --------------------------------------------------------------------------- +# 4. Build & install the in-repo caret package. +# --------------------------------------------------------------------------- +echo "==> Building and installing caret from pkg/caret" +R CMD INSTALL --no-multiarch --with-keep.source pkg/caret + +echo "==> Verifying caret loads" +Rscript -e 'suppressPackageStartupMessages(library(caret)); cat("caret", as.character(packageVersion("caret")), "loaded OK\n")' + +echo "==> install.sh complete"