#!/usr/bin/env bash # Verifies the claims in how-to-install-rubygems-ubuntu.html. # Standalone-safe: makes no lasting changes to the machine (any probe # directory it creates to test writability is removed immediately). set -u PASS=0 FAIL=0 SKIP=0 CONTENT=0 pass() { echo "PASS: $1"; PASS=$((PASS+1)); } fail() { echo "FAIL: $1"; FAIL=$((FAIL+1)); } skip() { echo "SKIP: $1"; SKIP=$((SKIP+1)); } content() { echo "CONTENT: $1"; CONTENT=$((CONTENT+1)); } # --- Claim: ruby and gem are both runnable, and gem -v succeeds without any # separate "install RubyGems" step having been performed by this script. --- if ! command -v ruby >/dev/null 2>&1; then skip "ruby not found on PATH — cannot check bundled RubyGems" else RUBY_VER="$(ruby -v 2>&1)" pass "ruby -v ran: $RUBY_VER" if ! command -v gem >/dev/null 2>&1; then fail "ruby is installed but gem is not on PATH — this would contradict the article's bundling claim" else GEM_VER="$(gem -v 2>&1)" if [[ "$GEM_VER" =~ ^[0-9]+\.[0-9]+ ]]; then pass "gem -v ran with no separate install step: $GEM_VER" else fail "gem -v did not return a version number: $GEM_VER" fi fi fi # --- Claim: the system/default gem install directory is not writable # without sudo, but the user install directory is — without creating # any lasting files (probe file is removed immediately either way). --- if command -v gem >/dev/null 2>&1; then SYS_DIR="$(gem environment gemdir 2>/dev/null)" if [[ -n "$SYS_DIR" && -d "$SYS_DIR" ]]; then PROBE="$SYS_DIR/.verify_probe_$$" if ( touch "$PROBE" ) 2>/dev/null; then rm -f "$PROBE" skip "system gem dir ($SYS_DIR) IS writable without sudo on this machine — the SIP-protected-path claim is macOS-specific and doesn't hold everywhere; not a failure" else pass "system gem dir ($SYS_DIR) is NOT writable without sudo, matching the article's finding" fi else skip "could not determine system gem dir — cannot test writability" fi USER_DIR="$(gem environment | grep 'USER INSTALLATION DIRECTORY' | sed 's/.*: *//')" if [[ -n "$USER_DIR" ]]; then PRE_EXISTED=0 [[ -d "$USER_DIR" ]] && PRE_EXISTED=1 mkdir -p "$USER_DIR" 2>/dev/null PROBE="$USER_DIR/.verify_probe_$$" if ( touch "$PROBE" ) 2>/dev/null; then rm -f "$PROBE" pass "user gem dir ($USER_DIR) is writable without sudo, matching the article's --user-install claim" else fail "user gem dir ($USER_DIR) was not writable without sudo" fi # Clean up: if this script created the directory (it did not pre-exist), # remove it so the script leaves no trace, same as the article's own probe. if [[ "$PRE_EXISTED" -eq 0 ]]; then rmdir "$USER_DIR" 2>/dev/null rmdir "$(dirname "$USER_DIR")" 2>/dev/null fi else skip "could not determine user gem install directory" fi else skip "gem not available — cannot test system/user gem dir writability" fi # --- Ubuntu-specific claims (ruby-full pulls Ruby 3.2 on 24.04, apt install # ruby-full) are cited from packages.ubuntu.com, not executable here # unless this is actually Ubuntu with apt available. --- if [[ -f /etc/os-release ]] && grep -qi ubuntu /etc/os-release 2>/dev/null && command -v apt-cache >/dev/null 2>&1; then APT_VER="$(apt-cache policy ruby-full 2>/dev/null | grep Candidate | awk '{print $2}')" if [[ -n "$APT_VER" ]]; then pass "apt-cache reports ruby-full candidate version: $APT_VER (compare to article's cited 1:3.2~ubuntu1 for 24.04)" else skip "apt-cache could not resolve a candidate version for ruby-full" fi else skip "not running on Ubuntu with apt available — ruby-full package version claim is a citation to packages.ubuntu.com, not executable here" fi ARTICLE="$(dirname "$0")/how-to-install-rubygems-ubuntu.html" if [[ -f "$ARTICLE" ]]; then grep -q "RubyGems ships with Ruby" "$ARTICLE" && content "article cites the RubyGems bundling guide" || fail "article missing the RubyGems bundling citation" grep -q -- "--user-install" "$ARTICLE" && content "article explains --user-install as the sudo alternative" || fail "article missing --user-install guidance" else skip "article HTML not present alongside script — content checks skipped (expected for a standalone /verify/ download)" skip "article HTML not present alongside script — content checks skipped (expected for a standalone /verify/ download)" fi echo "PASS=$PASS FAIL=$FAIL SKIP=$SKIP CONTENT=$CONTENT" [[ $FAIL -eq 0 ]]