Skip to content

Commit

Permalink
Merge pull request #8983 from bryan-bar/max-version
Browse files Browse the repository at this point in the history
fix(terraform): update `less-than`/`less-than/equals` version constraints
  • Loading branch information
randhircs authored Dec 16, 2024
2 parents 3f1e9f8 + f682f15 commit 44b2066
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 13 deletions.
21 changes: 12 additions & 9 deletions terraform/lib/dependabot/terraform/requirements_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,20 @@ def update_greatest_version(requirement, version_to_be_permitted)
op, version = requirement.requirements.first
version = version.release if version.prerelease?

index_to_update =
version.segments.map.with_index { |seg, i| seg.zero? ? 0 : i }.max

new_segments = version.segments.map.with_index do |_, index|
if index < index_to_update
# When 'less than'/'<',
# increment the last available segment only so that the new version is within the constraint
if op == "<"
new_segments = version.segments.map.with_index do |_, index|
version_to_be_permitted.segments[index]
elsif index == index_to_update
version_to_be_permitted.segments[index].to_i + 1
else
0
end
new_segments[-1] += 1
# When 'less-than/equal'/'<=', use the new version as-is even when previously set as a non-semver version
# Terraform treats shortened versions the same as a version with any remaining segments as 0
# Example: '0.2' is treated as '0.2.0' | '1' is treated as '1.0.0'
elsif op == "<="
new_segments = version_to_be_permitted.segments
else
raise "Unexpected operation: #{op}"
end

requirement_class.new("#{op} #{new_segments.join('.')}")
Expand Down
71 changes: 67 additions & 4 deletions terraform/spec/dependabot/terraform/requirements_updater_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,82 @@
end
end

context "when a =>,< requirement was previously specified" do
context "when <= requirement was previously specified" do
context "when it is satisfied" do
let(:requirement) { "<= 0.3.7" }

it { is_expected.to eq(requirements.first) }
end

context "when it is not satisfied" do
let(:requirement) { "<= 0.1.9" }

its([:requirement]) { is_expected.to eq("<= 0.3.7") }

context "when specifying two version segments" do
let(:requirement) { "<= 0.3" }
let(:latest_version) { version_class.new("2.8.5") }

its([:requirement]) { is_expected.to eq("<= 2.8.5") }
end

context "when specifying three version segments" do
let(:requirement) { "<= 0.3.7" }
let(:latest_version) { version_class.new("2.8.5") }

its([:requirement]) { is_expected.to eq("<= 2.8.5") }
end

context "when minor and patch updated" do
let(:requirement) { "<= 0.3.7" }
let(:latest_version) { version_class.new("0.4.0") }

its([:requirement]) { is_expected.to eq("<= 0.4.0") }
end

context "when major, minor and patch updated" do
let(:requirement) { "<= 0.3.7" }
let(:latest_version) { version_class.new("1.4.0") }

its([:requirement]) { is_expected.to eq("<= 1.4.0") }
end
end
end

context "when a =>,<,<= requirement was previously specified" do
context "when satisfied" do
let(:requirement) { ">= 0.2.1, < 0.4.0" }
let(:latest_version) { "0.3.7" }

its([:requirement]) { is_expected.to eq(">= 0.2.1, < 0.4.0") }
end

context "when not satisfied" do
let(:requirement) { ">= 0.2.1, < 0.3.0" }
context "when not satisfied, 0 patch version" do
let(:requirement) { ">= 0.2.1, < 0.3.0, <= 0.3.0" }
let(:latest_version) { "0.3.7" }

its([:requirement]) { is_expected.to eq(">= 0.2.1, < 0.4.0") }
its([:requirement]) { is_expected.to eq(">= 0.2.1, < 0.3.8, <= 0.3.7") }
end

context "when not satisfied, non-0 patch version" do
let(:requirement) { ">= 0.2.1, < 0.3.2, <= 0.3.2" }
let(:latest_version) { "0.3.7" }

its([:requirement]) { is_expected.to eq(">= 0.2.1, < 0.3.8, <= 0.3.7") }
end

context "when not satisfied, major and minor only" do
let(:requirement) { ">= 0.2.1, < 0.3, <= 0.3" }
let(:latest_version) { "0.3.7" }

its([:requirement]) { is_expected.to eq(">= 0.2.1, < 0.4, <= 0.3.7") }
end

context "when not satisfied, major and minor only" do
let(:requirement) { ">= 0.2.1, < 0.3, <= 0.3" }
let(:latest_version) { "1.4.0" }

its([:requirement]) { is_expected.to eq(">= 0.2.1, < 1.5, <= 1.4.0") }
end
end
end
Expand Down

0 comments on commit 44b2066

Please sign in to comment.