mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-12-28 06:49:19 +00:00
Add tooling for GitHub Codespaces
With this, a new user can fork Rustlings and start a Github Codespace. The Container will already be correctly set up with everything needed, and VSCode tasks are set up for starting rustlings.
This commit is contained in:
parent
2af9e89ba5
commit
8e99ca9c0c
41
.devcontainer/Dockerfile
Normal file
41
.devcontainer/Dockerfile
Normal file
@ -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
.devcontainer/devcontainer.json
Normal file
58
.devcontainer/devcontainer.json
Normal file
@ -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
.devcontainer/validate.sh
Executable file
75
.devcontainer/validate.sh
Executable file
@ -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
.vscode/tasks.json
vendored
Normal file
95
.vscode/tasks.json
vendored
Normal file
@ -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…
x
Reference in New Issue
Block a user