class Noexec

Constants

CURRENT
DEBUG

Attributes

bin[R]
gemfile[R]
rubygems_specs[R]

Public Class Methods

new(bin) click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 9
def initialize(bin)
  log "Bin used: #{bin}"
  bin = bin.split(/ /)
  @bin = File.basename(bin[1]||bin[0])
  log "Bin calculated: #{@bin}"
end

Public Instance Methods

candidate?() click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 27
def candidate?
  log "Examining #{gemfile}"
  config_file = File.expand_path('../.noexec.yaml', gemfile)
  if File.exist?(config_file)
    log "Using config file at #{config_file}"
    require "yaml"
    config = YAML::load_file(config_file)
    unless config['include'].nil? ^ config['exclude'].nil?
      raise "You cannot have both an include and exclude section in your #{config_file.inspect}"
    end
    if config['include'] && config['include'].include?(bin)
      log "Binary included by config"
      return true
    elsif config['exclude'] && config['exclude'].include?(bin)
      log "Binary excluded by config"
      return false
    end
    log "Config based matching didn't find it, resorting to Gemfile lookup"
  end
  runtime = Bundler.load
  log2(){ "runtime specs: #{runtime.specs.map{|g| "#{g.name}-#{g.version}"}*" "}" }
  if rubygems_spec # that single gem
    missing_spec = runtime.
      instance_variable_get(:@definition).
      missing_specs.
      detect{|spec| spec.name == rubygems_spec.name}
    if missing_spec
      puts "\e[31mCould not find proper version of #{missing_spec.to_s} in any of the sources\e[0m"
      puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
      exit Bundler::GemNotFound.new.status_code
    end
  end
  if runtime.specs.detect{ |spec| spec.executables.include?(bin) }
    return true
  end
  Bundler.unload!(rubygems_specs)
  false
rescue Bundler::BundlerError, Bundler::GemfileError => e
  warn "Ignoring candidate #{gemfile}:\n#{e}" if Noexec::DEBUG
  false
end
check() click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 108
def check
  if %w(bundle rubygems-bundler-uninstaller).include?(bin)
    log "Noexec - skipped binary: #{bin}"

  elsif ENV['NOEXEC_EXCLUDE'] && ENV['NOEXEC_EXCLUDE'].split(/ /).include?(bin)
    log "Noexec - ENV skipped binary: #{bin}"

  elsif ENV['BUNDLE_GEMFILE'] && ENV['BUNDLE_BIN_PATH'] && ENV['RUBYOPT']
    log "Noexec - already in 'bundle exec'"

  elsif %w(0 skip).include?( ENV['NOEXEC'] ) || ENV.key?('NOEXEC_DISABLE')
    #TODO: deprecated in 1.1.0, to be removed later -- 2012.09.05
    $stderr.puts "Warning, 'NOEXEC' environment variable is deprecated, switch to 'NOEXEC_DISABLE=1'." if ENV.key?('NOEXEC')
    log "Noexec - disabled with environment variable"

  else
    setup

  end
end
log(msg) click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 16
def log(msg)
  puts msg if Noexec::DEBUG
end
log2(msg=nil) { || ... } click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 20
def log2(msg=nil)
  if Noexec::DEBUG == "2"
    msg=yield if msg.nil? && block_given?
    puts msg
  end
end
old_specs() click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 69
def old_specs
  if Hash === rubygems_specs
  then @rubygems_specs.values
  else @rubygems_specs
  end
end
rubygems_spec() click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 76
def rubygems_spec
  @rubygems_spec ||= old_specs.detect{|spec| spec.executables.include?(bin) }
end
setup() click to toggle source
# File lib/rubygems-bundler/noexec.rb, line 80
def setup
  puts "Noexec - starting check" if Noexec::DEBUG
  require "bundler-unload"

  @rubygems_specs = Bundler.rubygems.plain_specs # save it for unloading and checking binary
  log2(){ "rubygems_specs: #{rubygems_specs.map{|g| "#{g.name}-#{g.version}"}*" "}" }

  @gemfile = ENV['BUNDLE_GEMFILE'] || File.join(Noexec::CURRENT, "Gemfile")
  initial_env_gemfile = ENV['BUNDLE_GEMFILE']

  while true
    ENV['BUNDLE_GEMFILE'] = gemfile
    if File.file?(gemfile) && candidate?
      log "Keeping #{gemfile} loaded"
      Bundler.setup
      return
    end
    new_gemfile = File.expand_path("../../Gemfile", gemfile)
    break if new_gemfile == gemfile
    @gemfile = new_gemfile
  end
  log "No valid Gemfile found, moving on"
  ENV['BUNDLE_GEMFILE'] = initial_env_gemfile
rescue LoadError
  warn "bundler not being used, unable to load" if Noexec::DEBUG
  ENV['BUNDLE_GEMFILE'] = initial_env_gemfile
end