mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 15:23:03 +02:00
feat: downalod and install exercism
This commit is contained in:
parent
964f3b5df6
commit
1a2e7d7b49
106
scripts/utils/download_exercism_bulk.sh
Executable file
106
scripts/utils/download_exercism_bulk.sh
Executable file
@ -0,0 +1,106 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Download ALL Exercism exercises for offline practice
|
||||||
|
#
|
||||||
|
# This clones the official Exercism track repositories which contain
|
||||||
|
# ALL exercises with their test suites - no need to unlock one by one!
|
||||||
|
#
|
||||||
|
# Exercises are in: exercises/practice/<exercise-name>/
|
||||||
|
# Each exercise has tests you can run locally.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TRACKS_DIR="${HOME}/exercism-tracks"
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
success() { echo -e "${GREEN}✓ $1${NC}"; }
|
||||||
|
info() { echo -e "${BLUE}ℹ $1${NC}"; }
|
||||||
|
warn() { echo -e "${YELLOW}⚠ $1${NC}"; }
|
||||||
|
|
||||||
|
echo "=============================================="
|
||||||
|
echo " Exercism Bulk Exercise Downloader"
|
||||||
|
echo " Download ALL exercises for offline practice"
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
mkdir -p "$TRACKS_DIR"
|
||||||
|
cd "$TRACKS_DIR"
|
||||||
|
|
||||||
|
# Tracks to download (add/remove as needed)
|
||||||
|
declare -A TRACKS=(
|
||||||
|
["python"]="https://github.com/exercism/python.git"
|
||||||
|
["c"]="https://github.com/exercism/c.git"
|
||||||
|
["cpp"]="https://github.com/exercism/cpp.git"
|
||||||
|
["javascript"]="https://github.com/exercism/javascript.git"
|
||||||
|
["typescript"]="https://github.com/exercism/typescript.git"
|
||||||
|
["rust"]="https://github.com/exercism/rust.git"
|
||||||
|
["go"]="https://github.com/exercism/go.git"
|
||||||
|
["bash"]="https://github.com/exercism/bash.git"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Optional tracks (uncomment to include)
|
||||||
|
# TRACKS["java"]="https://github.com/exercism/java.git"
|
||||||
|
# TRACKS["ruby"]="https://github.com/exercism/ruby.git"
|
||||||
|
# TRACKS["haskell"]="https://github.com/exercism/haskell.git"
|
||||||
|
# TRACKS["elixir"]="https://github.com/exercism/elixir.git"
|
||||||
|
|
||||||
|
echo "Downloading ${#TRACKS[@]} tracks to: $TRACKS_DIR"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for track in "${!TRACKS[@]}"; do
|
||||||
|
url="${TRACKS[$track]}"
|
||||||
|
|
||||||
|
if [[ -d "$track" ]]; then
|
||||||
|
info "Updating $track..."
|
||||||
|
(cd "$track" && git pull --quiet) && success "$track updated"
|
||||||
|
else
|
||||||
|
info "Cloning $track..."
|
||||||
|
git clone --depth 1 "$url" && success "$track cloned"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show exercise count
|
||||||
|
if [[ -d "$track/exercises/practice" ]]; then
|
||||||
|
count=$(ls "$track/exercises/practice" | wc -l)
|
||||||
|
echo " → $count practice exercises available"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "=============================================="
|
||||||
|
echo " Download Complete!"
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
echo "Exercises location: $TRACKS_DIR/<track>/exercises/practice/"
|
||||||
|
echo ""
|
||||||
|
echo "Example - Running Python exercises:"
|
||||||
|
echo " cd $TRACKS_DIR/python/exercises/practice/hello-world"
|
||||||
|
echo " python -m pytest -v"
|
||||||
|
echo ""
|
||||||
|
echo "Example - Running C exercises:"
|
||||||
|
echo " cd $TRACKS_DIR/c/exercises/practice/hello-world"
|
||||||
|
echo " make test"
|
||||||
|
echo ""
|
||||||
|
echo "Example - Running JavaScript exercises:"
|
||||||
|
echo " cd $TRACKS_DIR/javascript/exercises/practice/hello-world"
|
||||||
|
echo " npm install && npm test"
|
||||||
|
echo ""
|
||||||
|
echo "Each exercise folder contains:"
|
||||||
|
echo " - README.md (instructions)"
|
||||||
|
echo " - *_test.* (test file - run these!)"
|
||||||
|
echo " - .meta/exemplar.* (reference solution - don't peek!)"
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
echo ""
|
||||||
|
echo "Track summary:"
|
||||||
|
for track in "${!TRACKS[@]}"; do
|
||||||
|
if [[ -d "$track/exercises/practice" ]]; then
|
||||||
|
count=$(ls "$track/exercises/practice" 2>/dev/null | wc -l)
|
||||||
|
printf " %-15s %3d exercises\n" "$track" "$count"
|
||||||
|
fi
|
||||||
|
done | sort
|
||||||
319
scripts/utils/install_exercism.sh
Executable file
319
scripts/utils/install_exercism.sh
Executable file
@ -0,0 +1,319 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Install Exercism CLI - Offline Coding Challenges
|
||||||
|
#
|
||||||
|
# Exercism is a free, open source platform with:
|
||||||
|
# - 65+ programming languages
|
||||||
|
# - Built-in test suites for each exercise
|
||||||
|
# - Works offline after downloading exercises
|
||||||
|
#
|
||||||
|
# Website: https://exercism.org
|
||||||
|
# License: AGPL-3.0
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
success() { echo -e "${GREEN}✓ $1${NC}"; }
|
||||||
|
warn() { echo -e "${YELLOW}⚠ $1${NC}"; }
|
||||||
|
error() { echo -e "${RED}✗ $1${NC}"; }
|
||||||
|
info() { echo -e "${BLUE}ℹ $1${NC}"; }
|
||||||
|
|
||||||
|
EXERCISM_DIR="${HOME}/exercism"
|
||||||
|
|
||||||
|
echo "=============================================="
|
||||||
|
echo " Exercism - Offline Coding Challenges"
|
||||||
|
echo " Free & Open Source with Built-in Tests"
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Install Exercism CLI
|
||||||
|
install_exercism_cli() {
|
||||||
|
if command -v exercism &>/dev/null; then
|
||||||
|
local version
|
||||||
|
version=$(exercism version 2>/dev/null | head -1)
|
||||||
|
success "Exercism CLI already installed: $version"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing Exercism CLI..."
|
||||||
|
|
||||||
|
# Try package managers first
|
||||||
|
if command -v pacman &>/dev/null; then
|
||||||
|
# Check AUR
|
||||||
|
if command -v yay &>/dev/null; then
|
||||||
|
yay -S --noconfirm exercism-bin
|
||||||
|
success "Exercism CLI installed via AUR"
|
||||||
|
return 0
|
||||||
|
elif command -v paru &>/dev/null; then
|
||||||
|
paru -S --noconfirm exercism-bin
|
||||||
|
success "Exercism CLI installed via AUR"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
elif command -v brew &>/dev/null; then
|
||||||
|
brew install exercism
|
||||||
|
success "Exercism CLI installed via Homebrew"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Manual installation from GitHub releases
|
||||||
|
info "Installing from GitHub releases..."
|
||||||
|
|
||||||
|
local arch
|
||||||
|
case "$(uname -m)" in
|
||||||
|
x86_64) arch="x86_64" ;;
|
||||||
|
aarch64 | arm64) arch="arm64" ;;
|
||||||
|
armv7l) arch="armv7" ;;
|
||||||
|
i686) arch="i386" ;;
|
||||||
|
*)
|
||||||
|
error "Unsupported architecture: $(uname -m)"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local os="linux"
|
||||||
|
[[ "$(uname -s)" == "Darwin" ]] && os="darwin"
|
||||||
|
|
||||||
|
# Get latest release
|
||||||
|
local latest_url="https://api.github.com/repos/exercism/cli/releases/latest"
|
||||||
|
local download_url
|
||||||
|
|
||||||
|
download_url=$(curl -fsSL "$latest_url" | grep "browser_download_url.*${os}-${arch}" | head -1 | cut -d '"' -f 4)
|
||||||
|
|
||||||
|
if [[ -z "$download_url" ]]; then
|
||||||
|
error "Could not find download URL for your system"
|
||||||
|
echo "Please install manually from: https://exercism.org/docs/using/solving-exercises/working-locally"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Downloading from: $download_url"
|
||||||
|
local temp_dir
|
||||||
|
temp_dir=$(mktemp -d)
|
||||||
|
|
||||||
|
curl -fL --progress-bar "$download_url" -o "$temp_dir/exercism.tar.gz"
|
||||||
|
tar -xzf "$temp_dir/exercism.tar.gz" -C "$temp_dir"
|
||||||
|
|
||||||
|
# Install to ~/.local/bin
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
mv "$temp_dir/exercism" "$HOME/.local/bin/"
|
||||||
|
chmod +x "$HOME/.local/bin/exercism"
|
||||||
|
|
||||||
|
rm -rf "$temp_dir"
|
||||||
|
|
||||||
|
success "Exercism CLI installed to ~/.local/bin/exercism"
|
||||||
|
|
||||||
|
# Check PATH
|
||||||
|
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
||||||
|
warn "Add ~/.local/bin to your PATH:"
|
||||||
|
echo ' export PATH="$HOME/.local/bin:$PATH"'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure exercism workspace
|
||||||
|
configure_exercism() {
|
||||||
|
echo ""
|
||||||
|
echo "=== Configuring Exercism ==="
|
||||||
|
|
||||||
|
mkdir -p "$EXERCISM_DIR"
|
||||||
|
|
||||||
|
# Check if already configured
|
||||||
|
if exercism configure 2>&1 | grep -q "workspace"; then
|
||||||
|
success "Exercism already configured"
|
||||||
|
else
|
||||||
|
# Set workspace directory
|
||||||
|
exercism configure --workspace="$EXERCISM_DIR"
|
||||||
|
success "Workspace set to: $EXERCISM_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "To fully configure Exercism with your account:"
|
||||||
|
echo " 1. Create free account at https://exercism.org"
|
||||||
|
echo " 2. Go to https://exercism.org/settings/api_cli"
|
||||||
|
echo " 3. Copy your API token"
|
||||||
|
echo " 4. Run: exercism configure --token=YOUR_TOKEN"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install test runners for languages
|
||||||
|
install_test_runners() {
|
||||||
|
echo ""
|
||||||
|
echo "=== Installing Test Runners ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Python - pytest
|
||||||
|
if command -v python3 &>/dev/null; then
|
||||||
|
if python3 -c "import pytest" 2>/dev/null; then
|
||||||
|
success "Python: pytest already installed"
|
||||||
|
else
|
||||||
|
info "Installing pytest for Python exercises..."
|
||||||
|
pip3 install --user pytest 2>/dev/null && success "Python: pytest installed" || warn "Python: install pytest manually"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# JavaScript/TypeScript - Node.js + npm
|
||||||
|
if command -v node &>/dev/null; then
|
||||||
|
success "JavaScript/TypeScript: Node.js available ($(node --version))"
|
||||||
|
info " Tests run with: npm test (or jest)"
|
||||||
|
else
|
||||||
|
warn "JavaScript/TypeScript: Install Node.js for JS/TS exercises"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# C - gcc + criterion/cmocka
|
||||||
|
if command -v gcc &>/dev/null; then
|
||||||
|
success "C: gcc available"
|
||||||
|
info " Some C exercises use Unity test framework (included in exercise)"
|
||||||
|
else
|
||||||
|
warn "C: Install gcc for C exercises"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# C++ - g++ + Catch2/doctest
|
||||||
|
if command -v g++ &>/dev/null; then
|
||||||
|
success "C++: g++ available"
|
||||||
|
info " C++ exercises use Catch2 (header-only, included in exercise)"
|
||||||
|
else
|
||||||
|
warn "C++: Install g++ for C++ exercises"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Rust
|
||||||
|
if command -v cargo &>/dev/null; then
|
||||||
|
success "Rust: cargo available (tests with: cargo test)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Go
|
||||||
|
if command -v go &>/dev/null; then
|
||||||
|
success "Go: go available (tests with: go test)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Download exercises for a track (language)
|
||||||
|
download_track() {
|
||||||
|
local track="$1"
|
||||||
|
local count="${2:-10}"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "Downloading $count exercises for $track track..."
|
||||||
|
|
||||||
|
# Get list of exercises
|
||||||
|
local exercises
|
||||||
|
exercises=$(curl -fsSL "https://exercism.org/api/v2/tracks/${track}/exercises" 2>/dev/null |
|
||||||
|
grep -oP '"slug":"\K[^"]+' | head -n "$count")
|
||||||
|
|
||||||
|
if [[ -z "$exercises" ]]; then
|
||||||
|
warn "Could not fetch exercise list for $track"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local downloaded=0
|
||||||
|
for exercise in $exercises; do
|
||||||
|
local exercise_dir="$EXERCISM_DIR/$track/$exercise"
|
||||||
|
if [[ -d "$exercise_dir" ]]; then
|
||||||
|
echo " [exists] $exercise"
|
||||||
|
else
|
||||||
|
if exercism download --track="$track" --exercise="$exercise" 2>/dev/null; then
|
||||||
|
echo " [downloaded] $exercise"
|
||||||
|
((downloaded++))
|
||||||
|
else
|
||||||
|
echo " [failed] $exercise (may require auth)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
success "Downloaded $downloaded new exercises for $track"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show available tracks and usage
|
||||||
|
show_usage() {
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo " Exercism Usage Guide"
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}Download exercises:${NC}"
|
||||||
|
echo " exercism download --track=python --exercise=hello-world"
|
||||||
|
echo " exercism download --track=javascript --exercise=two-fer"
|
||||||
|
echo " exercism download --track=c --exercise=isogram"
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}Run tests locally:${NC}"
|
||||||
|
echo " Python: cd ~/exercism/python/hello-world && pytest"
|
||||||
|
echo " JavaScript: cd ~/exercism/javascript/hello-world && npm test"
|
||||||
|
echo " TypeScript: cd ~/exercism/typescript/hello-world && npm test"
|
||||||
|
echo " C: cd ~/exercism/c/hello-world && make test"
|
||||||
|
echo " C++: cd ~/exercism/cpp/hello-world && make"
|
||||||
|
echo " Rust: cd ~/exercism/rust/hello-world && cargo test"
|
||||||
|
echo " Go: cd ~/exercism/go/hello-world && go test"
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}Submit solution (when online):${NC}"
|
||||||
|
echo " exercism submit solution.py"
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}Popular tracks:${NC}"
|
||||||
|
echo " python, javascript, typescript, c, cpp, rust, go, java, ruby"
|
||||||
|
echo " bash, elixir, haskell, kotlin, swift, csharp, php, sql"
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}Batch download (requires API token):${NC}"
|
||||||
|
echo " # Download first 20 Python exercises:"
|
||||||
|
echo " for ex in \$(exercism download --track=python 2>&1 | head -20); do"
|
||||||
|
echo " exercism download --track=python --exercise=\$ex"
|
||||||
|
echo " done"
|
||||||
|
echo ""
|
||||||
|
echo "Exercises are in: $EXERCISM_DIR"
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main
|
||||||
|
main() {
|
||||||
|
# Step 1: Install CLI
|
||||||
|
echo ""
|
||||||
|
echo "=== Step 1: Installing Exercism CLI ==="
|
||||||
|
install_exercism_cli
|
||||||
|
|
||||||
|
# Step 2: Configure
|
||||||
|
configure_exercism
|
||||||
|
|
||||||
|
# Step 3: Install test runners
|
||||||
|
install_test_runners
|
||||||
|
|
||||||
|
# Step 4: Download sample exercises
|
||||||
|
echo ""
|
||||||
|
echo "=== Step 4: Downloading Sample Exercises ==="
|
||||||
|
echo ""
|
||||||
|
echo "Downloading a few starter exercises for common languages..."
|
||||||
|
echo "(Full download requires API token from exercism.org)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Try to download hello-world for each track
|
||||||
|
local tracks=("python" "javascript" "typescript" "c" "cpp")
|
||||||
|
|
||||||
|
for track in "${tracks[@]}"; do
|
||||||
|
local exercise_dir="$EXERCISM_DIR/$track/hello-world"
|
||||||
|
if [[ -d "$exercise_dir" ]]; then
|
||||||
|
echo " [$track] hello-world already exists"
|
||||||
|
else
|
||||||
|
if exercism download --track="$track" --exercise="hello-world" 2>/dev/null; then
|
||||||
|
success "[$track] hello-world downloaded"
|
||||||
|
else
|
||||||
|
warn "[$track] hello-world requires authentication"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Show usage
|
||||||
|
show_usage
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
success "Installation complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Sign up at https://exercism.org (free)"
|
||||||
|
echo " 2. Get your token from https://exercism.org/settings/api_cli"
|
||||||
|
echo " 3. Run: exercism configure --token=YOUR_TOKEN"
|
||||||
|
echo " 4. Download exercises and code offline!"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Loading…
Reference in New Issue
Block a user