class Dependabot::UpdateCheckers::Base

Attributes

credentials[R]
dependency[R]
dependency_files[R]
ignored_versions[R]
options[R]
raise_on_ignored[R]
repo_contents_path[R]
requirements_update_strategy[R]
security_advisories[R]

Public Class Methods

new(dependency:, dependency_files:, repo_contents_path: nil, credentials:, ignored_versions: [], raise_on_ignored: false, security_advisories: [], requirements_update_strategy: nil, options: {}) click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 15
def initialize(dependency:, dependency_files:, repo_contents_path: nil,
               credentials:, ignored_versions: [],
               raise_on_ignored: false, security_advisories: [],
               requirements_update_strategy: nil,
               options: {})
  @dependency = dependency
  @dependency_files = dependency_files
  @repo_contents_path = repo_contents_path
  @credentials = credentials
  @requirements_update_strategy = requirements_update_strategy
  @ignored_versions = ignored_versions
  @raise_on_ignored = raise_on_ignored
  @security_advisories = security_advisories
  @options = options
end

Public Instance Methods

can_update?(requirements_to_unlock:) click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 39
def can_update?(requirements_to_unlock:)
  # Can't update if all versions are being ignored
  return false if ignore_requirements.include?(requirement_class.new(">= 0"))

  if dependency.version
    version_can_update?(requirements_to_unlock: requirements_to_unlock)
  else
    # TODO: Handle full unlock updates for dependencies without a lockfile
    return false if requirements_to_unlock == :none

    requirements_can_update?
  end
end
conflicting_dependencies() click to toggle source

Finds any dependencies in the lockfile that have a subdependency on the given dependency that do not satisfy the target_version. @return [Array<Hash{String => String}]

name [String] the blocking dependencies name
version [String] the version of the blocking dependency
requirement [String] the requirement on the target_dependency
# File lib/dependabot/update_checkers/base.rb, line 103
def conflicting_dependencies
  [] # return an empty array for ecosystems that don't support this yet
end
ignore_requirements() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 144
def ignore_requirements
  ignored_versions.flat_map { |req| requirement_class.requirements_array(req) }
end
latest_resolvable_previous_version(_updated_version) click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 107
def latest_resolvable_previous_version(_updated_version)
  dependency.version
end
latest_resolvable_version() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 79
def latest_resolvable_version
  raise NotImplementedError
end
latest_resolvable_version_with_no_unlock() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 93
def latest_resolvable_version_with_no_unlock
  raise NotImplementedError
end
latest_version() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 64
def latest_version
  raise NotImplementedError
end
lowest_resolvable_security_fix_version() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 89
def lowest_resolvable_security_fix_version
  raise NotImplementedError
end
lowest_security_fix_version() click to toggle source

Lowest available security fix version not checking resolvability @return [Dependabot::<package manager>::Version, to_s] version class

# File lib/dependabot/update_checkers/base.rb, line 85
def lowest_security_fix_version
  raise NotImplementedError
end
preferred_resolvable_version() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 68
def preferred_resolvable_version
  # If this dependency is vulnerable, prefer trying to update to the
  # lowest_resolvable_security_fix_version. Otherwise update all the way
  # to the latest_resolvable_version.
  return lowest_resolvable_security_fix_version if vulnerable?

  latest_resolvable_version
rescue NotImplementedError
  latest_resolvable_version
end
requirement_class() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 119
def requirement_class
  Utils.requirement_class_for_package_manager(dependency.package_manager)
end
requirements_unlocked_or_can_be?() click to toggle source

For some langauges, the manifest file may be constructed such that Dependabot has no way to update it (e.g., if it fetches its versions from a web API). This method is overridden in those cases.

# File lib/dependabot/update_checkers/base.rb, line 126
def requirements_unlocked_or_can_be?
  true
end
up_to_date?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 31
def up_to_date?
  if dependency.version
    version_up_to_date?
  else
    requirements_up_to_date?
  end
end
updated_dependencies(requirements_to_unlock:) click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 53
def updated_dependencies(requirements_to_unlock:)
  return [] unless can_update?(requirements_to_unlock: requirements_to_unlock)

  case requirements_to_unlock&.to_sym
  when :none then [updated_dependency_without_unlock]
  when :own then [updated_dependency_with_own_req_unlock]
  when :all then updated_dependencies_after_full_unlock
  else raise "Unknown unlock level '#{requirements_to_unlock}'"
  end
end
updated_requirements() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 111
def updated_requirements
  raise NotImplementedError
end
version_class() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 115
def version_class
  Utils.version_class_for_package_manager(dependency.package_manager)
end
vulnerable?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 130
def vulnerable?
  return false if security_advisories.none?

  # Can't (currently) detect whether dependencies without a version
  # (i.e., for repos without a lockfile) are vulnerable
  return false unless dependency.version

  # Can't (currently) detect whether git dependencies are vulnerable
  return false if existing_version_is_sha?

  version = version_class.new(dependency.version)
  security_advisories.any? { |a| a.vulnerable?(version) }
end

Private Instance Methods

