Skip to content

Commit

Permalink
Raise Error for Unsupported Bundler Version (#10601)
Browse files Browse the repository at this point in the history
- Added unsupported version handling to the abstract package manager and implemented it for Bundler v1.

Co-authored-by: Landon Grindheim <landon.grindheim@gmail.com>
  • Loading branch information
kbukum1 and landongrindheim committed Sep 17, 2024
1 parent 95f169b commit 93e1827
Show file tree
Hide file tree
Showing 21 changed files with 272 additions and 279 deletions.
14 changes: 6 additions & 8 deletions bundler/lib/dependabot/bundler/package_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ module Dependabot
module Bundler
PACKAGE_MANAGER = "bundler"

SUPPORTED_BUNDLER_VERSIONS = T.let([
Version.new("2")
].freeze, T::Array[Dependabot::Version])
# Keep versions in ascending order
SUPPORTED_BUNDLER_VERSIONS = T.let([Version.new("2")].freeze, T::Array[Dependabot::Version])

DEPRECATED_BUNDLER_VERSIONS = T.let([
Version.new("1")
Expand Down Expand Up @@ -40,13 +39,12 @@ def initialize(version)
sig { override.returns(T::Array[Dependabot::Version]) }
attr_reader :supported_versions

sig { override.returns(T::Boolean) }
def deprecated?
deprecated_versions.include?(version)
end
sig { override.returns(T::Boolean) }
def unsupported?
!deprecated? && version < supported_versions.first
# Check if the feature flag for Bundler v1 unsupported error is enabled.
return false unless Dependabot::Experiments.enabled?(:bundler_v1_unsupported_error)

supported_versions.all? { |supported| supported > version }
end
end
end
Expand Down
78 changes: 54 additions & 24 deletions bundler/spec/dependabot/bundler/package_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,66 +50,96 @@
end
end

describe "SUPPORTED_BUNDLER_VERSIONS" do
it "is in ascending order" do
expect(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS)
.to eq(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS.sort)
end
end

describe "#deprecated?" do
context "when version is deprecated?" do
before do
allow(Dependabot::Experiments).to receive(:enabled?)
.with(:bundler_v1_unsupported_error)
.and_return(feature_flag_enabled)
end

context "when version is deprecated but not unsupported" do
let(:version) { "1" }
let(:feature_flag_enabled) { false }

it "returns true" do
expect(package_manager.deprecated?).to be true
end
end

context "when version is not deprecated" do
let(:version) { "2" }
context "when version is unsupported" do
let(:version) { "0.9" }
let(:feature_flag_enabled) { true }

it "returns false" do
it "returns false, as unsupported takes precedence" do
expect(package_manager.deprecated?).to be false
end
end
end

describe "#unsupported" do
context "when version is deprecated?" do
let(:version) { "1" }
describe "#unsupported?" do
before do
allow(Dependabot::Experiments).to receive(:enabled?)
.with(:bundler_v1_unsupported_error)
.and_return(feature_flag_enabled)
end

it "returns false" do
expect(package_manager.unsupported?).to be false
context "when feature flag is enabled and version is unsupported" do
let(:version) { "0.9" }
let(:feature_flag_enabled) { true }

it "returns true" do
expect(package_manager.unsupported?).to be true
end
end

context "when version is supported" do
context "when feature flag is enabled and version is supported" do
let(:version) { "2" }
let(:feature_flag_enabled) { true }

it "returns false" do
expect(package_manager.unsupported?).to be false
end
end

context "when version is unsupported?" do
context "when feature flag is disabled" do
let(:version) { "0.9" }
let(:feature_flag_enabled) { false }

it "returns true" do
expect(package_manager.unsupported?).to be true
it "returns false" do
expect(package_manager.unsupported?).to be false
end
end
end

describe "#supported_versions" do
context "when there are supported versions" do
let(:version) { "2" }
describe "#raise_if_unsupported!" do
before do
allow(Dependabot::Experiments).to receive(:enabled?)
.with(:bundler_v1_unsupported_error)
.and_return(feature_flag_enabled)
end

context "when feature flag is enabled and version is unsupported" do
let(:version) { "0.9" }
let(:feature_flag_enabled) { true }

it "returns the correct supported versions" do
expect(package_manager.supported_versions).to eq([Dependabot::Bundler::Version.new("2")])
it "raises a ToolVersionNotSupported error" do
expect { package_manager.raise_if_unsupported! }.to raise_error(Dependabot::ToolVersionNotSupported)
end
end
end

describe "#deprecated_versions" do
context "when there are deprecated versions" do
let(:version) { "2" }
context "when feature flag is disabled" do
let(:version) { "0.9" }
let(:feature_flag_enabled) { false }

it "returns the correct deprecated versions" do
expect(package_manager.deprecated_versions).to eq([Dependabot::Bundler::Version.new("1")])
it "does not raise an error" do
expect { package_manager.raise_if_unsupported! }.not_to raise_error
end
end
end
Expand Down
50 changes: 0 additions & 50 deletions common/lib/dependabot/notices.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,6 @@ def self.generate_supported_versions_description(supported_versions, support_lat
"Please upgrade to one of the following versions: #{versions_string}#{later_description}."
end

# Generates a support notice for the given package manager.
# @param package_manager [PackageManagerBase] The package manager object.
# @return [Notice, nil] The generated notice or nil if no notice is applicable.
sig do
params(
package_manager: PackageManagerBase
).returns(T.nilable(Notice))
end
def self.generate_support_notice(package_manager)
deprecation_notice = generate_pm_deprecation_notice(package_manager)

return deprecation_notice if deprecation_notice

generate_pm_unsupported_notice(package_manager)
end

# Generates a deprecation notice for the given package manager.
# @param package_manager [PackageManagerBase] The package manager object.
# @return [Notice, nil] The generated deprecation notice or nil if the package manager is not deprecated.
Expand Down Expand Up @@ -144,40 +128,6 @@ def self.generate_pm_deprecation_notice(package_manager)
)
end

# Generates an unsupported notice for the given package manager.
# @param package_manager [PackageManagerBase] The package manager object.
# @return [Notice, nil] The generated unsupported notice or nil if the package manager is not unsupported.
sig do
params(
package_manager: PackageManagerBase
).returns(T.nilable(Notice))
end
def self.generate_pm_unsupported_notice(package_manager)
return nil unless package_manager.unsupported?

mode = NoticeMode::ERROR
supported_versions_description = generate_supported_versions_description(
package_manager.supported_versions,
package_manager.support_later_versions?
)
notice_type = "#{package_manager.name}_unsupported_error"
title = "Package manager unsupported notice"
description = "Dependabot no longer supports `#{package_manager.name} v#{package_manager.version}`!"

## Add the supported versions to the description
description += "\n\n#{supported_versions_description}\n" unless supported_versions_description.empty?

Notice.new(
mode: mode,
type: notice_type,
package_manager_name: package_manager.name,
title: title,
description: description,
show_in_pr: true,
show_alert: true
)
end

sig { params(notice: Notice).returns(T.nilable(String)) }
def self.markdown_from_description(notice)
description = notice.description
Expand Down
22 changes: 18 additions & 4 deletions common/lib/dependabot/package_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ def supported_versions
# package_manager.deprecated? #=> true
sig { 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

Expand All @@ -64,12 +67,23 @@ def deprecated?
# package_manager.unsupported? #=> false
sig { returns(T::Boolean) }
def unsupported?
return true if unsupported_versions.include?(version)
false
end

supported_versions = self.supported_versions
return version < supported_versions.first if supported_versions.any?
# Raises an error if the current package manager version is unsupported.
# If the version is unsupported, it raises a ToolVersionNotSupported error.
sig { void }
def raise_if_unsupported!
return unless unsupported?

false
# Example: v2.*, v3.*
supported_versions_message = supported_versions.map { |v| "v#{v}.*" }.join(", ")

raise ToolVersionNotSupported.new(
name,
version.to_s,
supported_versions_message
)
end

# Indicates if the package manager supports later versions beyond those listed in supported_versions.
Expand Down
Loading

0 comments on commit 93e1827

Please sign in to comment.