Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Use the official Rust image as base
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye

# Set the minimum required Rust version for Rustlings
ENV RUST_VERSION=1.88.0
ENV RUSTUP_HOME=/usr/local/rustup
ENV PATH=/usr/local/rustup/bin:$PATH

# Install the specific Rust version and required components
RUN rustup install ${RUST_VERSION} \
&& rustup default ${RUST_VERSION} \
&& rustup component add clippy rustfmt rust-src \
&& rustup --version \
&& rustc --version \
&& cargo --version \
&& cargo clippy --version

# Install additional useful tools for Rust development
RUN apt-get update && apt-get install -y \
# Git for version control (should already be installed but ensuring it's present)
git \
# Build essentials for any native dependencies
build-essential \
# Tools for debugging and profiling
gdb \
valgrind \
# Text processing tools that might be useful for Rustlings
jq \
tree \
# Clean up apt cache to reduce image size
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Set up the workspace directory
WORKDIR /workspaces/rustlings

# Verify the installation works correctly
RUN rustc --version \
&& cargo --version \
&& clippy-driver --version \
&& rustfmt --version
58 changes: 58 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"name": "Rustlings Development Environment",
"build": {
"dockerfile": "Dockerfile",
"context": "."
},
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
"ghcr.io/devcontainers/features/git:1": {
"ppa": true,
"version": "latest"
}
},
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": {
"setup-tools": "rustc --version && cargo --version && rustup component add clippy rustfmt",
"validate": ".devcontainer/validate.sh",
"setup-welcome": "echo 'echo \"🦀 Welcome to the Rustlings development environment!\"' >> ~/.bashrc && echo 'echo \"Rust version: $(rustc --version)\"' >> ~/.bashrc && echo 'echo \"Ready to start learning Rust with Rustlings!\"' >> ~/.bashrc"
},
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"rust-lang.rust-analyzer"
],
"settings": {
"rust-analyzer.cargo.buildScripts.enable": true,
"rust-analyzer.procMacro.enable": true,
"editor.formatOnSave": true,
"editor.tabSize": 4,
"editor.insertSpaces": true,
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"terminal.integrated.defaultProfile.linux": "bash",
"[rust]": {
"editor.defaultFormatter": null
}
}
}
},
// Set container environment variables
"containerEnv": {
"RUSTLINGS_DEV_MODE": "1"
},
// Port forwarding for any potential web servers or debugging
"forwardPorts": [
8080,
3000
],
// Lifecycle scripts
"onCreateCommand": {
"install-tools": "rustup component add clippy rustfmt && rustup update"
},
// Mount the workspace to preserve file permissions and git configuration
"mounts": [
"source=${localWorkspaceFolder}/.git,target=${containerWorkspaceFolder}/.git,type=bind,consistency=cached"
]
}
75 changes: 75 additions & 0 deletions .devcontainer/validate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/bin/bash

# Devcontainer validation script for Rustlings
# This script tests that all required tools are available and working

set -e

echo "🦀 Validating Rustlings Devcontainer Setup..."
echo "=============================================="

# Check Rust toolchain
echo "✓ Checking Rust toolchain..."
rustc --version
cargo --version

# Check minimum Rust version (1.88+)
RUST_VERSION=$(rustc --version | sed 's/rustc \([0-9]\+\.[0-9]\+\).*/\1/')
REQUIRED_VERSION="1.88"

if [ "$(printf '%s\n' "$REQUIRED_VERSION" "$RUST_VERSION" | sort -V | head -n1)" = "$REQUIRED_VERSION" ]; then
echo " ✓ Rust version $RUST_VERSION meets requirement (≥ $REQUIRED_VERSION)"
else
echo " ✗ Rust version $RUST_VERSION does not meet requirement (≥ $REQUIRED_VERSION)"
exit 1
fi

# Check required components
echo "✓ Checking required Rust components..."
rustup component list --installed | grep -q "clippy" && echo " ✓ Clippy is installed"
rustup component list --installed | grep -q "rustfmt" && echo " ✓ rustfmt is installed"

# Test clippy works
echo "✓ Testing Clippy..."
clippy-driver --version > /dev/null && echo " ✓ Clippy is functional"

# Test rustfmt works
echo "✓ Testing rustfmt..."
rustfmt --version > /dev/null && echo " ✓ rustfmt is functional"

# Check Git
echo "✓ Checking Git..."
git --version > /dev/null && echo " ✓ Git is installed"

# Test basic Rust compilation
echo "✓ Testing Rust compilation..."
cd /tmp
cargo init --name test_project > /dev/null 2>&1
cd test_project
cargo check > /dev/null 2>&1 && echo " ✓ Rust compilation works"
cd .. && rm -rf test_project

# Check if we're in the Rustlings workspace
echo "✓ Checking Rustlings workspace..."
if [ -f "/workspaces/rustlings/Cargo.toml" ]; then
echo " ✓ Rustlings workspace is mounted correctly"
cd /workspaces/rustlings

# Test Rustlings build
echo "✓ Testing Rustlings build..."
cargo check > /dev/null 2>&1 && echo " ✓ Rustlings compiles successfully"

# Test Rustlings clippy
echo "✓ Testing Rustlings clippy..."
cargo clippy -- --deny warnings > /dev/null 2>&1 && echo " ✓ Rustlings passes clippy checks"
else
echo " ⚠ Rustlings workspace not found at expected path"
fi

echo ""
echo "🎉 Devcontainer validation completed successfully!"
echo "Ready to start learning Rust with Rustlings!"
echo ""
echo "Try running:"
echo " cargo run -- init # Initialize exercises"
echo " cargo run -- watch # Start watching for changes"
95 changes: 95 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"version": "2.0.0",
"tasks": [

{
"label": "Start Rustlings",
"type": "shell",
"command": "cargo",
"args": [
"run"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new",
"clear": true
},
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Rustlings: Run Exercise",
"type": "shell",
"command": "cargo",
"args": [
"run",
"--",
"run",
"${input:exerciseName}"
],
"group": "build",
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Rustlings: Get Hint",
"type": "shell",
"command": "cargo",
"args": [
"run",
"--",
"hint",
"${input:exerciseName}"
],
"group": "build",
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Rustlings: Reset Exercise",
"type": "shell",
"command": "cargo",
"args": [
"run",
"--",
"reset",
"${input:exerciseName}"
],
"group": "build",
"presentation": {
"reveal": "always",
"panel": "shared"
},
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
}
],
"inputs": [
{
"id": "exerciseName",
"description": "Exercise name (e.g., variables1, functions2)",
"default": "",
"type": "promptString"
}
]
}
Loading