install.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
set -euo pipefail
echo "==================================================================="
echo "Installing Rove native toolchain..."
echo "==================================================================="
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
INSTALL_DIR="${ROVE_INSTALL_DIR:-${NYX_INSTALL_DIR:-$HOME/.rove}}"
BIN_DIR="$INSTALL_DIR/bin"
SRC_DIR="$INSTALL_DIR/src"
COMPILER_DIR="$INSTALL_DIR/compiler"
EXTENSION_DIR="$INSTALL_DIR/vscode-extension"
NATIVE_EXE="$BIN_DIR/rovec"
REPOSITORY="justsomeone-e/RoveLang"
RELEASE_TAG="${ROVE_RELEASE_TAG:-${NYX_RELEASE_TAG:-}}"
NATIVE_COMPILER_PATH="${ROVE_NATIVE_COMPILER_PATH:-${NYX_NATIVE_COMPILER_PATH:-}}"
SKIP_EDITOR_INSTALL="${ROVE_SKIP_EDITOR_INSTALL:-${NYX_SKIP_EDITOR_INSTALL:-0}}"
SKIP_PATH_UPDATE="${ROVE_SKIP_PATH_UPDATE:-${NYX_SKIP_PATH_UPDATE:-0}}"
TEMP_DIR=""
EXPECTED_VERSION=""
if [ -f "$SCRIPT_DIR/VERSION" ]; then
EXPECTED_VERSION="$(tr -d '\r\n' < "$SCRIPT_DIR/VERSION")"
fi
cleanup() {
if [ -n "$TEMP_DIR" ] && [ -d "$TEMP_DIR" ]; then
temp_base="${TMPDIR:-/tmp}"
case "$TEMP_DIR" in
"$temp_base"/rove-install.*) rm -rf -- "$TEMP_DIR" ;;
*) echo "[!] Refusing to remove unexpected temporary path: $TEMP_DIR" >&2 ;;
esac
fi
}
trap cleanup EXIT
download_file() {
source_url="$1"
destination="$2"
if command -v curl >/dev/null 2>&1; then
curl -fsSL --retry 2 --connect-timeout 15 "$source_url" -o "$destination"
return
fi
if command -v wget >/dev/null 2>&1; then
wget -q --timeout=30 -O "$destination" "$source_url"
return
fi
return 127
}
find_python() {
if command -v python3 >/dev/null 2>&1; then
command -v python3
elif command -v python >/dev/null 2>&1; then
command -v python
fi
}
validate_native() {
candidate="$1"
[ -f "$candidate" ] && [ -x "$candidate" ] || return 1
version_output="$("$candidate" --version 2>&1)" || return 1
if [ -n "$EXPECTED_VERSION" ]; then
case "$version_output" in
"rovec $EXPECTED_VERSION "*|"nyxc $EXPECTED_VERSION "*) return 0 ;;
*) return 1 ;;
esac
fi
case "$version_output" in
"rovec "*|"nyxc "*) return 0 ;;
*) return 1 ;;
esac
}
platform_name=""
case "$(uname -s)" in
Linux) platform_name="linux" ;;
Darwin) platform_name="macos" ;;
*) echo "[!] Unsupported native platform: $(uname -s)" >&2; exit 1 ;;
esac
architecture=""
case "$(uname -m)" in
x86_64|amd64) architecture="x86_64" ;;
arm64|aarch64) architecture="arm64" ;;
*) echo "[!] Unsupported native architecture: $(uname -m)" >&2; exit 1 ;;
esac
PYTHON_BIN="$(find_python || true)"
SOURCE_ROOT=""
if [ -d "$SCRIPT_DIR/src" ]; then
SOURCE_ROOT="$SCRIPT_DIR"
fi
mkdir -p "$BIN_DIR" "$SRC_DIR" "$COMPILER_DIR"
TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/rove-install.XXXXXX")"
NATIVE_READY=0
if [ -n "$NATIVE_COMPILER_PATH" ]; then
if ! validate_native "$NATIVE_COMPILER_PATH"; then
echo "[!] ROVE_NATIVE_COMPILER_PATH does not point to a working rovec executable." >&2
exit 1
fi
cp "$NATIVE_COMPILER_PATH" "$NATIVE_EXE"
chmod +x "$NATIVE_EXE"
NATIVE_READY=1
echo "[OK] Installed native compiler from ROVE_NATIVE_COMPILER_PATH."
fi
if [ "$NATIVE_READY" -eq 0 ] && [ -n "$SOURCE_ROOT" ]; then
for candidate in "$SOURCE_ROOT/build/self_host/rovec" "$SOURCE_ROOT/build/self_host/nyxc" "$SOURCE_ROOT/bin/rovec" "$SOURCE_ROOT/bin/nyxc"; do
if validate_native "$candidate"; then
cp "$candidate" "$NATIVE_EXE"
chmod +x "$NATIVE_EXE"
NATIVE_READY=1
echo "[OK] Installed existing local native compiler."
break
fi
done
fi
if [ "$NATIVE_READY" -eq 0 ] && [ -z "$SOURCE_ROOT" ] && [ -n "$RELEASE_TAG" ]; then
if [ -n "$RELEASE_TAG" ]; then
release_base="https://github.com/$REPOSITORY/releases/download/$RELEASE_TAG"
fi
for asset_name in "rovec-$platform_name-$architecture" "nyxc-$platform_name-$architecture"; do
asset_path="$TEMP_DIR/$asset_name"
checksum_path="$TEMP_DIR/$asset_name.sha256"
echo "[*] Looking for native release asset $asset_name..."
if download_file "$release_base/$asset_name" "$asset_path" && \
download_file "$release_base/$asset_name.sha256" "$checksum_path"; then
checksum_ok=0
if command -v sha256sum >/dev/null 2>&1; then
(cd "$TEMP_DIR" && sha256sum -c "$asset_name.sha256" >/dev/null) && checksum_ok=1
elif command -v shasum >/dev/null 2>&1; then
(cd "$TEMP_DIR" && shasum -a 256 -c "$asset_name.sha256" >/dev/null) && checksum_ok=1
fi
if [ "$checksum_ok" -eq 1 ]; then
cp "$asset_path" "$NATIVE_EXE"
chmod +x "$NATIVE_EXE"
if validate_native "$NATIVE_EXE"; then
NATIVE_READY=1
echo "[OK] Installed SHA-256 verified native release compiler."
break
fi
else
echo "[!] Native release checksum verification failed; using source bootstrap if available." >&2
fi
fi
done
fi
if [ "$NATIVE_READY" -eq 0 ] && [ -z "$SOURCE_ROOT" ] && [ -z "$RELEASE_TAG" ]; then
echo "[*] No release tag selected; installing the current main development source."
fi
if [ -z "$SOURCE_ROOT" ] && { [ "$NATIVE_READY" -eq 0 ] || [ -n "$PYTHON_BIN" ]; }; then
source_archive="$TEMP_DIR/rove-source.tar.gz"
source_extract="$TEMP_DIR/source"
mkdir -p "$source_extract"
if [ -n "$RELEASE_TAG" ]; then
source_url="https://github.com/$REPOSITORY/archive/refs/tags/$RELEASE_TAG.tar.gz"
else
source_url="https://github.com/$REPOSITORY/archive/refs/heads/main.tar.gz"
fi
echo "[*] Downloading Rove sources..."
if download_file "$source_url" "$source_archive" && tar -xzf "$source_archive" -C "$source_extract"; then
for candidate in "$source_extract"/*; do
if [ -d "$candidate/src" ]; then
SOURCE_ROOT="$candidate"
break
fi
done
else
echo "[!] Source download failed; continuing only if the native core is already installed." >&2
fi
fi
if [ -n "$SOURCE_ROOT" ]; then
if [ -f "$SOURCE_ROOT/VERSION" ]; then
EXPECTED_VERSION="$(tr -d '\r\n' < "$SOURCE_ROOT/VERSION")"
fi
echo "[*] Installing source and compiler support files..."
cp -R "$SOURCE_ROOT/src/." "$SRC_DIR/"
for legal_file in VERSION LICENSE; do
if [ -f "$SOURCE_ROOT/$legal_file" ]; then
cp "$SOURCE_ROOT/$legal_file" "$INSTALL_DIR/$legal_file"
fi
done
if [ -d "$SOURCE_ROOT/compiler" ]; then
cp -R "$SOURCE_ROOT/compiler/." "$COMPILER_DIR/"
fi
if [ -d "$SOURCE_ROOT/vscode-extension" ]; then
mkdir -p "$EXTENSION_DIR"
for extension_file in \
package.json package-lock.json extension.js server_options.js rove_commands.js \
language-configuration.json language-surface.json README.md CHANGELOG.md LICENSE
do
if [ -f "$SOURCE_ROOT/vscode-extension/$extension_file" ]; then
cp "$SOURCE_ROOT/vscode-extension/$extension_file" "$EXTENSION_DIR/$extension_file"
fi
done
for extension_directory in images snippets syntaxes; do
if [ -d "$SOURCE_ROOT/vscode-extension/$extension_directory" ]; then
mkdir -p "$EXTENSION_DIR/$extension_directory"
cp -R "$SOURCE_ROOT/vscode-extension/$extension_directory/." \
"$EXTENSION_DIR/$extension_directory/"
fi
done
fi
fi
if [ "$NATIVE_READY" -eq 0 ] && validate_native "$NATIVE_EXE"; then
NATIVE_READY=1
echo "[OK] Reusing installed native compiler."
fi
if [ "$NATIVE_READY" -eq 0 ]; then
if [ -z "$PYTHON_BIN" ] || [ ! -f "$SRC_DIR/cli.py" ]; then
echo "[!] No prebuilt rovec is available for this platform." >&2
echo " Python 3.10+ and a C++20 compiler are required for source bootstrap." >&2
exit 1
fi
echo "[*] No matching prebuilt binary; bootstrapping native rovec from source..."
(
cd "$INSTALL_DIR"
"$PYTHON_BIN" "$SRC_DIR/cli.py" self-host build -o "$NATIVE_EXE"
)
chmod +x "$NATIVE_EXE"
if ! validate_native "$NATIVE_EXE"; then
echo "[!] Bootstrapped native compiler failed validation." >&2
exit 1
fi
NATIVE_READY=1
echo "[OK] Native rovec bootstrap completed."
fi
for command_name in rove nyx; do
wrapper="$BIN_DIR/$command_name"
printf '%s\n' \
'#!/usr/bin/env bash' \
'set -euo pipefail' \
'wrapper_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"' \
'install_dir="$(dirname -- "$wrapper_dir")"' \
'native="$wrapper_dir/rovec"' \
'python_cli="$install_dir/src/cli.py"' \
'case "${1:-}" in' \
' check|compile|emit-cpp|version|--version|-v) exec "$native" "$@" ;;' \
'esac' \
'if command -v python3 >/dev/null 2>&1 && [ -f "$python_cli" ]; then' \
' exec python3 "$python_cli" "$@"' \
'fi' \
'if command -v python >/dev/null 2>&1 && [ -f "$python_cli" ]; then' \
' exec python "$python_cli" "$@"' \
'fi' \
'if [ "$#" -eq 0 ]; then exec "$native" --help; fi' \
'echo "This command still uses the optional Python orchestration layer. Install Python 3.10+, or use rovec check/compile/emit-cpp." >&2' \
'exit 2' > "$wrapper"
chmod +x "$wrapper"
done
install_editor_extension() {
if [ "$SKIP_EDITOR_INSTALL" = "1" ] || [ ! -d "$EXTENSION_DIR" ]; then
return
fi
extension_runtime=0
if command -v npm >/dev/null 2>&1; then
if (cd "$EXTENSION_DIR" && npm ci --omit=dev --ignore-scripts >/dev/null 2>&1); then
extension_runtime=1
else
echo "[!] npm could not install the Rove language-server client; syntax highlighting will still be installed." >&2
fi
else
echo "[!] npm not found; installing Rove syntax highlighting without the language-server client." >&2
fi
editor_found=0
sync_extension() {
destination="$1"
mkdir -p "$destination"
cp -R "$EXTENSION_DIR/." "$destination/"
editor_found=1
echo "[OK] Installed Rove editor support at: $destination"
}
if command -v code >/dev/null 2>&1 || [ -d "$HOME/.vscode/extensions" ]; then
sync_extension "$HOME/.vscode/extensions/rove-lang-support"
fi
if command -v code-insiders >/dev/null 2>&1 || [ -d "$HOME/.vscode-insiders/extensions" ]; then
sync_extension "$HOME/.vscode-insiders/extensions/rove-lang-support"
fi
if command -v codium >/dev/null 2>&1 || [ -d "$HOME/.vscode-oss/extensions" ]; then
sync_extension "$HOME/.vscode-oss/extensions/rove-lang-support"
fi
if [ "$editor_found" -eq 0 ]; then
echo "[*] VS Code/VSCodium was not detected. Editor files remain at: $EXTENSION_DIR"
elif [ "$extension_runtime" -eq 0 ]; then
echo "[*] Rove highlighting is available; install Node.js/npm and rerun the installer to enable LSP features."
fi
}
install_editor_extension
if command -v clang++ >/dev/null 2>&1 || command -v g++ >/dev/null 2>&1 || command -v c++ >/dev/null 2>&1; then
echo "[OK] Host C++ compiler detected for '#target cpp'."
else
echo "[!] No host C++20 compiler was found; 'rove run --target cpp' cannot link executables yet." >&2
echo " Arch: sudo pacman -S --needed base-devel" >&2
echo " Debian/Ubuntu: sudo apt install g++" >&2
echo " Then run: rove doctor" >&2
fi
if ! validate_native "$NATIVE_EXE"; then
echo "[!] Installed native rovec failed final validation." >&2
exit 1
fi
cp "$NATIVE_EXE" "$BIN_DIR/nyxc"
chmod +x "$BIN_DIR/rovec"
echo "[OK] Rove installed successfully at: $INSTALL_DIR"
echo " Native core: rovec --help (legacy alias: nyxc)"
echo " Unified CLI: rove --help (legacy alias: nyx)"
if [ "$SKIP_PATH_UPDATE" != "1" ]; then
echo "Add this directory to PATH: $BIN_DIR"
fi
echo "==================================================================="