Managing Jekyll Subdirectories with Bundler in Rake Tasks

When working on Jekyll plugins, a common requirement is to include a demo site for testing and showcasing functionality. This demo site often resides in a subdirectory (e.g., ./demo) with its own Gemfile, distinct from the plugin’s root Gemfile. Ensuring commands like bundle install and jekyll build execute correctly in this subdirectory while integrating seamlessly into a Rake-based workflow can be challenging, especially on cross-platform setups.

Problem: Subdirectory Context in Rake Tasks

Directly invoking commands like cd demo && bundle install in Rake tasks doesn’t reliably handle environment configurations. Specifically:

  • Bundler Context: Commands may still use the root Gemfile.
  • Environment Isolation: Switching directories alone doesn’t guarantee the correct environment is loaded, especially on Windows systems.

Solution: Explicit Environment Configuration

By explicitly setting the BUNDLE_GEMFILE environment variable, we can ensure Bundler uses the correct Gemfile for the subdirectory. A helper method centralizes this logic:

def safely_in_demo_dir
  demo_dir = File.join(Dir.pwd, "demo")
  raise "Demo directory not found: #{demo_dir}" unless Dir.exist?(demo_dir)

  ENV['BUNDLE_GEMFILE'] = File.join(demo_dir, "Gemfile")

  Dir.chdir(demo_dir) do
    yield
  end
ensure
  ENV.delete('BUNDLE_GEMFILE')
end

Implementation in Rake Tasks

The helper method integrates seamlessly into tasks:

namespace :demo do
  desc "Build the Jekyll demo site"
  task :build do
    safely_in_demo_dir do
      sh "bundle install"
      sh "bundle exec jekyll build"
    end
  end

  desc "Serve the Jekyll demo site locally"
  task :serve do
    safely_in_demo_dir do
      sh "bundle install"
      sh "bundle exec jekyll serve"
    end
  end
end

Key Benefits

  1. Environment Isolation: Ensures all commands execute in the context of the ./demo directory.
  2. Cross-Platform Compatibility: Works reliably across Unix-like systems and Windows.
  3. Reuse: Centralizes directory handling logic to minimize duplication.