From acec7fd69d1c88d3867b77759e28bad7989870a8 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Mon, 12 May 2014 14:14:46 +0100 Subject: Implemented a very basic plugin system. The way this works is pretty much the same way as `git` commands work. When invoking `bundler `, if the task isn't defined on Bundler::CLI, Bundler will try and figure out if there is a `bundler-` binary present on the path. If so, it's invoked. Same error message (and error codes) apply when a binary isn't found. Also, this is just a first, simple pass at the problem. @indirect and I had a chat about how it should work, and we should probably think about offering the possibility of loading up Ruby plugins in the already loaded Bundler environment. --- lib/bundler/cli.rb | 6 ++++++ spec/bundler/cli_spec.rb | 13 +++++++++++++ spec/support/helpers.rb | 11 +++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index bae7f54641..e9c47b6db1 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -67,6 +67,12 @@ module Bundler end end + def self.handle_no_command_error(command, has_namespace = $thor_runner) + return super unless command_path = Bundler.which("bundler-#{command}") + + Kernel.exec(command_path, *ARGV[1..-1]) + end + desc "init [OPTIONS]", "Generates a Gemfile into the current working directory" long_desc <<-D Init generates a default Gemfile in the current working directory. When adding a diff --git a/spec/bundler/cli_spec.rb b/spec/bundler/cli_spec.rb index ef4ec79656..a6a122a4c3 100644 --- a/spec/bundler/cli_spec.rb +++ b/spec/bundler/cli_spec.rb @@ -13,4 +13,17 @@ describe "bundle executable" do bundle 'unrecognized-tast', :exitstatus => true expect(exitstatus).to_not be_zero end + + it "looks for a binary and executes it if it's named bundler-" do + File.open(tmp('bundler-testtasks'), 'w', 0755) do |f| + f.puts "#!/usr/bin/env ruby\nputs 'Hello, world'\n" + end + + with_path_as(tmp) do + bundle 'testtasks', :exitstatus => true + end + + expect(exitstatus).to be_zero + expect(out).to eq('Hello, world') + end end diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb index cb09ecf834..a3a4b16aae 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -74,7 +74,6 @@ module Spec end.join cmd = "#{env} #{sudo} #{Gem.ruby} -I#{lib} #{requires_str} #{bundle_bin} #{cmd}#{args}" - if exitstatus sys_status(cmd) else @@ -83,7 +82,7 @@ module Spec end def bundle_ruby(options = {}) - expect_err = options.delete(:expect_err) + expect_err = options.delete(:expect_err) exitstatus = options.delete(:exitstatus) options["no-color"] = true unless options.key?("no-color") @@ -218,6 +217,14 @@ module Spec ENV['GEM_HOME'], ENV['GEM_PATH'] = gem_home, gem_path end + def with_path_as(path) + old_path = ENV['PATH'] + ENV['PATH'] = "#{path}:#{ENV['PATH']}" + yield + ensure + ENV['PATH'] = old_path + end + def break_git! FileUtils.mkdir_p(tmp("broken_path")) File.open(tmp("broken_path/git"), "w", 0755) do |f| -- cgit v1.2.1