Skip to content
Merged
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
76 changes: 76 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -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/
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
ruby: ['3.1', '3.2', '3.3']
ruby: ['3.4', '4.0']
rust: [stable]
# Windows support is currently disabled due to rb-sys compatibility issues
# include:
Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
ruby-version: '4.0'
bundler-cache: true

- name: Run RuboCop
Expand All @@ -97,7 +97,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
ruby-version: '4.0'
bundler-cache: true

- name: Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
ruby:
- '3.3'
- '4.0'

steps:
- uses: actions/checkout@v4
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
ruby-version: '4.0'

- name: Extract version from tag
id: extract_version
Expand Down Expand Up @@ -70,13 +70,13 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
ruby-version: '4.0'
bundler-cache: true

- uses: oxidize-rb/actions/cross-gem@v1
with:
platform: ${{ matrix.platform }}
ruby-versions: '3.1,3.2,3.3'
ruby-versions: '3.4,4.0'

- name: Upload gem artifact
uses: actions/upload-artifact@v4
Expand All @@ -95,7 +95,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
ruby-version: '4.0'
bundler-cache: true

- name: Build source gem
Expand Down
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ GEM
thor (1.4.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.1.0)
unicode-emoji (4.2.0)

PLATFORMS
arm64-darwin-23
Expand Down
52 changes: 52 additions & 0 deletions docker/Dockerfile.test
Original file line number Diff line number Diff line change
@@ -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}\""]
24 changes: 24 additions & 0 deletions docker/compose.test.yml
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions ext/rfmt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ crate-type = ["cdylib"]

[dependencies]
# Ruby FFI
magnus = { version = "0.6.2" }
rb-sys = "0.9.117"
magnus = { version = "0.8.2" }
rb-sys = "0.9.124"

# Serialization
serde = { version = "1.0", features = ["derive"] }
Expand Down
6 changes: 3 additions & 3 deletions ext/rfmt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use policy::SecurityPolicy;

use config::Config;
use emitter::Emitter;
use magnus::{define_module, function, prelude::*, Error, Ruby};
use magnus::{function, prelude::*, Error, Ruby};
use parser::{PrismAdapter, RubyParser};

fn format_ruby_code(ruby: &Ruby, source: String, json: String) -> Result<String, Error> {
Expand Down Expand Up @@ -45,10 +45,10 @@ fn rust_version() -> String {
}

#[magnus::init]
fn init(_ruby: &Ruby) -> Result<(), Error> {
fn init(ruby: &Ruby) -> Result<(), Error> {
logging::RfmtLogger::init();

let module = define_module("Rfmt")?;
let module = ruby.define_module("Rfmt")?;

module.define_singleton_method("format_code", function!(format_ruby_code, 2))?;
module.define_singleton_method("parse_to_json", function!(parse_to_json, 1))?;
Expand Down
88 changes: 88 additions & 0 deletions scripts/test-gem-install.sh
Original file line number Diff line number Diff line change
@@ -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 ""
Loading