Skip to content

Commit

Permalink
Added fix for lower pyproject low boundry issue for bump version (inc…
Browse files Browse the repository at this point in the history
…rease strategy).
  • Loading branch information
kbukum1 committed Jun 26, 2024
1 parent fed9c28 commit 24ed6c0
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 20 deletions.
9 changes: 7 additions & 2 deletions python/lib/dependabot/python/requirement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ class Requirement < Dependabot::Requirement
"===" => ->(v, r) { v.to_s == r.to_s }
)

# Override the lower bound logic for bump versions strategy.
BUMP_VERSIONS_OPS = OPS.merge(
">=" => ->(v, r) { v.to_s == r.to_s }
)

quoted = OPS.keys.sort_by(&:length).reverse
.map { |k| Regexp.quote(k) }.join("|")
version_pattern = Python::Version::VERSION_PATTERN
Expand Down Expand Up @@ -78,10 +83,10 @@ def initialize(*requirements)
super(requirements)
end

def satisfied_by?(version)
def satisfied_by?(version, ops = OPS)
version = Python::Version.new(version.to_s)

requirements.all? { |op, rv| (OPS[op] || OPS["="]).call(version, rv) }
requirements.all? { |op, rv| (ops[op] || ops["="]).call(version, rv) }
end

def exact?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,14 @@ def update_requirements_range(requirement_strings)
requirement_strings.map { |r| requirement_class.new(r) }

updated_requirement_strings = ruby_requirements.flat_map do |r|
next r.to_s if r.satisfied_by?(latest_resolvable_version)
next r.to_s if r.satisfied_by?(latest_resolvable_version, Requirement::BUMP_VERSIONS_OPS)

case op = r.requirements.first.first
when "<"
"<" + update_greatest_version(r.requirements.first.last, latest_resolvable_version)
when "<="
"<=" + latest_resolvable_version.to_s
when "!=", ">", ">="
"#{op}#{update_greatest_version(r.requirements.first.last, latest_resolvable_version)}"
when "<=", ">="
"#{op}#{latest_resolvable_version}"
when "!=", ">"
raise UnfixableRequirement
else
raise "Unexpected op for unsatisfied requirement: #{op}"
Expand Down
50 changes: 48 additions & 2 deletions python/spec/dependabot/python/requirement_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
its(:to_s) { is_expected.to eq(Gem::Requirement.new("~> 1.2.0").to_s) }
end

context "when dealing with one digits" do
context "when dealing with one digit" do
let(:requirement_string) { "~1" }

its(:to_s) { is_expected.to eq(Gem::Requirement.new("~> 1.0").to_s) }
Expand Down Expand Up @@ -185,7 +185,7 @@
it { is_expected.to eq([Gem::Requirement.new("1.2.1")]) }
end

context "with a illformed parentheses" do
context "with illformed parentheses" do
let(:requirement_string) { "(== 1.2).1" }

it "raises a helpful error" do
Expand Down Expand Up @@ -319,4 +319,50 @@
end
end
end

describe "#satisfied_by? with BUMP_VERSIONS_OPS" do
subject(:requirement_satisfied_by) { requirement.satisfied_by?(version, described_class::BUMP_VERSIONS_OPS) }

let(:requirement_string) { ">=1.0.0" }

context "with a Python::Version" do
let(:version) { version_class.new(version_string) }

context "when dealing with the exact version" do
let(:version_string) { "1.0.0" }

it { is_expected.to be(true) }
end

context "when dealing with a different version" do
let(:version_string) { "2.0.0" }

it { is_expected.to be(false) }
end

context "when dealing with the latest resolvable version" do
let(:version_string) { "1.0.0" }

it { is_expected.to be(true) }

context "when the requirement includes a local version" do
let(:requirement_string) { ">=1.0.0+gc.1" }

it { is_expected.to be(false) }
end

context "when the version includes a local version" do
let(:version_string) { "1.0.0+gc.1" }

