Ruby Rake Bundler Change Directory
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
- Environment Isolation: Ensures all commands execute in the context of the
./demo
directory. - Cross-Platform Compatibility: Works reliably across Unix-like systems and Windows.
- Reuse: Centralizes directory handling logic to minimize duplication.