class RuboCop::Lockfile

Encapsulation of a lockfile for use when checking for gems. Does not actually resolve gems, just parses the lockfile. @api private

Public Class Methods

new(lockfile_path = nil) click to toggle source

@param [String, Pathname, nil] lockfile_path

# File lib/rubocop/lockfile.rb, line 17
def initialize(lockfile_path = nil)
  lockfile_path ||= begin
    ::Bundler.default_lockfile if use_bundler_lock_parser?
  rescue ::Bundler::GemfileNotFound
    nil # We might not be a folder with a Gemfile, but that's okay.
  end

  @lockfile_path = lockfile_path
end

Public Instance Methods

dependencies() click to toggle source

Gems that the bundle directly depends on. @return [Array<Bundler::Dependency>, nil]

# File lib/rubocop/lockfile.rb, line 29
def dependencies
  return [] unless parser

  parser.dependencies.values
end
gem_versions(include_transitive_dependencies: true) click to toggle source

Returns the locked versions of gems from this lockfile. @param [Boolean] include_transitive_dependencies: When false, only direct dependencies

are returned, i.e. those listed explicitly in the `Gemfile`.

@returns [Hash{String => Gem::Version}] The locked gem versions, keyed by the gems’ names.

# File lib/rubocop/lockfile.rb, line 49
def gem_versions(include_transitive_dependencies: true)
  return {} unless parser

  all_gem_versions = parser.specs.to_h { |spec| [spec.name, spec.version] }

  if include_transitive_dependencies
    all_gem_versions
  else
    direct_dep_names = parser.dependencies.keys
    all_gem_versions.slice(*direct_dep_names)
  end
end
gems() click to toggle source

All activated gems, including transitive dependencies. @return [Array<Bundler::Dependency>, nil]

# File lib/rubocop/lockfile.rb, line 37
def gems
  return [] unless parser

  # `Bundler::LockfileParser` returns `Bundler::LazySpecification` objects
  # which are not resolved, so extract the dependencies from them
  parser.dependencies.values.concat(parser.specs.flat_map(&:dependencies))
end
includes_gem?(name) click to toggle source

Whether this lockfile includes the named gem, directly or indirectly. @param [String] name @return [Boolean]

# File lib/rubocop/lockfile.rb, line 65
def includes_gem?(name)
  gems.any? { |gem| gem.name == name }
end

Private Instance Methods

parser() click to toggle source

@return [Bundler::LockfileParser, nil]

# File lib/rubocop/lockfile.rb, line 72
def parser
  return @parser if defined?(@parser)

  @parser = if @lockfile_path && File.exist?(@lockfile_path) && use_bundler_lock_parser?
              begin
                lockfile = ::Bundler.read_file(@lockfile_path)
                ::Bundler::LockfileParser.new(lockfile) if lockfile
              rescue ::Bundler::BundlerError
                nil
              end
            end
end
use_bundler_lock_parser?() click to toggle source
# File lib/rubocop/lockfile.rb, line 85
def use_bundler_lock_parser?
  return false unless Object.const_defined?(:Bundler)

  Bundler.const_defined?(:LockfileParser) && Bundler::VERSION >= '2.0'
end