it { is_expected.to be(false) }
end
end

context "when dealing with an out-of-range version" do
let(:version_string) { "0.9.0" }

it { is_expected.to be(false) }
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
context "when requirement version is too high" do
let(:requirement_txt_req_string) { ">=2.0.0" }

its([:requirement]) { is_expected.to eq(:unfixable) }
its([:requirement]) { is_expected.to eq(">=1.5.0") }
end

context "when requirement had a local version" do
Expand All @@ -146,13 +146,13 @@
context "when needing an update" do
let(:requirement_txt_req_string) { ">=1.3.0, <1.5" }

its([:requirement]) { is_expected.to eq(">=1.3.0,<1.6") }
its([:requirement]) { is_expected.to eq(">=1.5.0,<1.6") }

context "when requirement version has more digits than the new version" do
let(:requirement_txt_req_string) { "<=1.9.2,>=1.9" }
let(:latest_resolvable_version) { "1.10" }

its([:requirement]) { is_expected.to eq(">=1.9,<=1.10") }
its([:requirement]) { is_expected.to eq("<=1.10,>=1.10") }
end
end
end
Expand Down Expand Up @@ -268,7 +268,7 @@
context "when the requirement version is too high" do
let(:setup_py_req_string) { ">=2.0.0" }

its([:requirement]) { is_expected.to eq(:unfixable) }
its([:requirement]) { is_expected.to eq(">=1.5.0") }
end

context "with an upper bound" do
Expand All @@ -279,7 +279,7 @@
context "when needing an update" do
let(:setup_py_req_string) { ">=1.3.0, <1.5" }

its([:requirement]) { is_expected.to eq(">=1.3.0,<1.6") }
its([:requirement]) { is_expected.to eq(">=1.5.0,<1.6") }
end
end
end
Expand Down Expand Up @@ -370,7 +370,7 @@
context "when the requirement version is too high" do
let(:setup_cfg_req_string) { ">=2.0.0" }

its([:requirement]) { is_expected.to eq(:unfixable) }
its([:requirement]) { is_expected.to eq(">=1.5.0") }
end

context "with an upper bound" do
Expand All @@ -381,7 +381,7 @@
context "when needing an update" do
let(:setup_cfg_req_string) { ">=1.3.0, <1.5" }

its([:requirement]) { is_expected.to eq(">=1.3.0,<1.6") }
its([:requirement]) { is_expected.to eq(">=1.5.0,<1.6") }
end
end
end
Expand Down Expand Up @@ -504,7 +504,7 @@
context "when the requirement version is too high" do
let(:pyproject_req_string) { ">=2.0.0" }

its([:requirement]) { is_expected.to eq(:unfixable) }
its([:requirement]) { is_expected.to eq(">=1.5.0") }
end

context "when the requirement had a local version" do
Expand All @@ -521,7 +521,7 @@
context "when needing an update" do
let(:pyproject_req_string) { ">=1.3.0, <1.5" }

its([:requirement]) { is_expected.to eq(">=1.3.0,<1.6") }
its([:requirement]) { is_expected.to eq(">=1.5.0,<1.6") }
end
end
end
Expand Down Expand Up @@ -650,7 +650,7 @@
context "when the requirement is too high" do
let(:pyproject_req_string) { ">=2.0.0" }

its([:requirement]) { is_expected.to eq(:unfixable) }
its([:requirement]) { is_expected.to eq(">=1.5.0") }
end

context "with an upper bound" do
Expand All @@ -661,7 +661,7 @@
context "when needing an update" do
let(:pyproject_req_string) { ">=1.3.0, <1.5" }

its([:requirement]) { is_expected.to eq(">=1.3.0,<1.6") }
its([:requirement]) { is_expected.to eq(">=1.5.0,<1.6") }
end
end
end
Expand Down

0 comments on commit 24ed6c0

Please sign in to comment.