class Dependabot::GitCommitChecker
Constants
- VERSION_REGEX
Attributes
credentials[R]
dependency[R]
ignored_versions[R]
Public Class Methods
new(dependency:, credentials:, ignored_versions: [], raise_on_ignored: false, requirement_class: nil, version_class: nil)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 24 def initialize(dependency:, credentials:, ignored_versions: [], raise_on_ignored: false, requirement_class: nil, version_class: nil) @dependency = dependency @credentials = credentials @ignored_versions = ignored_versions @raise_on_ignored = raise_on_ignored @requirement_class = requirement_class @version_class = version_class end
Public Instance Methods
branch_or_ref_in_release?(version)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 71 def branch_or_ref_in_release?(version) pinned_ref_in_release?(version) || branch_behind_release?(version) end
current_version()
click to toggle source
rubocop:enable Metrics/AbcSize rubocop:enable Metrics/PerceivedComplexity
# File lib/dependabot/git_commit_checker.rb, line 122 def current_version return unless dependency.version && version_tag?(dependency.version) version = dependency.version.match(VERSION_REGEX).named_captures.fetch("version") version_class.new(version) end
filter_lower_versions(tags)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 129 def filter_lower_versions(tags) return tags unless current_version versions = tags.map do |t| version = t.name.match(VERSION_REGEX).named_captures.fetch("version") version_class.new(version) end versions.select do |version| version > current_version end end
git_dependency?()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 35 def git_dependency? return false if dependency_source_details.nil? dependency_source_details.fetch(:type) == "git" end
git_repo_reachable?()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 153 def git_repo_reachable? local_upload_pack true rescue Dependabot::GitDependenciesNotReachable false end
head_commit_for_current_branch()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 75 def head_commit_for_current_branch ref = ref_or_branch || "HEAD" if pinned? return dependency.version || local_repo_git_metadata_fetcher.head_commit_for_ref(ref) end sha = local_repo_git_metadata_fetcher.head_commit_for_ref(ref) return sha if sha raise Dependabot::GitDependencyReferenceNotFound, dependency.name end
local_tag_for_latest_version()
click to toggle source
rubocop:disable Metrics/PerceivedComplexity rubocop:disable Metrics/AbcSize
# File lib/dependabot/git_commit_checker.rb, line 91 def local_tag_for_latest_version tags = local_tags. select { |t| version_tag?(t.name) && matches_existing_prefix?(t.name) } filtered = tags. reject { |t| tag_included_in_ignore_requirements?(t) } if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(tags).any? raise Dependabot::AllVersionsIgnored end tag = filtered. reject { |t| tag_is_prerelease?(t) && !wants_prerelease? }. max_by do |t| version = t.name.match(VERSION_REGEX).named_captures. fetch("version") version_class.new(version) end return unless tag version = tag.name.match(VERSION_REGEX).named_captures.fetch("version") { tag: tag.name, version: version_class.new(version), commit_sha: tag.commit_sha, tag_sha: tag.tag_sha } end
local_tag_for_pinned_version()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 142 def local_tag_for_pinned_version return unless pinned? ref = dependency_source_details.fetch(:ref) tags = local_tags.select { |t| t.commit_sha == ref && version_class.correct?(t.name) }. sort_by { |t| version_class.new(t.name) } return if tags.empty? tags[-1].name end
pinned?()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 41 def pinned? raise "Not a git dependency!" unless git_dependency? ref = dependency_source_details.fetch(:ref) branch = dependency_source_details.fetch(:branch) return false if ref.nil? return false if branch == ref return true if branch return true if dependency.version&.start_with?(ref) # Check the specified `ref` isn't actually a branch !local_upload_pack.match?("refs/heads/#{ref}") end
pinned_ref_looks_like_commit_sha?()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 62 def pinned_ref_looks_like_commit_sha? ref = dependency_source_details.fetch(:ref) return false unless ref&.match?(/^[0-9a-f]{6,40}$/) return false unless pinned? local_repo_git_metadata_fetcher.head_commit_for_ref(ref).nil? end
pinned_ref_looks_like_version?()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 56 def pinned_ref_looks_like_version? return false unless pinned? dependency_source_details.fetch(:ref).match?(VERSION_REGEX) end
Private Instance Methods
bitbucket_commit_comparison_status(ref1, ref2)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 251 def bitbucket_commit_comparison_status(ref1, ref2) url = "https://api.bitbucket.org/2.0/repositories/"\ "#{listing_source_repo}/commits/?"\ "include=#{ref2}&exclude=#{ref1}" client = Clients::BitbucketWithRetries. for_bitbucket_dot_org(credentials: credentials) response = client.get(url) # Conservatively assume that ref2 is ahead in the equality case, of # if we get an unexpected format (e.g., due to a 404) if JSON.parse(response.body).fetch("values", ["x"]).none? then "behind" else "ahead" end end
branch_behind_release?(version)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 180 def branch_behind_release?(version) raise "Not a git dependency!" unless git_dependency? return false if ref_or_branch.nil? return false if listing_source_url.nil? tag = listing_tag_for_version(version.to_s) return false unless tag # Check if behind, excluding the case where it's identical, because # we normally wouldn't switch you from tracking master to a release. commit_included_in_tag?( commit: ref_or_branch, tag: tag, allow_identical: false ) end
commit_included_in_tag?(tag:, commit:, allow_identical: false)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 214 def commit_included_in_tag?(tag:, commit:, allow_identical: false) status = case Source.from_url(listing_source_url)&.provider when "github" then github_commit_comparison_status(tag, commit) when "gitlab" then gitlab_commit_comparison_status(tag, commit) when "bitbucket" then bitbucket_commit_comparison_status(tag, commit) else raise "Unknown source" end return true if status == "behind" allow_identical && status == "identical" rescue Octokit::NotFound, Gitlab::Error::NotFound, Clients::Bitbucket::NotFound, Octokit::InternalServerError false end
dependency_source_details()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 268 def dependency_source_details sources = dependency.requirements. map { |requirement| requirement.fetch(:source) }.uniq.compact. select { |source| source[:type] == "git" } return sources.first if sources.count <= 1 # If there are multiple source types, or multiple source URLs, then it's # unclear how we should proceed if sources.map { |s| [s.fetch(:type), s.fetch(:url, nil)] }.uniq.count > 1 raise "Multiple sources! #{sources.join(', ')}" end # Otherwise it's reasonable to take the first source and use that. This # will happen if we have multiple git sources with difference references # specified. In that case it's fine to update them all. sources.first end
github_commit_comparison_status(ref1, ref2)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 232 def github_commit_comparison_status(ref1, ref2) client = Clients::GithubWithRetries. for_github_dot_com(credentials: credentials) client.compare(listing_source_repo, ref1, ref2).status end
gitlab_commit_comparison_status(ref1, ref2)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 239 def gitlab_commit_comparison_status(ref1, ref2) client = Clients::GitlabWithRetries. for_gitlab_dot_com(credentials: credentials) comparison = client.compare(listing_source_repo, ref1, ref2) if comparison.commits.none? then "behind" elsif comparison.compare_same_ref then "identical" else "ahead" end end
ignore_requirements()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 357 def ignore_requirements ignored_versions.flat_map { |req| requirement_class.requirements_array(req) } end
listing_repo_git_metadata_fetcher()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 400 def listing_repo_git_metadata_fetcher @listing_repo_git_metadata_fetcher ||= GitMetadataFetcher.new( url: listing_source_url, credentials: credentials ) end
listing_source_repo()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 323 def listing_source_repo return unless listing_source_url Source.from_url(listing_source_url)&.repo end
listing_source_url()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 304 def listing_source_url @listing_source_url ||= begin # Remove the git source, so the metadata finder looks on the # registry candidate_dep = Dependency.new( name: dependency.name, version: dependency.version, requirements: [], package_manager: dependency.package_manager ) MetadataFinders. for_package_manager(dependency.package_manager). new(dependency: candidate_dep, credentials: credentials). source_url end end
listing_tag_for_version(version)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 329 def listing_tag_for_version(version) listing_tags. find { |t| t.name =~ /(?:[^0-9\.]|\A)#{Regexp.escape(version)}\z/ }&. name end
listing_upload_pack()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 351 def listing_upload_pack return unless listing_source_url listing_repo_git_metadata_fetcher.upload_pack end
local_repo_git_metadata_fetcher()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 392 def local_repo_git_metadata_fetcher @local_repo_git_metadata_fetcher ||= GitMetadataFetcher.new( url: dependency_source_details.fetch(:url), credentials: credentials ) end
local_upload_pack()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 198 def local_upload_pack local_repo_git_metadata_fetcher.upload_pack end
matches_existing_prefix?(tag)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 297 def matches_existing_prefix?(tag) return true unless ref_or_branch&.match?(VERSION_REGEX) ref_or_branch.gsub(VERSION_REGEX, "").gsub(/v$/i, "") == tag.gsub(VERSION_REGEX, "").gsub(/v$/i, "") end
pinned_ref_in_release?(version)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 164 def pinned_ref_in_release?(version) raise "Not a git dependency!" unless git_dependency? return false unless pinned? return false if listing_source_url.nil? tag = listing_tag_for_version(version.to_s) return false unless tag commit_included_in_tag?( commit: dependency_source_details.fetch(:ref), tag: tag, allow_identical: true ) end
ref_or_branch()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 288 def ref_or_branch dependency_source_details.fetch(:ref) || dependency_source_details.fetch(:branch) end
requirement_class()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 386 def requirement_class return @requirement_class if @requirement_class Utils.requirement_class_for_package_manager(dependency.package_manager) end
tag_included_in_ignore_requirements?(tag)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 370 def tag_included_in_ignore_requirements?(tag) version = tag.name.match(VERSION_REGEX).named_captures.fetch("version") ignore_requirements.any? { |r| r.satisfied_by?(version_class.new(version)) } end
tag_is_prerelease?(tag)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 375 def tag_is_prerelease?(tag) version = tag.name.match(VERSION_REGEX).named_captures.fetch("version") version_class.new(version).prerelease? end
version_class()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 380 def version_class return @version_class if @version_class Utils.version_class_for_package_manager(dependency.package_manager) end
version_tag?(tag)
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 293 def version_tag?(tag) tag.match?(VERSION_REGEX) end
wants_prerelease?()
click to toggle source
# File lib/dependabot/git_commit_checker.rb, line 361 def wants_prerelease? return false unless dependency_source_details&.fetch(:ref, nil) return false unless pinned_ref_looks_like_version? version = dependency_source_details.fetch(:ref).match(VERSION_REGEX). named_captures.fetch("version") version_class.new(version).prerelease? end