summaryrefslogtreecommitdiff
path: root/lib/bundler/cli/exec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bundler/cli/exec.rb')
-rw-r--r--lib/bundler/cli/exec.rb54
1 files changed, 34 insertions, 20 deletions
diff --git a/lib/bundler/cli/exec.rb b/lib/bundler/cli/exec.rb
index 0b0e991ea5..2fdc416286 100644
--- a/lib/bundler/cli/exec.rb
+++ b/lib/bundler/cli/exec.rb
@@ -12,29 +12,27 @@ module Bundler
@options = options
@cmd = args.shift
@args = args
-
- if !Bundler.current_ruby.jruby?
- @args << { :close_others => !options.keep_file_descriptors? }
- elsif options.keep_file_descriptors?
- Bundler.ui.warn "Ruby version #{RUBY_VERSION} defaults to keeping non-standard file descriptors on Kernel#exec."
- end
+ @args << { close_others: !options.keep_file_descriptors? } unless Bundler.current_ruby.jruby?
end
def run
validate_cmd!
SharedHelpers.set_bundle_environment
if bin_path = Bundler.which(cmd)
- if !Bundler.settings[:disable_exec_load] && ruby_shebang?(bin_path)
- return kernel_load(bin_path, *args)
+ if !Bundler.settings[:disable_exec_load] && directly_loadable?(bin_path)
+ bin_path.delete_suffix!(".bat") if Gem.win_platform?
+ kernel_load(bin_path, *args)
+ else
+ bin_path = "./" + bin_path unless File.absolute_path?(bin_path)
+ kernel_exec(bin_path, *args)
end
- kernel_exec(bin_path, *args)
else
# exec using the given command
kernel_exec(cmd, *args)
end
end
- private
+ private
def validate_cmd!
return unless cmd.nil?
@@ -43,15 +41,11 @@ module Bundler
end
def kernel_exec(*args)
- ui = Bundler.ui
- Bundler.ui = nil
Kernel.exec(*args)
rescue Errno::EACCES, Errno::ENOEXEC
- Bundler.ui = ui
Bundler.ui.error "bundler: not executable: #{cmd}"
exit 126
rescue Errno::ENOENT
- Bundler.ui = ui
Bundler.ui.error "bundler: command not found: #{cmd}"
Bundler.ui.warn "Install missing gem executables with `bundle install`"
exit 127
@@ -62,24 +56,44 @@ module Bundler
ARGV.replace(args)
$0 = file
Process.setproctitle(process_title(file, args)) if Process.respond_to?(:setproctitle)
- ui = Bundler.ui
- Bundler.ui = nil
require_relative "../setup"
TRAPPED_SIGNALS.each {|s| trap(s, "DEFAULT") }
Kernel.load(file)
rescue SystemExit, SignalException
raise
- rescue Exception => e # rubocop:disable Lint/RescueException
- Bundler.ui = ui
+ rescue Exception # rubocop:disable Lint/RescueException
Bundler.ui.error "bundler: failed to load command: #{cmd} (#{file})"
- backtrace = e.backtrace ? e.backtrace.take_while {|bt| !bt.start_with?(__FILE__) } : []
- abort "#{e.class}: #{e.message}\n #{backtrace.join("\n ")}"
+ Bundler::FriendlyErrors.disable!
+ raise
end
def process_title(file, args)
"#{file} #{args.join(" ")}".strip
end
+ def directly_loadable?(file)
+ if Gem.win_platform?
+ script_wrapper?(file)
+ else
+ ruby_shebang?(file)
+ end
+ end
+
+ def script_wrapper?(file)
+ script_file = file.delete_suffix(".bat")
+ return false unless File.exist?(script_file)
+
+ if File.zero?(script_file)
+ Bundler.ui.warn "#{script_file} is empty"
+ return false
+ end
+
+ header = File.open(file, "r") {|f| f.read(32) }
+ ruby_exe = "#{RbConfig::CONFIG["RUBY_INSTALL_NAME"]}#{RbConfig::CONFIG["EXEEXT"]}"
+ ruby_exe = "ruby.exe" if ruby_exe.empty?
+ header.include?(ruby_exe)
+ end
+
def ruby_shebang?(file)
possibilities = [
"#!/usr/bin/env ruby\n",