Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve some Sorbet errors in Terraform #9545

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 31 additions & 12 deletions terraform/lib/dependabot/terraform/file_fetcher.rb
@@ -1,7 +1,8 @@
# typed: false
# typed: strict
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/file_fetchers"
require "dependabot/file_fetchers/base"
require "dependabot/terraform/file_selector"
Expand All @@ -12,15 +13,17 @@ class FileFetcher < Dependabot::FileFetchers::Base
extend T::Sig
extend T::Helpers

include FileSelector
include FileFilter

# https://www.terraform.io/docs/language/modules/sources.html#local-paths
LOCAL_PATH_SOURCE = %r{source\s*=\s*['"](?<path>..?\/[^'"]+)}

sig { override.params(filenames: T::Array[String]).returns(T::Boolean) }
def self.required_files_in?(filenames)
filenames.any? { |f| f.end_with?(".tf", ".hcl") }
end

sig { override.returns(String) }
def self.required_files_message
"Repo must contain a Terraform configuration file."
end
Expand All @@ -37,22 +40,35 @@ def fetch_files

private

sig { returns(T::Array[Dependabot::DependencyFile]) }
def terraform_files
@terraform_files ||=
@terraform_files ||= T.let(
repo_contents(raise_errors: false)
.select { |f| f.type == "file" && f.name.end_with?(".tf") }
.map { |f| fetch_file_from_host(f.name) }
.map { |f| fetch_file_from_host(f.name) },
T.nilable(T::Array[Dependabot::DependencyFile])
)
end

sig { returns(T::Array[Dependabot::DependencyFile]) }
def terragrunt_files
@terragrunt_files ||=
@terragrunt_files ||= T.let(
repo_contents(raise_errors: false)
.select { |f| f.type == "file" && terragrunt_file?(f.name) }
.map { |f| fetch_file_from_host(f.name) }
.map { |f| fetch_file_from_host(f.name) },
T.nilable(T::Array[Dependabot::DependencyFile])
)
end

sig do
params(
files: T::Array[Dependabot::DependencyFile],
dir: String
)
.returns(T::Array[Dependabot::DependencyFile])
end
def local_path_module_files(files, dir: ".")
terraform_files = []
terraform_files = T.let([], T::Array[Dependabot::DependencyFile])

files.each do |file|
terraform_file_local_module_details(file).each do |path|
Expand All @@ -71,19 +87,22 @@ def local_path_module_files(files, dir: ".")
terraform_files.tap { |fs| fs.each { |f| f.support_file = true } }
end

sig { params(file: Dependabot::DependencyFile).returns(T::Array[String]) }
def terraform_file_local_module_details(file)
return [] unless file.name.end_with?(".tf")
return [] unless file.content.match?(LOCAL_PATH_SOURCE)
return [] unless file.content&.match?(LOCAL_PATH_SOURCE)

file.content.scan(LOCAL_PATH_SOURCE).flatten.map do |path|
T.must(file.content).scan(LOCAL_PATH_SOURCE).flatten.map do |path|
Pathname.new(path).cleanpath.to_path
end
end

sig { returns(T.nilable(Dependabot::DependencyFile)) }
def lockfile
return @lockfile if defined?(@lockfile)

@lockfile = fetch_file_if_present(".terraform.lock.hcl")
@lockfile ||= T.let(
fetch_file_if_present(".terraform.lock.hcl"),
T.nilable(Dependabot::DependencyFile)
)
end
end
end
Expand Down
24 changes: 24 additions & 0 deletions terraform/lib/dependabot/terraform/file_filter.rb
@@ -0,0 +1,24 @@
# typed: strong
# frozen_string_literal: true

require "sorbet-runtime"

module Dependabot
module Terraform
module FileFilter
extend T::Sig

private

sig { params(file_name: String).returns(T::Boolean) }
def terragrunt_file?(file_name)
!lockfile?(file_name) && file_name.end_with?(".hcl")
end

sig { params(filename: String).returns(T::Boolean) }
def lockfile?(filename)
filename == ".terraform.lock.hcl"
end
end
end
end
47 changes: 30 additions & 17 deletions terraform/lib/dependabot/terraform/file_selector.rb
@@ -1,26 +1,39 @@
# typed: false
# typed: strong
# frozen_string_literal: true

module FileSelector
private
require "sorbet-runtime"

def terraform_files
dependency_files.select { |f| f.name.end_with?(".tf") }
end
require "dependabot/terraform/file_filter"

def terragrunt_files
dependency_files.select { |f| terragrunt_file?(f.name) }
end
module Dependabot
module Terraform
module FileSelector
extend T::Sig
extend T::Helpers

def terragrunt_file?(file_name)
!lockfile?(file_name) && file_name.end_with?(".hcl")
end
abstract!

def lockfile?(filename)
filename == ".terraform.lock.hcl"
end
sig { abstract.returns(T::Array[Dependabot::DependencyFile]) }
def dependency_files; end

private

include FileFilter

sig { returns(T::Array[Dependabot::DependencyFile]) }
def terraform_files
dependency_files.select { |f| f.name.end_with?(".tf") }
end

sig { returns(T::Array[Dependabot::DependencyFile]) }
def terragrunt_files
dependency_files.select { |f| terragrunt_file?(f.name) }
end

def lockfile
dependency_files.find { |f| lockfile?(f.name) }
sig { returns(T.nilable(Dependabot::DependencyFile)) }
def lockfile
dependency_files.find { |f| lockfile?(f.name) }
end
end
end
end