diff --git a/terraform/lib/dependabot/terraform/file_parser.rb b/terraform/lib/dependabot/terraform/file_parser.rb index 764f73231c7..c13cab8c710 100644 --- a/terraform/lib/dependabot/terraform/file_parser.rb +++ b/terraform/lib/dependabot/terraform/file_parser.rb @@ -269,7 +269,7 @@ def git_source_details_from(source_string) if git_url.include?("git@") T.must(git_url.split("git@").last).sub(":", "/") else - git_url.sub(%r{.*?://}, "") + git_url.sub(%r{(?:\w{3,5})?://}, "") end querystr = URI.parse("https://" + bare_uri).query @@ -308,7 +308,7 @@ def source_type(source_string) path_uri = URI.parse(T.must(source_string.split(%r{(?] # @raise [Dependabot::DependabotError] when the versions cannot be retrieved + sig { params(identifier: String).returns(T::Array[Dependabot::Terraform::Version]) } def all_provider_versions(identifier:) base_url = service_url_for("providers.v1") response = http_get!(URI.join(base_url, "#{identifier}/versions")) @@ -76,6 +88,7 @@ def all_provider_versions(identifier:) # "hashicorp/consul/aws" # @return [Array] # @raise [Dependabot::DependabotError] when the versions cannot be retrieved + sig { params(identifier: String).returns(T::Array[Dependabot::Terraform::Version]) } def all_module_versions(identifier:) base_url = service_url_for("modules.v1") response = http_get!(URI.join(base_url, "#{identifier}/versions")) @@ -93,8 +106,9 @@ def all_module_versions(identifier:) # @param dependency [Dependabot::Dependency] the dependency who's source # we're attempting to find # @return [nil, Dependabot::Source] + sig { params(dependency: Dependabot::Dependency).returns(T.nilable(Dependabot::Source)) } def source(dependency:) - type = dependency.requirements.first[:source][:type] + type = T.must(dependency.requirements.first)[:source][:type] base_url = service_url_for(service_key_for(type)) case type # https://www.terraform.io/internals/module-registry-protocol#download-source-code-for-a-specific-module-version @@ -126,6 +140,7 @@ def source(dependency:) # @param service_key [String] the service type described in https://www.terraform.io/docs/internals/remote-service-discovery.html#supported-services # @param return String # @raise [Dependabot::PrivateSourceAuthenticationFailure] when the service is not available + sig { params(service_key: String).returns(String) } def service_url_for(service_key) url_for(services.fetch(service_key)) rescue KeyError @@ -134,26 +149,35 @@ def service_url_for(service_key) private + sig { returns(String) } attr_reader :hostname + + sig { returns(T::Hash[String, String]) } attr_reader :tokens + sig { returns(T.class_of(Dependabot::Terraform::Version)) } def version_class Version end + sig { params(hostname: String).returns(T::Hash[String, String]) } def headers_for(hostname) token = tokens[hostname] token ? { "Authorization" => "Bearer #{token}" } : {} end + sig { returns(T::Hash[String, String]) } def services - @services ||= + @services ||= T.let( begin response = http_get(url_for("/.well-known/terraform.json")) response.status == 200 ? JSON.parse(response.body) : {} - end + end, + T.nilable(T::Hash[String, String]) + ) end + sig { params(type: String).returns(String) } def service_key_for(type) case type when "module", "modules", "registry" @@ -165,6 +189,7 @@ def service_key_for(type) end end + sig { params(url: T.any(String, URI::Generic)).returns(Excon::Response) } def http_get(url) Dependabot::RegistryClient.get( url: url.to_s, @@ -172,6 +197,7 @@ def http_get(url) ) end + sig { params(url: URI::Generic).returns(Excon::Response) } def http_get!(url) response = http_get(url) @@ -181,6 +207,7 @@ def http_get!(url) response end + sig { params(path: String).returns(String) } def url_for(path) uri = URI.parse(path) return uri.to_s if uri.scheme == "https" @@ -191,6 +218,7 @@ def url_for(path) uri.to_s end + sig { params(message: String).returns(Dependabot::DependabotError) } def error(message) Dependabot::DependabotError.new(message) end