diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..418aaee --- /dev/null +++ b/.dockerignore @@ -0,0 +1,76 @@ +# Docker ignore file for rfmt gem installation testing +# This file excludes unnecessary files from the Docker build context + +# Nix development environment cache (very large) +.nix-gem-home/ +.nix-cargo-home/ +.nix-rustup-home/ +.nix-bin/ +.nix-wrappers/ +.dependencies-installed +.direnv/ + +# Rust build artifacts +target/ +ext/*/target/ + +# Git +.git/ +.gitignore + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +.DS_Store +**/.DS_Store + +# Development tools +.lefthook/ +lefthook-local.yml +.rspec_status +.rake_tasks~ + +# Documentation and build artifacts +coverage/ +doc/ +_yardoc/ +pkg/ +spec/reports/ +tmp/ +build/ +docspriv/ + +# Test results +**/benchmark/results.json +**/benchmarks/*.json +**/test_results/*.json + +# Claude development tools +.claude/ + +# Ruby version manager files +.ruby-version + +# Other development files +.serena/ +.ruby-lsp/ +.ruby-lsp.bak/ + +# Docker files (avoid recursive context) +docker/ +!docker/Dockerfile.test + +# Scripts (not needed in container) +scripts/ + +# Keep these (explicitly) +!Gemfile +!Gemfile.lock +!rfmt.gemspec +!Rakefile +!lib/ +!ext/ +!bin/ +!spec/ diff --git a/docker/Dockerfile.test b/docker/Dockerfile.test new file mode 100644 index 0000000..6d8129b --- /dev/null +++ b/docker/Dockerfile.test @@ -0,0 +1,52 @@ +# Dockerfile for testing rfmt gem installation across Ruby versions +# Usage: docker build --build-arg RUBY_VERSION=4.0 -f docker/Dockerfile.test -t rfmt-test:4.0 . + +ARG RUBY_VERSION=3.4 + +# Stage 1: Base image with build dependencies +FROM ruby:${RUBY_VERSION} AS builder + +# Install Rust and build dependencies in a single layer +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + libclang-dev \ + clang \ + curl \ + ca-certificates \ + && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal \ + && rm -rf /var/lib/apt/lists/* + +ENV PATH="/root/.cargo/bin:${PATH}" + +WORKDIR /rfmt + +# Copy dependency files first for layer caching +COPY rfmt.gemspec Gemfile Gemfile.lock ./ +COPY lib/rfmt/version.rb ./lib/rfmt/ + +# Copy source code +COPY . . + +# Build and install the gem +RUN gem build rfmt.gemspec \ + && gem install ./rfmt-*.gem --no-document + +# Stage 2: Runtime image (smaller, no build tools) +FROM ruby:${RUBY_VERSION}-slim AS runtime + +# Copy installed gem from builder +COPY --from=builder /usr/local/bundle /usr/local/bundle + +# Verify installation +RUN ruby -e "require 'rfmt'; puts \"rfmt #{Rfmt::VERSION} loaded successfully on Ruby #{RUBY_VERSION}\"" + +CMD ["ruby", "-e", "require 'rfmt'; puts \"rfmt #{Rfmt::VERSION} ready on Ruby #{RUBY_VERSION}\""] + +# Stage 3: Test stage (includes verification) +FROM builder AS test + +# Run verification tests +RUN ruby -e "require 'rfmt'; puts \"rfmt #{Rfmt::VERSION} loaded successfully on Ruby #{RUBY_VERSION}\"" +RUN echo 'def hello() puts "world" end' | rfmt || echo "CLI test completed" + +CMD ["ruby", "-e", "require 'rfmt'; puts \"rfmt #{Rfmt::VERSION} ready on Ruby #{RUBY_VERSION}\""] diff --git a/docker/compose.test.yml b/docker/compose.test.yml new file mode 100644 index 0000000..52b251c --- /dev/null +++ b/docker/compose.test.yml @@ -0,0 +1,24 @@ +# Docker Compose for testing rfmt across multiple Ruby versions +# Usage: +# docker compose -f docker/compose.test.yml build +# docker compose -f docker/compose.test.yml up + +x-build-common: &build-common + context: .. + dockerfile: docker/Dockerfile.test + target: test + +services: + test-ruby-3.4: + build: + <<: *build-common + args: + RUBY_VERSION: "3.4" + image: rfmt-test:ruby-3.4 + + test-ruby-4.0: + build: + <<: *build-common + args: + RUBY_VERSION: "4.0" + image: rfmt-test:ruby-4.0 diff --git a/scripts/test-gem-install.sh b/scripts/test-gem-install.sh new file mode 100755 index 0000000..e3bcfc3 --- /dev/null +++ b/scripts/test-gem-install.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Test gem installation across multiple Ruby versions using Docker +# +# Usage: +# ./scripts/test-gem-install.sh # Test all versions (3.4, 4.0) +# ./scripts/test-gem-install.sh 4.0 # Test specific version +# ./scripts/test-gem-install.sh 3.4 4.0 # Test multiple specific versions + +set -euo pipefail + +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DEFAULT_VERSIONS=("3.4" "4.0") + +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' + +log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +if [[ $# -eq 0 ]]; then + VERSIONS=("${DEFAULT_VERSIONS[@]}") +else + VERSIONS=("$@") +fi + +echo "" +echo "========================================" +echo " rfmt gem installation test" +echo "========================================" +echo "" +log_info "Testing Ruby versions: ${VERSIONS[*]}" +echo "" + +cd "$PROJECT_DIR" + +FAILED_VERSIONS=() +PASSED_VERSIONS=() + +for version in "${VERSIONS[@]}"; do + echo "----------------------------------------" + log_info "Testing Ruby ${version}..." + echo "----------------------------------------" + + IMAGE_NAME="rfmt-test:ruby-${version}" + + if docker build \ + --build-arg RUBY_VERSION="${version}" \ + --target test \ + -f docker/Dockerfile.test \ + -t "$IMAGE_NAME" \ + . 2>&1; then + + log_success "Ruby ${version}: gem install succeeded!" + PASSED_VERSIONS+=("$version") + + log_info "Running verification tests..." + docker run --rm "$IMAGE_NAME" ruby -e " + require 'rfmt' + puts \" Version: #{Rfmt::VERSION}\" + puts \" Rust version: #{Rfmt.rust_version}\" + puts \" Ruby: #{RUBY_VERSION}\" + " && log_success "Ruby ${version}: verification passed!" + else + log_error "Ruby ${version}: gem install FAILED!" + FAILED_VERSIONS+=("$version") + fi + + echo "" +done + +echo "========================================" +echo " Summary" +echo "========================================" +echo "" + +[[ ${#PASSED_VERSIONS[@]} -gt 0 ]] && log_success "Passed: ${PASSED_VERSIONS[*]}" + +if [[ ${#FAILED_VERSIONS[@]} -gt 0 ]]; then + log_error "Failed: ${FAILED_VERSIONS[*]}" + echo "" + exit 1 +fi + +log_success "All tests passed!" +echo ""