module Gem::BUNDLED_GEMS

Constants

ARCHDIR
DLEXT
EXACT
LIBDIR
LIBEXT
PREFIXED
SINCE
WARNED

Public Class Methods

build_message(gem) click to toggle source
# File bundled_gems.rb, line 94
def self.build_message(gem)
  msg = " which #{RUBY_VERSION < SINCE[gem] ? "will no longer be" : "is not"} part of the default gems since Ruby #{SINCE[gem]}."

  if defined?(Bundler)
    msg += " Add #{gem} to your Gemfile or gemspec."
    # We detect the gem name from caller_locations. We need to skip 2 frames like:
    # lib/ruby/3.3.0+0/bundled_gems.rb:90:in `warning?'",
    # lib/ruby/3.3.0+0/bundler/rubygems_integration.rb:247:in `block (2 levels) in replace_require'",
    location = caller_locations(3,3)[0]&.path
    if File.file?(location) && !location.start_with?(Gem::BUNDLED_GEMS::LIBDIR)
      caller_gem = nil
      Gem.path.each do |path|
        if location =~ %r{#{path}/gems/([\w\-\.]+)}
          caller_gem = $1
          break
        end
      end
      if caller_gem
        msg += " Also contact author of #{caller_gem} to add #{gem} into its gemspec."
      end
    end
  else
    msg += " Install #{gem} from RubyGems."
  end

  msg
end
find_gem(path) click to toggle source
# File bundled_gems.rb, line 59
def self.find_gem(path)
  if !path
    return
  elsif path.start_with?(ARCHDIR)
    n = path.delete_prefix(ARCHDIR).sub(DLEXT, "")
  elsif path.start_with?(LIBDIR)
    n = path.delete_prefix(LIBDIR).chomp(".rb")
  else
    return
  end
  EXACT[n] or PREFIXED[n = n[%r[\A[^/]+(?=/)]]] && n
end
warning?(name, specs: nil) click to toggle source
# File bundled_gems.rb, line 72
def self.warning?(name, specs: nil)
  name = File.path(name) # name can be a feature name or a file path with String or Pathname
  return if specs.to_a.map(&:name).include?(name.sub(LIBEXT, ""))
  name = name.tr("/", "-")
  _t, path = $:.resolve_feature_path(name)
  return unless gem = find_gem(path)
  caller = caller_locations(3, 3).find {|c| c&.absolute_path}
  return if find_gem(caller&.absolute_path)
  name = name.sub(LIBEXT, "") # assume "foo.rb"/"foo.so" belongs to "foo" gem
  return if WARNED[name]
  WARNED[name] = true
  if gem == true
    gem = name
  elsif gem
    return if WARNED[gem]
    WARNED[gem] = true
    "#{name} is found in #{gem}"
  else
    return
  end + build_message(gem)
end