can_compare_requirements?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 278
def can_compare_requirements?
  version_from_requirements &&
    latest_version &&
    version_class.correct?(latest_version.to_s)
end
changed_requirements() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 284
def changed_requirements
  (updated_requirements - dependency.requirements)
end
existing_version_is_sha?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 204
def existing_version_is_sha?
  return false if version_class.correct?(dependency.version)

  dependency.version.match?(/^[0-9a-f]{6,}$/)
end
latest_version_resolvable_with_full_unlock?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 150
def latest_version_resolvable_with_full_unlock?
  raise NotImplementedError
end
numeric_version_can_update?(requirements_to_unlock:) click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 241
def numeric_version_can_update?(requirements_to_unlock:)
  return false if numeric_version_up_to_date?

  case requirements_to_unlock&.to_sym
  when :none
    new_version = latest_resolvable_version_with_no_unlock
    new_version && new_version > version_class.new(dependency.version)
  when :own
    preferred_version_resolvable_with_unlock?
  when :all
    latest_version_resolvable_with_full_unlock?
  else raise "Unknown unlock level '#{requirements_to_unlock}'"
  end
end
numeric_version_up_to_date?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 230
def numeric_version_up_to_date?
  return false unless latest_version

  # If a lockfile isn't out of date and the package has switched to a git
  # source then we'll get a numeric version switching to a git SHA. In
  # this case we treat the version as up-to-date so that it's ignored.
  return true if latest_version.to_s.match?(/^[0-9a-f]{40}$/)

  latest_version <= version_class.new(dependency.version)
end
preferred_version_resolvable_with_unlock?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 256
def preferred_version_resolvable_with_unlock?
  new_version = preferred_resolvable_version
  return false unless new_version

  if existing_version_is_sha?
    return false if new_version.to_s.start_with?(dependency.version)
  elsif new_version <= version_class.new(dependency.version)
    return false
  end

  updated_requirements.none? { |r| r[:requirement] == :unfixable }
end
requirements_can_update?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 298
def requirements_can_update?
  return false if changed_requirements.none?

  changed_requirements.none? { |r| r[:requirement] == :unfixable }
end
requirements_up_to_date?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 269
def requirements_up_to_date?
  if can_compare_requirements?
    return (version_from_requirements >=
            version_class.new(latest_version.to_s))
  end

  changed_requirements.none?
end
sha1_version_can_update?(requirements_to_unlock:) click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 214
def sha1_version_can_update?(requirements_to_unlock:)
  return false if sha1_version_up_to_date?

  # All we can do with SHA-1 hashes is check for presence and equality
  case requirements_to_unlock&.to_sym
  when :none
    new_version = latest_resolvable_version_with_no_unlock
    new_version && !new_version.to_s.start_with?(dependency.version)
  when :own
    preferred_version_resolvable_with_unlock?
  when :all
    latest_version_resolvable_with_full_unlock?
  else raise "Unknown unlock level '#{requirements_to_unlock}'"
  end
end
sha1_version_up_to_date?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 210
def sha1_version_up_to_date?
  latest_version&.to_s&.start_with?(dependency.version)
end
updated_dependencies_after_full_unlock() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 182
def updated_dependencies_after_full_unlock
  raise NotImplementedError
end
updated_dependency_with_own_req_unlock() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 168
def updated_dependency_with_own_req_unlock
  version = preferred_resolvable_version.to_s
  previous_version = latest_resolvable_previous_version(version)&.to_s

  Dependency.new(
    name: dependency.name,
    version: version,
    requirements: updated_requirements,
    previous_version: previous_version,
    previous_requirements: dependency.requirements,
    package_manager: dependency.package_manager
  )
end
updated_dependency_without_unlock() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 154
def updated_dependency_without_unlock
  version = latest_resolvable_version_with_no_unlock.to_s
  previous_version = latest_resolvable_previous_version(version)&.to_s

  Dependency.new(
    name: dependency.name,
    version: version,
    requirements: dependency.requirements,
    previous_version: previous_version,
    previous_requirements: dependency.requirements,
    package_manager: dependency.package_manager
  )
end
version_can_update?(requirements_to_unlock:) click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 192
def version_can_update?(requirements_to_unlock:)
  if existing_version_is_sha?
    return sha1_version_can_update?(
      requirements_to_unlock: requirements_to_unlock
    )
  end

  numeric_version_can_update?(
    requirements_to_unlock: requirements_to_unlock
  )
end
version_from_requirements() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 288
def version_from_requirements
  @version_from_requirements ||=
    dependency.requirements.map { |r| r.fetch(:requirement) }.compact.
    flat_map { |req_str| requirement_class.requirements_array(req_str) }.
    flat_map(&:requirements).
    reject { |req_array| req_array.first.start_with?("<") }.
    map(&:last).
    max
end
version_up_to_date?() click to toggle source
# File lib/dependabot/update_checkers/base.rb, line 186
def version_up_to_date?
  return sha1_version_up_to_date? if existing_version_is_sha?

  numeric_version_up_to_date?
end