Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 70 additions & 17 deletions updater/lib/dependabot/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,60 @@ def commit_message_options
self.class.standardise_keys(@commit_message_options).compact
end

def security_advisories_for(dependency)
relevant_advisories =
security_advisories.
select { |adv| adv.fetch("dependency-name").casecmp(dependency.name).zero? }

relevant_advisories.map do |adv|
vulnerable_versions = adv["affected-versions"] || []
safe_versions = (adv["patched-versions"] || []) +
(adv["unaffected-versions"] || [])

Dependabot::SecurityAdvisory.new(
dependency_name: dependency.name,
package_manager: package_manager,
vulnerable_versions: vulnerable_versions,
safe_versions: safe_versions
)
end
end

def ignore_conditions_for(dependency)
update_config.ignored_versions_for(
dependency,
security_updates_only: security_updates_only?
)
end

# TODO: Present Dependabot::Config::IgnoreCondition in calling code
#
# This is a workaround for our existing logging using the 'raw'
# ignore conditions passed into the job definition rather than
# the objects returned by `ignore_conditions_for`.
#
# The blocker on adopting Dependabot::Config::IgnoreCondition is
# that it does not have a 'source' attribute which we currently
# use to distinguish rules from the config file from those that
# were created via "@dependabot ignore version" commands
Comment on lines +243 to +250
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the context here 😄

def log_ignore_conditions_for(dependency)
conditions = ignore_conditions.select { |ic| name_match?(ic["dependency-name"], dependency.name) }
return if conditions.empty?

Dependabot.logger.info("Ignored versions:")
conditions.each do |ic|
unless ic["version-requirement"].nil?
Dependabot.logger.info(" #{ic['version-requirement']} - from #{ic['source']}")
end

ic["update-types"]&.each do |update_type|
msg = " #{update_type} - from #{ic['source']}"
msg += " (doesn't apply to security update)" if security_updates_only?
Dependabot.logger.info(msg)
end
end
end

private

def register_experiments
Expand All @@ -233,23 +287,22 @@ def build_source(source_details)
)
end

def security_advisories_for(dep)
relevant_advisories =
security_advisories.
select { |adv| adv.fetch("dependency-name").casecmp(dep.name).zero? }

relevant_advisories.map do |adv|
vulnerable_versions = adv["affected-versions"] || []
safe_versions = (adv["patched-versions"] || []) +
(adv["unaffected-versions"] || [])

Dependabot::SecurityAdvisory.new(
dependency_name: dep.name,
package_manager: package_manager,
vulnerable_versions: vulnerable_versions,
safe_versions: safe_versions
)
end
# Provides a Dependabot::Config::UpdateConfig objected hydrated with
# relevant information obtained from the job definition.
#
# At present we only use this for ignore rules.
def update_config
return @update_config if defined? @update_config

@update_config ||= Dependabot::Config::UpdateConfig.new(
ignore_conditions: ignore_conditions.map do |ic|
Dependabot::Config::IgnoreCondition.new(
dependency_name: ic["dependency-name"],
versions: [ic["version-requirement"]].compact,
update_types: ic["update-types"]
)
end
)
end
end
end
70 changes: 4 additions & 66 deletions updater/lib/dependabot/updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def check_and_create_pull_request(dependency)
# rubocop:enable Metrics/PerceivedComplexity

def raise_on_ignored?(dependency)
job.security_updates_only? || ignore_conditions_for(dependency).any?
job.security_updates_only? || job.ignore_conditions_for(dependency).any?
end

def record_security_update_not_needed_error(checker)
Expand Down Expand Up @@ -505,7 +505,7 @@ def log_checking_for_update(dependency)
Dependabot.logger.info(
"Checking if #{dependency.name} #{dependency.version} needs updating"
)
log_ignore_conditions(dependency)
job.log_ignore_conditions_for(dependency)
end

def all_versions_ignored?(dependency, checker)
Expand All @@ -520,25 +520,6 @@ def all_versions_ignored?(dependency, checker)
true
end

