class LibyearBundler::Models::Ruby
Logic and information pertaining to the installed and newest Ruby
versions
Constants
- RUBY_VERSION_DATA_URL
Public Class Methods
We'll only consider non-prerelease versions when analyzing ruby version, which we also implcitly do for gem versions because that's bundler's default behavior
@return [Array<String>]
# File lib/libyear_bundler/models/ruby.rb, line 32 def all_stable_versions all_versions.reject do |version| ::Gem::Version.new(version).prerelease? end end
# File lib/libyear_bundler/models/ruby.rb, line 18 def initialize(lockfile, release_date_cache) unless release_date_cache.nil? || release_date_cache.is_a?(ReleaseDateCache) raise TypeError, 'Invalid release_date_cache' end @lockfile = lockfile @release_date_cache = release_date_cache end
# File lib/libyear_bundler/models/ruby.rb, line 38 def newest_version ::Gem::Version.new(all_stable_versions.first) end
# File lib/libyear_bundler/models/ruby.rb, line 42 def newest_version_release_date if @release_date_cache.nil? release_date(newest_version) else @release_date_cache[name, newest_version] end end
# File lib/libyear_bundler/models/ruby.rb, line 50 def newest_version_sequence_index all_stable_versions.find_index(newest_version.to_s) end
# File lib/libyear_bundler/models/ruby.rb, line 54 def release_date(version_obj) version = version_obj.to_s v = all_stable_versions.detect { |ver| ver == version } if v.nil? raise format('Cannot determine release date for ruby %s', version) end # YAML#safe_load provides an already-parsed Date object, so the following # is a Date object v['date'] end
Private Class Methods
The following URL is the only official, easily-parseable document with Ruby
version information that I'm aware of, but is not supported as such (github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173). It's been recommend that ruby-lang.org provide a supported document: github.com/ruby/www.ruby-lang.org/pull/1637#issuecomment-344934173 TODO: Use supported document with version information if it becomes available.
@return [Array<String>]
# File lib/libyear_bundler/models/ruby.rb, line 78 def all_versions @_all_versions ||= begin uri = ::URI.parse(RUBY_VERSION_DATA_URL) response = ::Net::HTTP.get_response(uri) # The Date object is passed through here due to a bug in # YAML#safe_load # https://github.com/ruby/psych/issues/262 ::YAML .safe_load(response.body, [Date]) .map { |release| release['version'] } end end
Public Instance Methods
# File lib/libyear_bundler/models/ruby.rb, line 92 def installed_version @_installed_version ||= begin version_from_bundler || version_from_ruby_version_file || version_from_ruby end end
# File lib/libyear_bundler/models/ruby.rb, line 100 def installed_version_release_date if @release_date_cache.nil? self.class.release_date(installed_version) else @release_date_cache[name, installed_version] end end
# File lib/libyear_bundler/models/ruby.rb, line 108 def libyears ::LibyearBundler::Calculators::Libyear.calculate( installed_version_release_date, self.class.newest_version_release_date ) end
# File lib/libyear_bundler/models/ruby.rb, line 115 def name 'ruby' end
Simply delegates to class method, but we still need it to conform to the interface expected by `Report#meta_line_summary`.
# File lib/libyear_bundler/models/ruby.rb, line 121 def newest_version self.class.newest_version end
Simply delegates to class method, but we still need it to conform to the interface expected by `Report#meta_line_summary`.
# File lib/libyear_bundler/models/ruby.rb, line 127 def newest_version_release_date self.class.newest_version_release_date end
# File lib/libyear_bundler/models/ruby.rb, line 131 def outdated? installed_version < newest_version end
# File lib/libyear_bundler/models/ruby.rb, line 135 def version_number_delta ::LibyearBundler::Calculators::VersionNumberDelta.calculate( installed_version, self.class.newest_version ) end
# File lib/libyear_bundler/models/ruby.rb, line 142 def version_sequence_delta ::LibyearBundler::Calculators::VersionSequenceDelta.calculate( installed_version_sequence_index, self.class.newest_version_sequence_index ) end
Private Instance Methods
# File lib/libyear_bundler/models/ruby.rb, line 151 def installed_version_sequence_index self.class.all_stable_versions.index(installed_version.to_s) end
# File lib/libyear_bundler/models/ruby.rb, line 155 def shell_out_to_ruby # ruby appends a 'p' followed by the patch level number # to the version number for stable releases, which returns # a false positive using `::Gem::Version#prerelease?`. # Understandably, because ruby is not a gem, but we'd like # to use `prerelease?`. # Pre-releases are appended with 'dev', and so adhere to # `::Gem::Version`'s definition of a pre-release. # Sources: # - https://github.com/ruby/ruby/blob/trunk/version.h#L37 # - https://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Version.html `ruby --version`.split[1].gsub(/p\d*/, '') end
# File lib/libyear_bundler/models/ruby.rb, line 169 def version_from_bundler return unless File.exist?(@lockfile) ruby_version_string = ::Bundler::LockfileParser .new(@lockfile) .ruby_version return if ruby_version_string.nil? ::Bundler::RubyVersion.from_string(ruby_version_string).gem_version end
# File lib/libyear_bundler/models/ruby.rb, line 186 def version_from_ruby ::Gem::Version.new(shell_out_to_ruby) end
TODO: this path should probably be relative to `@lockfile` instead TODO: of being relative to the current working directory.
# File lib/libyear_bundler/models/ruby.rb, line 181 def version_from_ruby_version_file return unless ::File.exist?('.ruby-version') ::Gem::Version.new(::File.read('.ruby-version').strip) end