class LibyearBundler::Models::Ruby

Logic and information pertaining to the installed and newest Ruby versions

Constants

RUBY_VERSION_DATA_URL

Public Class Methods

all_stable_versions() click to toggle source

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
new(lockfile, release_date_cache) click to toggle source
# 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
newest_version() click to toggle source
# File lib/libyear_bundler/models/ruby.rb, line 38
def newest_version
  ::Gem::Version.new(all_stable_versions.first)
end
newest_version_release_date() click to toggle source
# 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
newest_version_sequence_index() click to toggle source
# File lib/libyear_bundler/models/ruby.rb, line 50
def newest_version_sequence_index
  all_stable_versions.find_index(newest_version.to_s)
end
release_date(version_obj) click to toggle source
# 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

all_versions() click to toggle source

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

installed_version() click to toggle source
# 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
installed_version_release_date() click to toggle source
# 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
libyears() click to toggle source
# 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
name() click to toggle source
# File lib/libyear_bundler/models/ruby.rb, line 115
def name
  'ruby'
end
newest_version() click to toggle source

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
newest_version_release_date() click to toggle source

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
outdated?() click to toggle source
# File lib/libyear_bundler/models/ruby.rb, line 131
def outdated?
  installed_version < newest_version
end
version_number_delta() click to toggle source
# File lib/libyear_bundler/models/ruby.rb, line 135
def version_number_delta
  ::LibyearBundler::Calculators::VersionNumberDelta.calculate(
    installed_version,
    self.class.newest_version
  )
end
version_sequence_delta() click to toggle source
# 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

installed_version_sequence_index() click to toggle source
# 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
shell_out_to_ruby() click to toggle source
# 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
version_from_bundler() click to toggle source
# 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
version_from_ruby() click to toggle source
# File lib/libyear_bundler/models/ruby.rb, line 186
def version_from_ruby
  ::Gem::Version.new(shell_out_to_ruby)
end
version_from_ruby_version_file() click to toggle source

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