def log_ignore_conditions(dep)
conditions = job.ignore_conditions.
select { |ic| name_match?(ic["dependency-name"], dep.name) }
return if conditions.empty?

Dependabot.logger.info("Ignored versions:")
conditions.each do |ic|
unless ic["version-requirement"].nil?
Dependabot.logger.info(" #{ic['version-requirement']} - from #{ic['source']}")
end

ic["update-types"]&.each do |update_type|
msg = " #{update_type} - from #{ic['source']}"
msg += " (doesn't apply to security update)" if job.security_updates_only?
Dependabot.logger.info(msg)
end
end
end

def log_up_to_date(dependency)
Dependabot.logger.info(
"No update needed for #{dependency.name} #{dependency.version}"
Expand Down Expand Up @@ -610,8 +591,8 @@ def update_checker_for(dependency, raise_on_ignored:)
dependency_files: dependency_snapshot.dependency_files,
repo_contents_path: job.repo_contents_path,
credentials: job.credentials,
ignored_versions: ignore_conditions_for(dependency),
security_advisories: security_advisories_for(dependency),
ignored_versions: job.ignore_conditions_for(dependency),
security_advisories: job.security_advisories_for(dependency),
raise_on_ignored: raise_on_ignored,
requirements_update_strategy: job.requirements_update_strategy,
options: job.experiments
Expand All @@ -628,49 +609,6 @@ def file_updater_for(dependencies)
)
end

def ignore_conditions_for(dep)
update_config_ignored_versions(job.ignore_conditions, dep)
end

def update_config_ignored_versions(ignore_conditions, dep)
ignore_conditions = ignore_conditions.map do |ic|
Dependabot::Config::IgnoreCondition.new(
dependency_name: ic["dependency-name"],
versions: [ic["version-requirement"]].compact,
update_types: ic["update-types"]
)
end
Dependabot::Config::UpdateConfig.
new(ignore_conditions: ignore_conditions).
ignored_versions_for(dep, security_updates_only: job.security_updates_only?)
end

def name_match?(name1, name2)
WildcardMatcher.match?(
job.name_normaliser.call(name1),
job.name_normaliser.call(name2)
)
end

def security_advisories_for(dep)
relevant_advisories =
job.security_advisories.
select { |adv| adv.fetch("dependency-name").casecmp(dep.name).zero? }

relevant_advisories.map do |adv|
vulnerable_versions = adv["affected-versions"] || []
safe_versions = (adv["patched-versions"] || []) +
(adv["unaffected-versions"] || [])

Dependabot::SecurityAdvisory.new(
dependency_name: dep.name,
package_manager: job.package_manager,
vulnerable_versions: vulnerable_versions,
safe_versions: safe_versions
)
end
end

def generate_dependency_files_for(updated_dependencies)
if updated_dependencies.count == 1
updated_dependency = updated_dependencies.first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,24 +185,7 @@ def log_up_to_date(dependency)
end

def raise_on_ignored?(dependency)
ignore_conditions_for(dependency).any?
end

def ignore_conditions_for(dep)
update_config_ignored_versions(job.ignore_conditions, dep)
end

def update_config_ignored_versions(ignore_conditions, dep)
ignore_conditions = ignore_conditions.map do |ic|
Dependabot::Config::IgnoreCondition.new(
dependency_name: ic["dependency-name"],
versions: [ic["version-requirement"]].compact,
update_types: ic["update-types"]
)
end
Dependabot::Config::UpdateConfig.
new(ignore_conditions: ignore_conditions).
ignored_versions_for(dep, security_updates_only: false)
job.ignore_conditions_for(dependency).any?
end

def update_checker_for(dependency, dependency_files, raise_on_ignored:)
Expand Down Expand Up @@ -234,32 +217,7 @@ def log_checking_for_update(dependency)
"Checking if #{dependency.name} #{dependency.version} needs updating"
)
# FIXME: Grouped updates do not honour ignore rules for now
# log_ignore_conditions(dependency)
end

def log_ignore_conditions(dep)
conditions = job.ignore_conditions.
select { |ic| name_match?(ic["dependency-name"], dep.name) }
return if conditions.empty?

