From 37a476259eb99f26bb59ce898e8fca004b6cd514 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 13:31:04 -0400 Subject: [PATCH 1/6] Add test for rust_installed function when rustup not found --- lib/rust-utils.bash | 11 +++++++ test/install/test-rust-utils.bats | 51 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 lib/rust-utils.bash create mode 100644 test/install/test-rust-utils.bats diff --git a/lib/rust-utils.bash b/lib/rust-utils.bash new file mode 100644 index 00000000..88e06d16 --- /dev/null +++ b/lib/rust-utils.bash @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# Rust installation utilities +# Provides functions for detecting and installing Rust toolchain + +set -euo pipefail + +# Check if Rust is already installed +rust_installed() { + command -v rustup &>/dev/null +} \ No newline at end of file diff --git a/test/install/test-rust-utils.bats b/test/install/test-rust-utils.bats new file mode 100644 index 00000000..a10eda51 --- /dev/null +++ b/test/install/test-rust-utils.bats @@ -0,0 +1,51 @@ +#!/usr/bin/env bats + +# Test Rust utility functions + +# Load the Rust utilities +load "../../lib/rust-utils.bash" + +setup() { + # Create temporary directory for each test + export TEST_TEMP_DIR + TEST_TEMP_DIR="$(mktemp -d)" + + # Save original environment + export ORIGINAL_PATH="$PATH" + export ORIGINAL_CARGO_HOME="${CARGO_HOME:-}" + export ORIGINAL_RUSTUP_HOME="${RUSTUP_HOME:-}" + + # Create mock bin directory + export MOCK_BIN="$TEST_TEMP_DIR/bin" + mkdir -p "$MOCK_BIN" +} + +teardown() { + # Restore original environment + export PATH="$ORIGINAL_PATH" + + if [[ -n "$ORIGINAL_CARGO_HOME" ]]; then + export CARGO_HOME="$ORIGINAL_CARGO_HOME" + else + unset CARGO_HOME + fi + + if [[ -n "$ORIGINAL_RUSTUP_HOME" ]]; then + export RUSTUP_HOME="$ORIGINAL_RUSTUP_HOME" + else + unset RUSTUP_HOME + fi + + # Clean up temporary directory + if [[ -n "${TEST_TEMP_DIR:-}" && -d "$TEST_TEMP_DIR" ]]; then + rm -rf "$TEST_TEMP_DIR" + fi +} + +@test "rust_installed returns false when rustup not found" { + # Ensure rustup is not in PATH + PATH="$MOCK_BIN" + + run rust_installed + [ "$status" -eq 1 ] +} \ No newline at end of file From 221c9a513d010af9339f5bd11ad6824e6d5cda94 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 13:31:24 -0400 Subject: [PATCH 2/6] Add test for rust_installed function when rustup is found --- test/install/test-rust-utils.bats | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/install/test-rust-utils.bats b/test/install/test-rust-utils.bats index a10eda51..9d1ea793 100644 --- a/test/install/test-rust-utils.bats +++ b/test/install/test-rust-utils.bats @@ -48,4 +48,19 @@ teardown() { run rust_installed [ "$status" -eq 1 ] +} + +@test "rust_installed returns true when rustup is found" { + # Create mock rustup command + cat > "$MOCK_BIN/rustup" << 'EOF' +#!/bin/bash +echo "rustup 1.26.0" +EOF + chmod +x "$MOCK_BIN/rustup" + + # Add mock bin to PATH + PATH="$MOCK_BIN:$PATH" + + run rust_installed + [ "$status" -eq 0 ] } \ No newline at end of file From 028ce7c6098413723387a1dc90dd3549d5eca9ca Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 13:33:24 -0400 Subject: [PATCH 3/6] Add setup_rust_environment function with test --- lib/rust-utils.bash | 6 ++++++ test/install/test-rust-utils.bats | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/rust-utils.bash b/lib/rust-utils.bash index 88e06d16..ee83a320 100644 --- a/lib/rust-utils.bash +++ b/lib/rust-utils.bash @@ -8,4 +8,10 @@ set -euo pipefail # Check if Rust is already installed rust_installed() { command -v rustup &>/dev/null +} + +# Set up Rust environment variables +setup_rust_environment() { + export CARGO_HOME="$HOME/.config/cargo" + export RUSTUP_HOME="$HOME/.config/rustup" } \ No newline at end of file diff --git a/test/install/test-rust-utils.bats b/test/install/test-rust-utils.bats index 9d1ea793..16c5bfe9 100644 --- a/test/install/test-rust-utils.bats +++ b/test/install/test-rust-utils.bats @@ -63,4 +63,14 @@ EOF run rust_installed [ "$status" -eq 0 ] +} + +@test "setup_rust_environment sets CARGO_HOME and RUSTUP_HOME" { + run setup_rust_environment + [ "$status" -eq 0 ] + + # Source the function and check the variables + setup_rust_environment + [[ "$CARGO_HOME" == "$HOME/.config/cargo" ]] + [[ "$RUSTUP_HOME" == "$HOME/.config/rustup" ]] } \ No newline at end of file From 961f61014349339b7dc929f6632d378e354ab060 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 14:06:47 -0400 Subject: [PATCH 4/6] Add install_rust_toolchain function with test --- lib/rust-utils.bash | 10 +++++++++ test/install/test-rust-utils.bats | 34 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/rust-utils.bash b/lib/rust-utils.bash index ee83a320..33f40dc7 100644 --- a/lib/rust-utils.bash +++ b/lib/rust-utils.bash @@ -14,4 +14,14 @@ rust_installed() { setup_rust_environment() { export CARGO_HOME="$HOME/.config/cargo" export RUSTUP_HOME="$HOME/.config/rustup" +} + +# Install Rust toolchain using rustup +install_rust_toolchain() { + echo "🦀 Installing Rust toolchain..." + + # Download and run rustup installer + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + + echo "🚀 Finished installing rustup, rustc and cargo." } \ No newline at end of file diff --git a/test/install/test-rust-utils.bats b/test/install/test-rust-utils.bats index 16c5bfe9..8ab033a9 100644 --- a/test/install/test-rust-utils.bats +++ b/test/install/test-rust-utils.bats @@ -73,4 +73,38 @@ EOF setup_rust_environment [[ "$CARGO_HOME" == "$HOME/.config/cargo" ]] [[ "$RUSTUP_HOME" == "$HOME/.config/rustup" ]] +} + +@test "install_rust_toolchain uses curl to download rustup installer" { + # Create mock curl command that logs its arguments + local curl_log="$TEST_TEMP_DIR/curl.log" + cat > "$MOCK_BIN/curl" << EOF +#!/bin/bash +echo "curl called with: \$@" > "$curl_log" +# Mock the rustup script response +cat << 'SCRIPT_EOF' +#!/bin/sh +echo "Mock rustup installer executed" +SCRIPT_EOF +EOF + chmod +x "$MOCK_BIN/curl" + + # Create mock sh command to capture script execution + cat > "$MOCK_BIN/sh" << 'EOF' +#!/bin/bash +echo "sh executed" +EOF + chmod +x "$MOCK_BIN/sh" + + # Add mock bin to PATH + PATH="$MOCK_BIN:$PATH" + + run install_rust_toolchain + [ "$status" -eq 0 ] + + # Check that curl was called with correct arguments + [[ -f "$curl_log" ]] + local curl_args=$(cat "$curl_log") + [[ "$curl_args" =~ "--proto" ]] + [[ "$curl_args" =~ "https://sh.rustup.rs" ]] } \ No newline at end of file From cf498d549e916bab03e6f4f7c52a8893db75bf88 Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 15:24:27 -0400 Subject: [PATCH 5/6] Add rust.bash installation script with test for already installed case --- bin/install/rust.bash | 30 +++++++++++ test/install/test-rust-installation.bats | 67 ++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100755 bin/install/rust.bash create mode 100644 test/install/test-rust-installation.bats diff --git a/bin/install/rust.bash b/bin/install/rust.bash new file mode 100755 index 00000000..e8d7bdc4 --- /dev/null +++ b/bin/install/rust.bash @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# Rust installation script (bash version) +# Installs Rust toolchain using rustup if not already installed + +# shellcheck disable=SC1091 # Don't follow sourced files + +set -euo pipefail + +# Load Rust utilities +source "${DOTFILES:-$HOME/Repos/ooloth/dotfiles}/lib/rust-utils.bash" + +main() { + # Check if Rust is already installed + if rust_installed; then + echo "🦀 Rust is already installed" + return 0 + fi + + # Set up environment variables + setup_rust_environment + + # Install Rust toolchain + install_rust_toolchain +} + +# Only run main if script is executed directly +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi \ No newline at end of file diff --git a/test/install/test-rust-installation.bats b/test/install/test-rust-installation.bats new file mode 100644 index 00000000..7cfbff15 --- /dev/null +++ b/test/install/test-rust-installation.bats @@ -0,0 +1,67 @@ +#!/usr/bin/env bats + +# Test Rust installation script + +setup() { + # Create temporary directory for each test + export TEST_TEMP_DIR + TEST_TEMP_DIR="$(mktemp -d)" + + # Save original environment + export ORIGINAL_HOME="$HOME" + export ORIGINAL_DOTFILES="${DOTFILES:-}" + export ORIGINAL_PATH="$PATH" + + # Set up test environment + export HOME="$TEST_TEMP_DIR/fake_home" + export DOTFILES="$TEST_TEMP_DIR/fake_dotfiles" + + # Create fake dotfiles structure + mkdir -p "$DOTFILES/lib" + cp "lib/rust-utils.bash" "$DOTFILES/lib/" + + # Create mock bin directory + export MOCK_BIN="$TEST_TEMP_DIR/bin" + mkdir -p "$MOCK_BIN" +} + +teardown() { + # Restore original environment + export HOME="$ORIGINAL_HOME" + export PATH="$ORIGINAL_PATH" + + if [[ -n "${ORIGINAL_DOTFILES}" ]]; then + export DOTFILES="$ORIGINAL_DOTFILES" + else + unset DOTFILES + fi + + # Clean up temporary directory + if [[ -n "${TEST_TEMP_DIR:-}" && -d "$TEST_TEMP_DIR" ]]; then + rm -rf "$TEST_TEMP_DIR" + fi +} + +@test "rust.bash exists and is executable" { + [ -f "$(pwd)/bin/install/rust.bash" ] + [ -x "$(pwd)/bin/install/rust.bash" ] +} + +@test "rust.bash skips installation when rust is already installed" { + # Create mock rustup command + cat > "$MOCK_BIN/rustup" << 'EOF' +#!/bin/bash +echo "rustup 1.26.0" +EOF + chmod +x "$MOCK_BIN/rustup" + + # Add mock bin to PATH + PATH="$MOCK_BIN:$PATH" + + # Run rust installation + run bash "$(pwd)/bin/install/rust.bash" + + # Should indicate rust is already installed + [[ "$output" =~ "Rust is already installed" ]] + [ "$status" -eq 0 ] +} \ No newline at end of file From b2b4e22c10d970f56d6da1c8cc58d9afd754858d Mon Sep 17 00:00:00 2001 From: Michael Uloth Date: Fri, 11 Jul 2025 15:41:36 -0400 Subject: [PATCH 6/6] Add test for rust.bash installation when rust not present --- test/install/test-rust-installation.bats | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/install/test-rust-installation.bats b/test/install/test-rust-installation.bats index 7cfbff15..aa84d96d 100644 --- a/test/install/test-rust-installation.bats +++ b/test/install/test-rust-installation.bats @@ -64,4 +64,40 @@ EOF # Should indicate rust is already installed [[ "$output" =~ "Rust is already installed" ]] [ "$status" -eq 0 ] +} + +@test "rust.bash installs rust when not present" { + # Create mock curl command that logs execution + local install_log="$TEST_TEMP_DIR/install.log" + cat > "$MOCK_BIN/curl" << EOF +#!/bin/bash +echo "curl executed with: \$@" > "$install_log" +# Mock the rustup script +cat << 'SCRIPT_EOF' +#!/bin/sh +echo "Mock rustup installer executed" +SCRIPT_EOF +EOF + chmod +x "$MOCK_BIN/curl" + + # Create mock sh to capture installation + cat > "$MOCK_BIN/sh" << 'EOF' +#!/bin/bash +echo "sh executed with rustup installer" +EOF + chmod +x "$MOCK_BIN/sh" + + # Override PATH to exclude system rustup but keep essential commands + PATH="$MOCK_BIN:/usr/bin:/bin" + + # Run rust installation + run bash "$(pwd)/bin/install/rust.bash" + + # Should indicate installation is happening + [[ "$output" =~ "Installing Rust toolchain" ]] + [[ "$output" =~ "Finished installing rustup" ]] + [ "$status" -eq 0 ] + + # Verify curl was called + [[ -f "$install_log" ]] } \ No newline at end of file