diff --git a/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb b/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb index 8e9c8ca10a6..5cb05e05a82 100644 --- a/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb +++ b/bundler/lib/dependabot/bundler/file_updater/requirement_replacer.rb @@ -167,6 +167,8 @@ def space_after_specifier?(requirement_nodes) req_string.include?(" ") end + EQUALITY_OPERATOR = /(?!])=/.freeze + def use_equality_operator?(requirement_nodes) return true if requirement_nodes.none? @@ -178,7 +180,7 @@ def use_equality_operator?(requirement_nodes) requirement_nodes.first.children.first.loc.expression.source end - req_string.match?(/(?!])=/) + req_string.match?(EQUALITY_OPERATOR) end def new_requirement_string(quote_characters:, @@ -203,7 +205,7 @@ def serialized_req(req, use_equality_operator) # Gem::Requirement serializes exact matches as a string starting # with `=`. We may need to remove that equality operator if it # wasn't used originally. - tmp_req = tmp_req.gsub(/(?!])=/, "") unless use_equality_operator + tmp_req = tmp_req.gsub(EQUALITY_OPERATOR, "") unless use_equality_operator tmp_req.strip end diff --git a/bundler/spec/dependabot/bundler/update_checker/requirements_updater_spec.rb b/bundler/spec/dependabot/bundler/update_checker/requirements_updater_spec.rb index d0ca3660cae..31599d1df3e 100644 --- a/bundler/spec/dependabot/bundler/update_checker/requirements_updater_spec.rb +++ b/bundler/spec/dependabot/bundler/update_checker/requirements_updater_spec.rb @@ -324,17 +324,25 @@ context "and one is a != requirement" do context "that is binding" do - let(:gemspec_requirement_string) { "~> 1.4, != 1.8.0" } + let(:gemspec_requirement_string) { "~> 1.4, != #{latest_version}" } its([:requirement]) { is_expected.to eq("~> 1.4") } end context "that is not binding" do - let(:gemspec_requirement_string) { "~> 1.4.0, != 1.5.0" } + let(:gemspec_requirement_string) { "~> 1.4, != #{latest_resolvable_version}" } its([:requirement]) do - is_expected.to eq(">= 1.4, != 1.5.0, < 1.9") + is_expected.to eq("~> 1.4, != #{latest_resolvable_version}") end end end + + context "when latest version is denied" do + let(:latest_version) { "2.0.4" } + let(:latest_resolvable_version) { "2.0.3" } + let(:gemspec_requirement_string) { ">= 2.0.0, != 2.0.4" } + + its([:requirement]) { is_expected.to eq(">= 2.0.0, != 2.0.4") } + end end context "when a beta version was used in the old requirement" do @@ -400,6 +408,20 @@ context "when there are multiple requirements" do let(:gemspec_requirement_string) { "> 1.0.0, <= 1.4.0" } its([:requirement]) { is_expected.to eq("> 1.0.0, <= 1.9.0") } + + context "and one is a != requirement" do + context "that is binding" do + let(:gemspec_requirement_string) { "~> 1.4, != #{latest_resolvable_version}" } + its([:requirement]) { is_expected.to eq("~> 1.4") } + end + + context "that is not binding" do + let(:gemspec_requirement_string) { "~> 1.4, != #{latest_version}" } + its([:requirement]) do + is_expected.to eq("~> 1.4, != #{latest_version}") + end + end + end end context "when a beta version was used in the old requirement" do