Dependabot.logger.info("Ignored versions:")
conditions.each do |ic|
unless ic["version-requirement"].nil?
Dependabot.logger.info(" #{ic['version-requirement']} - from #{ic['source']}")
end

ic["update-types"]&.each do |update_type|
msg = " #{update_type} - from #{ic['source']}"
Dependabot.logger.info(msg)
end
end
end

def name_match?(name1, name2)
WildcardMatcher.match?(
job.name_normaliser.call(name1),
job.name_normaliser.call(name2)
)
# job.log_ignore_conditions_for(dependency)
end

def all_versions_ignored?(dependency, checker)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,24 +148,7 @@ def close_pull_request(reason:)
end

def raise_on_ignored?(dependency)
ignore_conditions_for(dependency).any?
end

def ignore_conditions_for(dep)
update_config_ignored_versions(job.ignore_conditions, dep)
end

def update_config_ignored_versions(ignore_conditions, dep)
ignore_conditions = ignore_conditions.map do |ic|
Dependabot::Config::IgnoreCondition.new(
dependency_name: ic["dependency-name"],
versions: [ic["version-requirement"]].compact,
update_types: ic["update-types"]
)
end
Dependabot::Config::UpdateConfig.
new(ignore_conditions: ignore_conditions).
ignored_versions_for(dep, security_updates_only: false)
job.ignore_conditions_for(dependency).any?
end

def update_checker_for(dependency, raise_on_ignored:)
Expand All @@ -174,8 +157,8 @@ def update_checker_for(dependency, raise_on_ignored:)
dependency_files: dependency_snapshot.dependency_files,
repo_contents_path: job.repo_contents_path,
credentials: job.credentials,
ignored_versions: ignore_conditions_for(dependency),
security_advisories: security_advisories_for(dependency),
ignored_versions: job.ignore_conditions_for(dependency),
security_advisories: job.security_advisories_for(dependency),
raise_on_ignored: raise_on_ignored,
requirements_update_strategy: job.requirements_update_strategy,
options: job.experiments
Expand All @@ -192,48 +175,11 @@ def file_updater_for(dependencies)
)
end

def security_advisories_for(dep)
relevant_advisories =
job.security_advisories.
select { |adv| adv.fetch("dependency-name").casecmp(dep.name).zero? }

relevant_advisories.map do |adv|
vulnerable_versions = adv["affected-versions"] || []
safe_versions = (adv["patched-versions"] || []) +
(adv["unaffected-versions"] || [])

Dependabot::SecurityAdvisory.new(
dependency_name: dep.name,
package_manager: job.package_manager,
vulnerable_versions: vulnerable_versions,
safe_versions: safe_versions
)
end
end

def log_checking_for_update(dependency)
Dependabot.logger.info(
"Checking if #{dependency.name} #{dependency.version} needs updating"
)
log_ignore_conditions(dependency)
end

def log_ignore_conditions(dep)
conditions = job.ignore_conditions.
select { |ic| name_match?(ic["dependency-name"], dep.name) }
return if conditions.empty?

Dependabot.logger.info("Ignored versions:")
conditions.each do |ic|
unless ic["version-requirement"].nil?
Dependabot.logger.info(" #{ic['version-requirement']} - from #{ic['source']}")
end

ic["update-types"]&.each do |update_type|
msg = " #{update_type} - from #{ic['source']}"
Dependabot.logger.info(msg)
end
end
job.log_ignore_conditions_for(dependency)
end

def all_versions_ignored?(dependency, checker)
Expand All @@ -244,13 +190,6 @@ def all_versions_ignored?(dependency, checker)
true
end

def name_match?(name1, name2)
WildcardMatcher.match?(
job.name_normaliser.call(name1),
job.name_normaliser.call(name2)
)
end

def requirements_to_unlock(checker)
if job.lockfile_only? || !checker.requirements_unlocked_or_can_be?
if checker.can_update?(requirements_to_unlock: :none) then :none
Expand Down
Loading