Class: Noexec

Inherits:
Object
  • Object
show all
Defined in:
lib/rubygems-bundler/noexec.rb

Constant Summary collapse

DEBUG =
ENV.key?('NOEXEC_DEBUG')
CURRENT =
Dir.pwd

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bin) ⇒ Noexec

Returns a new instance of Noexec.



9
10
11
12
13
14
# 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

Instance Attribute Details

#binObject (readonly)

Returns the value of attribute bin.



7
8
9
# File 'lib/rubygems-bundler/noexec.rb', line 7

def bin
  @bin
end

Instance Method Details

#candidate?(gemfile) ⇒ Boolean

Returns:

  • (Boolean)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rubygems-bundler/noexec.rb', line 20

def candidate?(gemfile)
  config_file = File.expand_path('../.noexec.yaml', gemfile)
  log "Considering #{config_file.inspect}"
  if File.exist?(config_file)
    log "Using config file at #{config_file}"
    require "yaml"
    config = YAML::load_file(config_file)
    raise "You cannot have both an include and exclude section in your #{config_file.inspect}" unless config['include'].nil? ^ config['exclude'].nil?
    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
  return true if %w(ruby irb).include?(bin)
  ENV['BUNDLE_GEMFILE'] = gemfile
  Bundler.with_bundle do |runtime|
    if rubygems_spec
      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
    return true if runtime.specs.detect{ |spec| spec.executables.include?(bin) }
  end
  false
rescue Bundler::BundlerError, Bundler::GemfileError => e
  warn "Ignoring candidate #{gemfile}:\n#{e}" if Noexec::DEBUG
  false
end

#checkObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rubygems-bundler/noexec.rb', line 87

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) ⇒ Object



16
17
18
# File 'lib/rubygems-bundler/noexec.rb', line 16

def log(msg)
  puts msg if Noexec::DEBUG
end

#rubygems_specObject



59
60
61
# File 'lib/rubygems-bundler/noexec.rb', line 59

def rubygems_spec
  @rubygems_spec ||= Bundler.rubygems.plain_specs.detect{|spec| spec.executables.include?(bin) }
end

#setupObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/rubygems-bundler/noexec.rb', line 63

def setup
  puts "Noexec - starting check" if Noexec::DEBUG
  require "bundler-unload"

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