diff --git a/updater/lib/dependabot/dependency_snapshot.rb b/updater/lib/dependabot/dependency_snapshot.rb index 30f3a0b7..b9c2c853 100644 --- a/updater/lib/dependabot/dependency_snapshot.rb +++ b/updater/lib/dependabot/dependency_snapshot.rb @@ -242,8 +242,9 @@ def dependency_file_parser options: job.experiments ) # Add 'package_manager' to the depedency_snapshopt to use it in operations' - package_manager_for_current_directory = parser.package_manager - @package_manager[@current_directory] = package_manager_for_current_directory + package_manager = parser.package_manager + + @package_manager[@current_directory] = package_manager # Log deprecation notices if the package manager is deprecated # and add them to the notices array @@ -252,7 +253,7 @@ def dependency_file_parser # add deprecation notices for the package manager add_deprecation_notice( notices: notices_for_current_directory, - package_manager: package_manager_for_current_directory + package_manager: package_manager ) @notices[@current_directory] = notices_for_current_directory diff --git a/updater/lib/dependabot/updater/group_update_creation.rb b/updater/lib/dependabot/updater/group_update_creation.rb index abf23f64..9494698c 100644 --- a/updater/lib/dependabot/updater/group_update_creation.rb +++ b/updater/lib/dependabot/updater/group_update_creation.rb @@ -241,6 +241,9 @@ def compile_updates_for(dependency, dependency_files, group) # rubocop:disable M return [] end + # Raise an error if the package manager version is unsupported + dependency_snapshot.package_manager&.raise_if_unsupported! + checker.updated_dependencies( requirements_to_unlock: requirements_to_unlock ) diff --git a/updater/lib/dependabot/updater/operations/create_security_update_pull_request.rb b/updater/lib/dependabot/updater/operations/create_security_update_pull_request.rb index 156a48f3..d10754aa 100644 --- a/updater/lib/dependabot/updater/operations/create_security_update_pull_request.rb +++ b/updater/lib/dependabot/updater/operations/create_security_update_pull_request.rb @@ -105,6 +105,7 @@ def check_and_create_pr_with_error_handling(dependency) # rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/PerceivedComplexity # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/CyclomaticComplexity sig { params(dependency: Dependabot::Dependency).void } def check_and_create_pull_request(dependency) dependency = vulnerable_version(dependency) if dependency.metadata[:all_versions] @@ -145,6 +146,9 @@ def check_and_create_pull_request(dependency) log_requirements_for_update(requirements_to_unlock, checker) return record_security_update_not_possible_error(checker) if requirements_to_unlock == :update_not_possible + # Raise an error if the package manager version is unsupported + dependency_snapshot.package_manager&.raise_if_unsupported! + updated_deps = checker.updated_dependencies( requirements_to_unlock: requirements_to_unlock ) @@ -198,6 +202,7 @@ def check_and_create_pull_request(dependency) # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/PerceivedComplexity + # rubocop:enable Metrics/CyclomaticComplexity sig { params(dependency: Dependabot::Dependency).returns(Dependabot::Dependency) } def vulnerable_version(dependency) return dependency if dependency.metadata[:all_versions].count == 1 diff --git a/updater/lib/dependabot/updater/operations/refresh_security_update_pull_request.rb b/updater/lib/dependabot/updater/operations/refresh_security_update_pull_request.rb index a70b4662..6202dc7a 100644 --- a/updater/lib/dependabot/updater/operations/refresh_security_update_pull_request.rb +++ b/updater/lib/dependabot/updater/operations/refresh_security_update_pull_request.rb @@ -54,6 +54,9 @@ def perform Dependabot.logger.info("Starting update job for #{job.source.repo}") Dependabot.logger.info("Checking and updating security pull requests...") + # Raise an error if the package manager version is unsupported + dependency_snapshot.package_manager&.raise_if_unsupported! + # Retrieve the list of initial notices from dependency snapshot @notices = dependency_snapshot.notices # More notices can be added during the update process 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 aafa2b2e..4919c758 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 @@ -138,6 +138,9 @@ def check_and_update_pull_request(dependencies) return close_pull_request(reason: :update_no_longer_possible) end + # Raise an error if the package manager version is unsupported + dependency_snapshot.package_manager&.raise_if_unsupported! + updated_deps = checker.updated_dependencies( requirements_to_unlock: requirements_to_unlock ) diff --git a/updater/lib/dependabot/updater/operations/update_all_versions.rb b/updater/lib/dependabot/updater/operations/update_all_versions.rb index bdcc9a20..40e63264 100644 --- a/updater/lib/dependabot/updater/operations/update_all_versions.rb +++ b/updater/lib/dependabot/updater/operations/update_all_versions.rb @@ -172,6 +172,9 @@ def check_and_create_pull_request(dependency) notices: @notices ) + # Raise an error if the package manager version is unsupported + dependency_snapshot.package_manager&.raise_if_unsupported! + if dependency_change.updated_dependency_files.empty? raise "UpdateChecker found viable dependencies to be updated, but FileUpdater failed to update any files" end diff --git a/updater/spec/support/dummy_pkg_helpers.rb b/updater/spec/support/dummy_pkg_helpers.rb index de4b572f..2f207f5f 100644 --- a/updater/spec/support/dummy_pkg_helpers.rb +++ b/updater/spec/support/dummy_pkg_helpers.rb @@ -1,6 +1,7 @@ # typed: false # frozen_string_literal: true +require "dependabot/package_manager" require "dependabot/dependency_file" # This module provides some shortcuts for working with our two mock RubyGems packages: @@ -61,4 +62,37 @@ def create_temporary_content_directory(fixture:, directory: "/", state: "origina def updated_bundler_files_hash(fixture: "bundler") updated_bundler_files(fixture: fixture).map(&:to_h) end + + # Stub PackageManagerBase + class StubPackageManager < Dependabot::PackageManagerBase + def initialize(name:, version:, deprecated_versions: [], unsupported_versions: [], supported_versions: []) + @name = name + @version = version + @deprecated_versions = deprecated_versions + @unsupported_versions = unsupported_versions + @supported_versions = supported_versions + end + + attr_reader :name + attr_reader :version + attr_reader :deprecated_versions + attr_reader :unsupported_versions + attr_reader :supported_versions + + sig { override.returns(T::Boolean) } + def deprecated? + # If the version is unsupported, the unsupported error is getting raised separately. + return false if unsupported? + + deprecated_versions.include?(version) + end + + sig { override.returns(T::Boolean) } + def unsupported? + # Check if the feature flag for Bundler v1 unsupported error is enabled. + return false unless name == "bundler" && Dependabot::Experiments.enabled?(:bundler_v1_unsupported_error) + + version < supported_versions.first + end + end end