diff --git a/updater/lib/dependabot/job.rb b/updater/lib/dependabot/job.rb index 82b9d070a7a..935037b45ce 100644 --- a/updater/lib/dependabot/job.rb +++ b/updater/lib/dependabot/job.rb @@ -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 + 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 @@ -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 diff --git a/updater/lib/dependabot/updater.rb b/updater/lib/dependabot/updater.rb index 9fd1795a952..d8ff28a1092 100644 --- a/updater/lib/dependabot/updater.rb +++ b/updater/lib/dependabot/updater.rb @@ -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) @@ -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) @@ -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}" @@ -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 @@ -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 diff --git a/updater/lib/dependabot/updater/operations/group_update_all_versions.rb b/updater/lib/dependabot/updater/operations/group_update_all_versions.rb index db192c7ba29..6f94f924a01 100644 --- a/updater/lib/dependabot/updater/operations/group_update_all_versions.rb +++ b/updater/lib/dependabot/updater/operations/group_update_all_versions.rb @@ -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:) @@ -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) diff --git a/updater/lib/dependabot/updater/operations/refresh_version_update_pull_request.rb b/updater/lib/dependabot/updater/operations/refresh_version_update_pull_request.rb index 560b2cb0d16..beda55a4aaf 100644 --- a/updater/lib/dependabot/updater/operations/refresh_version_update_pull_request.rb +++ b/updater/lib/dependabot/updater/operations/refresh_version_update_pull_request.rb @@ -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:) @@ -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 @@ -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) @@ -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 diff --git a/updater/lib/dependabot/updater/operations/update_all_versions.rb b/updater/lib/dependabot/updater/operations/update_all_versions.rb index 8fb797b25e3..87248dd4d33 100644 --- a/updater/lib/dependabot/updater/operations/update_all_versions.rb +++ b/updater/lib/dependabot/updater/operations/update_all_versions.rb @@ -138,24 +138,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, raise_on_ignored:) @@ -164,8 +147,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 @@ -182,55 +165,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 - 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)