Skip to content

Commit

Permalink
Strict type Dependabot::Terraform::RequirementsUpdater (#10641)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieMagee authored Sep 20, 2024
1 parent 9974bc4 commit 85827d2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
45 changes: 40 additions & 5 deletions terraform/lib/dependabot/terraform/requirements_updater.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# typed: true
# typed: strict
# frozen_string_literal: true

####################################################################
# For more details on Terraform version constraints, see: #
# https://www.terraform.io/docs/modules/usage.html#module-versions #
####################################################################

require "sorbet-runtime"

require "dependabot/terraform/version"
require "dependabot/terraform/requirement"

Expand Down Expand Up @@ -46,27 +48,35 @@ module Terraform
# }
# }
class RequirementsUpdater
extend T::Sig

# @param requirements [Hash{Symbol => String, Array, Hash}]
# @param latest_version [Dependabot::Terraform::Version]
# @param tag_for_latest_version [String, NilClass]
sig do
params(
requirements: T::Array[T::Hash[Symbol, T.untyped]],
latest_version: T.nilable(Dependabot::Version::VersionParameter),
tag_for_latest_version: T.nilable(String)
).void
end
def initialize(requirements:, latest_version:, tag_for_latest_version:)
@requirements = requirements
@tag_for_latest_version = tag_for_latest_version

return unless latest_version
return unless version_class.correct?(latest_version)

@latest_version = version_class.new(latest_version)
@latest_version = T.let(version_class.new(latest_version), Dependabot::Terraform::Version)
end

# @return requirements [Hash{Symbol => String, Array, Hash}]
# * requirement [String, NilClass] the updated version constraint
# * groups [Array] no-op for terraform
# * file [String] the file that specified this dependency
# * source [Hash{Symbol => String}] The updated git or registry source details
sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
def updated_requirements
return requirements unless latest_version

# NOTE: Order is important here. The FileUpdater needs the updated
# requirement at index `i` to correspond to the previous requirement
# at the same index.
Expand All @@ -81,17 +91,24 @@ def updated_requirements

private

sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
attr_reader :requirements

sig { returns(Dependabot::Terraform::Version) }
attr_reader :latest_version

sig { returns(T.nilable(String)) }
attr_reader :tag_for_latest_version

sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
def update_git_requirement(req)
return req unless req.dig(:source, :ref)
return req unless tag_for_latest_version

req.merge(source: req[:source].merge(ref: tag_for_latest_version))
end

sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
def update_registry_requirement(req)
return req if req.fetch(:requirement).nil?

Expand All @@ -111,13 +128,15 @@ def update_registry_requirement(req)
end

# Updates the version in a "~>" constraint to allow the given version
sig { params(req_string: String).returns(String) }
def update_twiddle_version(req_string)
old_version = requirement_class.new(req_string)
.requirements.first.last
updated_version = at_same_precision(latest_version, old_version)
req_string.sub(old_version.to_s, updated_version)
end

sig { params(req_string: String).returns(T::Array[Dependabot::Terraform::Requirement]) }
def update_range(req_string)
requirement_class.new(req_string).requirements.flat_map do |r|
ruby_req = requirement_class.new(r.join(" "))
Expand All @@ -131,6 +150,13 @@ def update_range(req_string)
end
end

sig do
params(
new_version: Dependabot::Terraform::Version,
old_version: Dependabot::Terraform::Version
)
.returns(String)
end
def at_same_precision(new_version, old_version)
release_precision =
old_version.to_s.split(".").count { |i| i.match?(/^\d+$/) }
Expand All @@ -149,6 +175,13 @@ def at_same_precision(new_version, old_version)

# Updates the version in a "<" or "<=" constraint to allow the given
# version
sig do
params(
requirement: Dependabot::Requirement,
version_to_be_permitted: T.any(String, Dependabot::Terraform::Version)
)
.returns(Dependabot::Terraform::Requirement)
end
def update_greatest_version(requirement, version_to_be_permitted)
if version_to_be_permitted.is_a?(String)
version_to_be_permitted =
Expand All @@ -164,7 +197,7 @@ def update_greatest_version(requirement, version_to_be_permitted)
if index < index_to_update
version_to_be_permitted.segments[index]
elsif index == index_to_update
version_to_be_permitted.segments[index] + 1
version_to_be_permitted.segments[index].to_i + 1
else
0
end
Expand All @@ -173,10 +206,12 @@ def update_greatest_version(requirement, version_to_be_permitted)
requirement_class.new("#{op} #{new_segments.join('.')}")
end

sig { returns(T.class_of(Dependabot::Terraform::Version)) }
def version_class
Version
end

sig { returns(T.class_of(Dependabot::Terraform::Requirement)) }
def requirement_class
Requirement
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@

specify { expect(updater.updated_requirements.count).to eq(1) }

context "when there is no latest version" do
let(:latest_version) { nil }

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

context "when there is a latest version" do
let(:latest_version) { version_class.new("0.3.7") }

Expand Down

0 comments on commit 85827d2

Please sign in to comment.