class SmarterBundler::Bundle
Constants
- KNOWN_SOLUTIONS_187_192
Note the versions listed in KNOWN_SOLUTIONS are the first NON working version for the first ruby version listed (eg 1.8.7, 1.9.3, 2.2.2)
- KNOWN_SOLUTIONS_193_221
- KNOWN_SOLUTIONS_222_22x
Public Instance Methods
call_bundle(bundle_args)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 89 def call_bundle(bundle_args) require_gems_check = if File.size? 'Rakefile' 'bundle exec rake environment' else "ruby -e 'puts \"Checking gems can be loaded ...\" ; " + "require \"rubygems\" ; "+ "require \"bundler/setup\" ; "+ "Bundler.require(:default) ; "+ "puts \"PASSED GEM LOAD TEST\" ' " end shell "bundle #{bundle_args.join(' ')} && #{require_gems_check}" end
fatal_error(result)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 106 def fatal_error(result) ruby_version_error(result) || syntax_error(result) end
install_failed_gem(gem, version)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 102 def install_failed_gem(gem, version) shell? "gem install '#{gem}' -v '#{version}'" end
known_solution(gem)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 118 def known_solution(gem) known_solutions[gem] end
known_solutions()
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 122 def known_solutions if RUBY_VERSION <= '1.9.2' KNOWN_SOLUTIONS_187_192 elsif RUBY_VERSION <= '2.2.1' KNOWN_SOLUTIONS_193_221 elsif RUBY_VERSION <= '2.3' KNOWN_SOLUTIONS_222_22x else { } end end
parse_output(result)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 134 def parse_output(result) result.output.each do |line| if line =~ /Make sure that `gem install (\S+) -v '(\S+)'`/ return [$1, $2] elsif line =~ %r{SyntaxError: .*/ruby/[^/]*/gems/([^/]*)-(\d[^/]+)/} return [$1, $2] elsif line =~ %r{/ruby/[^/]*/gems/([^/]*)-(\d[^/]+)/\S+:\d+: syntax error} return [$1, $2] end end nil end
ruby_version_error(result)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 110 def ruby_version_error(result) result.output.select { |l| l =~ /requires Ruby version/ }.any? end
rubygems_earlier_version(gem, version)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 147 def rubygems_earlier_version(gem, version) @rubygems_cache = {} @platforms ||= begin if RUBY_PLATFORM =~ /linux/ ['', 'ruby', 'mri'] else [RUBY_PLATFORM] end end @rubygems_cache[gem] ||= begin url = "https://rubygems.org/api/v1/versions/#{gem}.yaml" uri = URI.parse(url) req = Net::HTTP::Get.new(uri.request_uri) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = (uri.scheme == 'https') response = http.request(req) text = response.body list = YAML.load(text) # puts "Request returned list: #{list.inspect}" list = list.select { |h| @platforms.include?(h['platform'].to_s) && !h['prerelease'] }.map do |h| h.reject do |k, v| %w{authors built_at created_at description downloads_count metadata summary rubygems_version licenses requirements sha}.include? k end end # puts "Trimmed prerelease list: #{list.inspect}" list rescue RuntimeError => ex puts "Ignoring exception: #{ex} - we will have to work it out the slow way" [] end list = @rubygems_cache[gem] if list.size == 0 puts "Unable to find version info at rubygems for #{gem}" return nil end current = list.select { |h| h['number'] == version }.first if current.nil? puts "Unable to find current version info at rubygems for #{gem}, version #{version}" return nil end puts "Found record for current version: #{current.inspect}" current_ruby_version = current['ruby_version'] # puts "current ruby_version: #{current_ruby_version.inspect}" if current_ruby_version.nil? puts "Rubygems has nil ruby_version spec for #{gem} #{version} - unable to pick next version" return nil end found = false same_versions = list.select do |h| (h['ruby_version'] == current_ruby_version) && (h['number'] !~ /[a-z]/i) end next_version = same_versions.map { |h| h['number'] }.last puts "Selected next_version: #{next_version}" next_version # [ # {"authors":"Evan David Light", # "built_at":"2011-08-08T04:00:00.000Z", # "created_at":"2011-08-08T21:23:40.254Z", # "description":"Behaviour Driven Development derived from Cucumber but as an internal DSL with methods for reuse", # "downloads_count":3493, # "metadata":{}, # "number":"0.7.1", # "summary":"Test::Unit-based acceptance testing DSL", # "platform":"ruby", # "rubygems_version":"\u003e= 0", # "ruby_version":null, # "prerelease":false, # "licenses":null, # "requirements":null, # "sha":"777c3a7ed83e44198b0a624976ec99822eb6f4a44bf1513eafbc7c13997cd86c"}, end
run(bundle_args)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 36 def run(bundle_args) @aggressive = bundle_args.first == '--aggressive' if @aggressive bundle_args = bundle_args.drop(1) end puts 'Smarter Bundler will recursively install your gems and output the successful bundler output. This may take a while.' count = 0 gemfile = SmarterBundler::Gemfile.new previous_failure = [] result = nil if @aggressive known_solutions.each do |gem, version| if gemfile.mentions? gem gemfile.restrict_gem_version(gem, version) count += 1 end end puts "Made #{count} adjustments in Gemfile based on known solutions" if count > 0 end while count < 100 result = call_bundle(bundle_args) failed_gem_and_version = parse_output(result) if failed_gem_and_version if previous_failure == failed_gem_and_version puts 'Aborting: Stuck trying to install the same gem and version!' exit 1 end previous_failure = failed_gem_and_version gem, version = *failed_gem_and_version if gemfile.restrict_gem_version(gem, known_solution(gem)) gemfile.save count += 1 elsif !fatal_error(result) && install_failed_gem(gem, version) puts 'Retrying seems to have fixed the problem' elsif ruby_version_error(result) && gemfile.restrict_gem_version(gem, rubygems_earlier_version(gem, version)) gemfile.save count += 1 elsif fatal_error(result) && gemfile.restrict_gem_version(gem, version) gemfile.save count += 1 else puts 'Aborting: Unable to fix installation of gems' exit 2 end else break end end puts "#{count} adjustments where made to the Gemfile" exit result ? result.status.to_i : 3 end
syntax_error(result)
click to toggle source
# File lib/smarter_bundler/bundle.rb, line 114 def syntax_error(result) result.output.select { |l| l =~ /(: syntax error|SyntaxError: )/ }.any? end