dependabot-terraform 0.145.4 → 0.148.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6cf1e8836cea7995d0aef09994f802d1998c32ef12bb7d226f130bb53edf138
4
- data.tar.gz: e5ca05e600f6d2f0882447122cfa35fcad661afd9eb974be345d60dc9f2558cb
3
+ metadata.gz: 7d7706b0b1a4caf093c24a35a6c49398abfa8c96b6ad18dc7db44bab894c7581
4
+ data.tar.gz: f482a7a71f487f0815ff464b189edab66c0a77e3d4ffdd1b5a5080e17680de27
5
5
  SHA512:
6
- metadata.gz: 992d918f528309caafe5b983cd48db2427fe729d9f8bd4c3d25ca06a92bf898454b29669285b01069df21a995dbe5a31d584e9a86afd761d1dffdbbb6b06fb78
7
- data.tar.gz: 39ef0856f66834d0c6a0a04ef8936c07f63706f1b665ddbec9c5c7db05b44370869e9acec2d77dcb56c77401e1473260d13a08fc4f2889f5aac8eac237247999
6
+ metadata.gz: bc1983b4f79f865bac2a1f12f379c96f649b7b4056d67c96a6a3d6d2ad0a27e653b216baad1f85aba931bd8c1510a01e4913e32307b91a4311b2160c60e80f44
7
+ data.tar.gz: d7b18e3cb48784d3fe22c305b6f609d75a7c553d3191305c3b30d2cecd45274a85b615f9513867f08a9d9ff07ae8b248dab1a8198a3c724b159c58016c0126f4
data/helpers/build CHANGED
@@ -13,7 +13,10 @@ if [ ! -d "$install_dir/bin" ]; then
13
13
  fi
14
14
 
15
15
  os="$(uname -s | tr '[:upper:]' '[:lower:]')"
16
- github_url="https://github.com/kvz/json2hcl"
17
- url="${github_url}/releases/download/v0.0.6/json2hcl_v0.0.6_${os}_amd64"
18
- wget -O "$install_dir/bin/json2hcl" "$url"
19
- chmod +x "$install_dir/bin/json2hcl"
16
+
17
+ hcl2json_checksum="24068f1e25a34d8f8ca763f34fce11527472891bfa834d1504f665855021d5d4"
18
+ hcl2json_url="https://github.com/tmccombs/hcl2json/releases/download/v0.3.3/hcl2json_${os}_amd64"
19
+ hcl2json_path="$install_dir/bin/hcl2json"
20
+ wget -O "$hcl2json_path" "$hcl2json_url"
21
+ echo "$hcl2json_checksum $hcl2json_path" | sha256sum -c
22
+ chmod +x "$install_dir/bin/hcl2json"
@@ -2,12 +2,15 @@
2
2
 
3
3
  require "dependabot/file_fetchers"
4
4
  require "dependabot/file_fetchers/base"
5
+ require "dependabot/terraform/file_selector"
5
6
 
6
7
  module Dependabot
7
8
  module Terraform
8
9
  class FileFetcher < Dependabot::FileFetchers::Base
10
+ include FileSelector
11
+
9
12
  def self.required_files_in?(filenames)
10
- filenames.any? { |f| f.end_with?(".tf", ".tfvars") }
13
+ filenames.any? { |f| f.end_with?(".tf", ".hcl") }
11
14
  end
12
15
 
13
16
  def self.required_files_message
@@ -39,7 +42,7 @@ module Dependabot
39
42
  def terragrunt_files
40
43
  @terragrunt_files ||=
41
44
  repo_contents(raise_errors: false).
42
- select { |f| f.type == "file" && f.name.end_with?(".tfvars") }.
45
+ select { |f| f.type == "file" && terragrunt_file?(f.name) }.
43
46
  map { |f| fetch_file_from_host(f.name) }
44
47
  end
45
48
  end
@@ -10,27 +10,38 @@ require "dependabot/file_parsers/base"
10
10
  require "dependabot/git_commit_checker"
11
11
  require "dependabot/shared_helpers"
12
12
  require "dependabot/errors"
13
+ require "dependabot/terraform/file_selector"
13
14
 
14
15
  module Dependabot
15
16
  module Terraform
16
17
  class FileParser < Dependabot::FileParsers::Base
17
18
  require "dependabot/file_parsers/base/dependency_set"
18
19
 
20
+ include FileSelector
21
+
19
22
  ARCHIVE_EXTENSIONS = %w(.zip .tbz2 .tgz .txz).freeze
20
23
 
21
24
  def parse
22
25
  dependency_set = DependencySet.new
23
26
 
24
27
  terraform_files.each do |file|
25
- modules = parsed_file(file).fetch("module", []).map(&:first)
28
+ modules = parsed_file(file).fetch("module", {})
26
29
  modules.each do |name, details|
27
- dependency_set << build_terraform_dependency(file, name, details)
30
+ dependency_set << build_terraform_dependency(file, name, details, false)
31
+ end
32
+
33
+ parsed_file(file).fetch("terraform", []).each do |terraform|
34
+ required_providers = terraform.fetch("required_providers", {})
35
+ required_providers.each do |provider|
36
+ provider.each do |name, details|
37
+ dependency_set << build_terraform_dependency(file, name, details, true)
38
+ end
39
+ end
28
40
  end
29
41
  end
30
42
 
31
43
  terragrunt_files.each do |file|
32
- modules = parsed_file(file).fetch("terragrunt", []).first || {}
33
- modules = modules.fetch("terraform", [])
44
+ modules = parsed_file(file).fetch("terraform", [])
34
45
  modules.each do |details|
35
46
  next unless details["source"]
36
47
 
@@ -38,17 +49,20 @@ module Dependabot
38
49
  end
39
50
  end
40
51
 
41
- dependency_set.dependencies
52
+ dependency_set.dependencies.sort_by(&:name)
42
53
  end
43
54
 
44
55
  private
45
56
 
46
- def build_terraform_dependency(file, name, details)
47
- details = details.first
57
+ def build_terraform_dependency(file, name, details, provider)
58
+ details = details.is_a?(Array) ? details.first : details
48
59
 
49
- source = source_from(details)
50
- dep_name =
51
- source[:type] == "registry" ? source[:module_identifier] : name
60
+ source = source_from(details, provider)
61
+ dep_name = case source[:type]
62
+ when "registry" then source[:module_identifier]
63
+ when "provider" then details["source"]
64
+ else name
65
+ end
52
66
  version_req = details["version"]&.strip
53
67
  version =
54
68
  if source[:type] == "git" then version_from_ref(source[:ref])
@@ -69,7 +83,7 @@ module Dependabot
69
83
  end
70
84
 
71
85
  def build_terragrunt_dependency(file, details)
72
- source = source_from(details)
86
+ source = source_from(details, false)
73
87
  dep_name =
74
88
  if Source.from_url(source[:url])
75
89
  Source.from_url(source[:url]).repo
@@ -93,7 +107,7 @@ module Dependabot
93
107
  end
94
108
 
95
109
  # Full docs at https://www.terraform.io/docs/modules/sources.html
96
- def source_from(details_hash)
110
+ def source_from(details_hash, provider)
97
111
  raw_source = details_hash.fetch("source")
98
112
  bare_source = get_proxied_source(raw_source)
99
113
 
@@ -104,17 +118,23 @@ module Dependabot
104
118
  when :github, :bitbucket, :git
105
119
  git_source_details_from(bare_source)
106
120
  when :registry
107
- registry_source_details_from(bare_source)
121
+ registry_source_details_from(bare_source, provider)
108
122
  end
109
123
 
110
124
  source_details[:proxy_url] = raw_source if raw_source != bare_source
111
125
  source_details
112
126
  end
113
127
 
114
- def registry_source_details_from(source_string)
128
+ def registry_source_details_from(source_string, provider)
115
129
  parts = source_string.split("//").first.split("/")
116
130
 
117
- if parts.count == 3
131
+ if provider && parts.count == 2
132
+ {
133
+ "type": "provider",
134
+ "registry_hostname": "registry.terraform.io",
135
+ "module_identifier": source_string
136
+ }
137
+ elsif parts.count == 3
118
138
  {
119
139
  type: "registry",
120
140
  registry_hostname: "registry.terraform.io",
@@ -210,30 +230,51 @@ module Dependabot
210
230
  end
211
231
  # rubocop:enable Metrics/PerceivedComplexity
212
232
 
233
+ # == Returns:
234
+ # A Hash representing each module found in the specified file
235
+ #
236
+ # E.g.
237
+ # {
238
+ # "module" => {
239
+ # {
240
+ # "consul" => [
241
+ # {
242
+ # "source"=>"consul/aws",
243
+ # "version"=>"0.1.0"
244
+ # }
245
+ # ]
246
+ # }
247
+ # },
248
+ # "terragrunt"=>[
249
+ # {
250
+ # "include"=>[{ "path"=>"${find_in_parent_folders()}" }],
251
+ # "terraform"=>[{ "source" => "git::git@github.com:gruntwork-io/modules-example.git//consul?ref=v0.0.2" }]
252
+ # }
253
+ # ],
254
+ # }
213
255
  def parsed_file(file)
214
256
  @parsed_buildfile ||= {}
215
- @parsed_buildfile[file.name] ||=
216
- SharedHelpers.in_a_temporary_directory do
217
- File.write("tmp.tf", file.content)
218
-
219
- command = "#{terraform_parser_path} -reverse < tmp.tf"
220
- start = Time.now
221
- stdout, stderr, process = Open3.capture3(command)
222
- time_taken = Time.now - start
223
-
224
- unless process.success?
225
- raise SharedHelpers::HelperSubprocessFailed.new(
226
- message: stderr,
227
- error_context: {
228
- command: command,
229
- time_taken: time_taken,
230
- process_exit_value: process.to_s
231
- }
232
- )
233
- end
234
-
235
- JSON.parse(stdout)
257
+ @parsed_buildfile[file.name] ||= SharedHelpers.in_a_temporary_directory do
258
+ File.write("tmp.tf", file.content)
259
+
260
+ command = "#{terraform_hcl2_parser_path} < tmp.tf"
261
+ start = Time.now
262
+ stdout, stderr, process = Open3.capture3(command)
263
+ time_taken = Time.now - start
264
+
265
+ unless process.success?
266
+ raise SharedHelpers::HelperSubprocessFailed.new(
267
+ message: stderr,
268
+ error_context: {
269
+ command: command,
270
+ time_taken: time_taken,
271
+ process_exit_value: process.to_s
272
+ }
273
+ )
236
274
  end
275
+
276
+ JSON.parse(stdout)
277
+ end
237
278
  rescue SharedHelpers::HelperSubprocessFailed => e
238
279
  msg = e.message.strip
239
280
  raise Dependabot::DependencyFileNotParseable.new(file.path, msg)
@@ -244,19 +285,16 @@ module Dependabot
244
285
  Pathname.new(File.join(helper_bin_dir, "json2hcl")).cleanpath.to_path
245
286
  end
246
287
 
288
+ def terraform_hcl2_parser_path
289
+ helper_bin_dir = File.join(native_helpers_root, "terraform/bin")
290
+ Pathname.new(File.join(helper_bin_dir, "hcl2json")).cleanpath.to_path
291
+ end
292
+
247
293
  def native_helpers_root
248
294
  default_path = File.join(__dir__, "../../../helpers/install-dir")
249
295
  ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", default_path)
250
296
  end
251
297
 
252
- def terraform_files
253
- dependency_files.select { |f| f.name.end_with?(".tf") }
254
- end
255
-
256
- def terragrunt_files
257
- dependency_files.select { |f| f.name.end_with?(".tfvars") }
258
- end
259
-
260
298
  def check_required_files
261
299
  return if [*terraform_files, *terragrunt_files].any?
262
300
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FileSelector
4
+ private
5
+
6
+ def terraform_files
7
+ dependency_files.select { |f| f.name.end_with?(".tf") }
8
+ end
9
+
10
+ def terragrunt_files
11
+ dependency_files.select { |f| terragrunt_file?(f.name) }
12
+ end
13
+
14
+ def terragrunt_file?(file_name)
15
+ file_name != ".terraform.lock.hcl" && file_name.end_with?(".hcl")
16
+ end
17
+ end
@@ -3,12 +3,15 @@
3
3
  require "dependabot/file_updaters"
4
4
  require "dependabot/file_updaters/base"
5
5
  require "dependabot/errors"
6
+ require "dependabot/terraform/file_selector"
6
7
 
7
8
  module Dependabot
8
9
  module Terraform
9
10
  class FileUpdater < Dependabot::FileUpdaters::Base
11
+ include FileSelector
12
+
10
13
  def self.updated_files_regex
11
- [/\.tf$/, /\.tfvars$/]
14
+ [/\.tf$/, /\.hcl$/]
12
15
  end
13
16
 
14
17
  def updated_dependency_files
@@ -44,7 +47,7 @@ module Dependabot
44
47
  case new_req[:source][:type]
45
48
  when "git"
46
49
  update_git_declaration(new_req, old_req, content, file.name)
47
- when "registry"
50
+ when "registry", "provider"
48
51
  update_registry_declaration(new_req, old_req, content)
49
52
  else
50
53
  raise "Don't know how to update a #{new_req[:source][:type]} "\
@@ -87,14 +90,6 @@ module Dependabot
87
90
  dependency_files.select { |file| filenames.include?(file.name) }
88
91
  end
89
92
 
90
- def terraform_files
91
- dependency_files.select { |f| f.name.end_with?(".tf") }
92
- end
93
-
94
- def terragrunt_files
95
- dependency_files.select { |f| f.name.end_with?(".tfvars") }
96
- end
97
-
98
93
  def check_required_files
99
94
  return if [*terraform_files, *terragrunt_files].any?
100
95
 
@@ -113,7 +108,7 @@ module Dependabot
113
108
  def git_declaration_regex(filename)
114
109
  # For terragrunt dependencies there's not a lot we can base the
115
110
  # regex on. Just look for declarations within a `terraform` block
116
- return /terraform\s*\{(?:(?!^\}).)*/m if filename.end_with?(".tfvars")
111
+ return /terraform\s*\{(?:(?!^\}).)*/m if terragrunt_file?(filename)
117
112
 
118
113
  # For modules we can do better - filter for module blocks that use the
119
114
  # name of the dependency
@@ -15,6 +15,7 @@ module Dependabot
15
15
  case new_source_type
16
16
  when "git" then find_source_from_git_url
17
17
  when "registry" then find_source_from_registry_details
18
+ when "provider" then find_source_from_provider_details
18
19
  else raise "Unexpected source type: #{new_source_type}"
19
20
  end
20
21
  end
@@ -36,29 +37,11 @@ module Dependabot
36
37
  Source.from_url(url)
37
38
  end
38
39
 
39
- # Registry API docs:
40
- # https://www.terraform.io/docs/registry/api.html
41
40
  def find_source_from_registry_details
42
41
  info = dependency.requirements.map { |r| r[:source] }.compact.first
43
-
44
42
  hostname = info[:registry_hostname] || info["registry_hostname"]
45
43
 
46
- # TODO: Implement service discovery for custom registries
47
- return unless hostname == "registry.terraform.io"
48
-
49
- url = "https://registry.terraform.io/v1/modules/"\
50
- "#{dependency.name}/#{dependency.version}"
51
-
52
- response = Excon.get(
53
- url,
54
- idempotent: true,
55
- **SharedHelpers.excon_defaults
56
- )
57
-
58
- raise "Response from registry was #{response.status}" unless response.status == 200
59
-
60
- source_url = JSON.parse(response.body).fetch("source")
61
- Source.from_url(source_url) if source_url
44
+ RegistryClient.new(hostname: hostname).source(dependency: dependency)
62
45
  end
63
46
  end
64
47
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dependabot/dependency"
4
+ require "dependabot/source"
5
+ require "dependabot/terraform/version"
6
+
7
+ module Dependabot
8
+ module Terraform
9
+ # Terraform::RegistryClient is a basic API client to interact with a
10
+ # terraform registry: https://www.terraform.io/docs/registry/api.html
11
+ class RegistryClient
12
+ PUBLIC_HOSTNAME = "registry.terraform.io"
13
+
14
+ def initialize(hostname:)
15
+ @hostname = hostname
16
+ end
17
+
18
+ # Fetch all the versions of a provider, and return a Version
19
+ # representation of them.
20
+ #
21
+ # @param identifier [String] the identifier for the dependency, i.e:
22
+ # "hashicorp/aws"
23
+ # @return [Array<Dependabot::Terraform::Version>]
24
+ # @raise [RuntimeError] when the versions cannot be retrieved
25
+ def all_provider_versions(identifier:)
26
+ # TODO: Implement service discovery for custom registries
27
+ return [] unless hostname == PUBLIC_HOSTNAME
28
+
29
+ response = get(endpoint: "providers/#{identifier}/versions")
30
+
31
+ JSON.parse(response).
32
+ fetch("versions").
33
+ map { |release| version_class.new(release.fetch("version")) }
34
+ end
35
+
36
+ # Fetch all the versions of a module, and return a Version
37
+ # representation of them.
38
+ #
39
+ # @param identifier [String] the identifier for the dependency, i.e:
40
+ # "hashicorp/consul/aws"
41
+ # @return [Array<Dependabot::Terraform::Version>]
42
+ # @raise [RuntimeError] when the versions cannot be retrieved
43
+ def all_module_versions(identifier:)
44
+ # TODO: Implement service discovery for custom registries
45
+ return [] unless hostname == PUBLIC_HOSTNAME
46
+
47
+ response = get(endpoint: "modules/#{identifier}/versions")
48
+
49
+ JSON.parse(response).
50
+ fetch("modules").first.fetch("versions").
51
+ map { |release| version_class.new(release.fetch("version")) }
52
+ end
53
+
54
+ # Fetch the "source" for a module or provider. We use the API to fetch
55
+ # the source for a dependency, this typically points to a source code
56
+ # repository, and then instantiate a Dependabot::Source object that we
57
+ # can use to fetch Metadata about a specific version of the dependency.
58
+ #
59
+ # @param dependency [Dependabot::Dependency] the dependency who's source
60
+ # we're attempting to find
61
+ # @return Dependabot::Source
62
+ # @raise [RuntimeError] when the source cannot be retrieved
63
+ def source(dependency:)
64
+ # TODO: Implement service discovery for custom registries
65
+ return unless hostname == PUBLIC_HOSTNAME
66
+
67
+ endpoint = if dependency.requirements.first[:source][:type] == "registry"
68
+ "modules/#{dependency.name}/#{dependency.version}"
69
+ elsif dependency.source[:type] == "provider"
70
+ "providers/#{dependency.name}/#{dependency.version}"
71
+ else
72
+ raise "Invalid source type"
73
+ end
74
+ response = get(endpoint: endpoint)
75
+
76
+ source_url = JSON.parse(response).fetch("source")
77
+ Source.from_url(source_url) if source_url
78
+ end
79
+
80
+ private
81
+
82
+ attr_reader :hostname
83
+
84
+ def get(endpoint:)
85
+ url = "https://#{hostname}/v1/#{endpoint}"
86
+
87
+ response = Excon.get(
88
+ url,
89
+ idempotent: true,
90
+ **SharedHelpers.excon_defaults
91
+ )
92
+
93
+ raise "Response from registry was #{response.status}" unless response.status == 200
94
+
95
+ response.body
96
+ end
97
+
98
+ def version_class
99
+ Version
100
+ end
101
+ end
102
+ end
103
+ end
@@ -10,9 +10,45 @@ require "dependabot/terraform/requirement"
10
10
 
11
11
  module Dependabot
12
12
  module Terraform
13
+ # Takes an array of `requirements` hashes for a dependency at the old
14
+ # version and a new version, and generates a set of new `requirements`
15
+ # hashes at the new version.
16
+ #
17
+ # A requirements hash is a basic description of a dependency at a certain
18
+ # version constraint, and it includes the data that is needed to update the
19
+ # manifest (i.e. the `.tf` file) with the new version.
20
+ #
21
+ # A requirements hash looks like this for a registry hosted requirement:
22
+ # ```ruby
23
+ # {
24
+ # requirement: "~> 0.2.1",
25
+ # groups: [],
26
+ # file: "main.tf",
27
+ # source: {
28
+ # type: "registry",
29
+ # registry_hostname: "registry.terraform.io",
30
+ # module_identifier: "hashicorp/consul/aws"
31
+ # }
32
+ # }
33
+ #
34
+ # And like this for a git requirement:
35
+ # ```ruby
36
+ # {
37
+ # requirement: nil,
38
+ # groups: [],
39
+ # file: "main.tf",
40
+ # source: {
41
+ # type: "git",
42
+ # url: "https://github.com/cloudposse/terraform-null-label.git",
43
+ # branch: nil,
44
+ # ref: nil
45
+ # }
46
+ # }
13
47
  class RequirementsUpdater
14
- def initialize(requirements:, latest_version:,
15
- tag_for_latest_version:)
48
+ # @param requirements [Hash{Symbol => String, Array, Hash}]
49
+ # @param latest_version [Dependabot::Terraform::Version]
50
+ # @param tag_for_latest_version [String, NilClass]
51
+ def initialize(requirements:, latest_version:, tag_for_latest_version:)
16
52
  @requirements = requirements
17
53
  @tag_for_latest_version = tag_for_latest_version
18
54
 
@@ -22,6 +58,11 @@ module Dependabot
22
58
  @latest_version = version_class.new(latest_version)
23
59
  end
24
60
 
61
+ # @return requirements [Hash{Symbol => String, Array, Hash}]
62
+ # * requirement [String, NilClass] the updated version constraint
63
+ # * groups [Array] no-op for terraform
64
+ # * file [String] the file that specified this dependency
65
+ # * source [Hash{Symbol => String}] The updated git or registry source details
25
66
  def updated_requirements
26
67
  return requirements unless latest_version
27
68
 
@@ -31,7 +72,7 @@ module Dependabot
31
72
  requirements.map do |req|
32
73
  case req.dig(:source, :type)
33
74
  when "git" then update_git_requirement(req)
34
- when "registry" then update_registry_requirement(req)
75
+ when "registry", "provider" then update_registry_requirement(req)
35
76
  else req
36
77
  end
37
78
  end
@@ -6,6 +6,7 @@ require "dependabot/git_commit_checker"
6
6
  require "dependabot/terraform/requirements_updater"
7
7
  require "dependabot/terraform/requirement"
8
8
  require "dependabot/terraform/version"
9
+ require "dependabot/terraform/registry_client"
9
10
 
10
11
  module Dependabot
11
12
  module Terraform
@@ -13,6 +14,7 @@ module Dependabot
13
14
  def latest_version
14
15
  return latest_version_for_git_dependency if git_dependency?
15
16
  return latest_version_for_registry_dependency if registry_dependency?
17
+ return latest_version_for_provider_dependency if provider_dependency?
16
18
  # Other sources (mercurial, path dependencies) just return `nil`
17
19
  end
18
20
 
@@ -65,34 +67,40 @@ module Dependabot
65
67
 
66
68
  return @latest_version_for_registry_dependency if @latest_version_for_registry_dependency
67
69
 
68
- versions = all_registry_versions
70
+ versions = all_module_versions
69
71
  versions.reject!(&:prerelease?) unless wants_prerelease?
70
72
  versions.reject! { |v| ignore_requirements.any? { |r| r.satisfied_by?(v) } }
71
73
 
72
74
  @latest_version_for_registry_dependency = versions.max
73
75
  end
74
76
 
75
- def all_registry_versions
76
- hostname = dependency_source_details.fetch(:registry_hostname)
77
+ def all_module_versions
77
78
  identifier = dependency_source_details.fetch(:module_identifier)
79
+ registry_client.all_module_versions(identifier: identifier)
80
+ end
81
+
82
+ def all_provider_versions
83
+ identifier = dependency_source_details.fetch(:module_identifier)
84
+ registry_client.all_provider_versions(identifier: identifier)
85
+ end
78
86
 
79
- # TODO: Implement service discovery for custom registries
80
- return [] unless hostname == "registry.terraform.io"
87
+ def registry_client
88
+ @registry_client ||= begin
89
+ hostname = dependency_source_details.fetch(:registry_hostname)
90
+ RegistryClient.new(hostname: hostname)
91
+ end
92
+ end
81
93
 
82
- url = "https://registry.terraform.io/v1/modules/"\
83
- "#{identifier}/versions"
94
+ def latest_version_for_provider_dependency
95
+ return unless provider_dependency?
84
96
 
85
- response = Excon.get(
86
- url,
87
- idempotent: true,
88
- **SharedHelpers.excon_defaults
89
- )
97
+ return @latest_version_for_provider_dependency if @latest_version_for_provider_dependency
90
98
 
91
- raise "Response from registry was #{response.status}" unless response.status == 200
99
+ versions = all_provider_versions
100
+ versions.reject!(&:prerelease?) unless wants_prerelease?
101
+ versions.reject! { |v| ignore_requirements.any? { |r| r.satisfied_by?(v) } }
92
102
 
93
- JSON.parse(response.body).
94
- fetch("modules").first.fetch("versions").
95
- map { |release| version_class.new(release.fetch("version")) }
103
+ @latest_version_for_provider_dependency = versions.max
96
104
  end
97
105
 
98
106
  def wants_prerelease?
@@ -160,6 +168,12 @@ module Dependabot
160
168
  dependency_source_details.fetch(:type) == "registry"
161
169
  end
162
170
 
171
+ def provider_dependency?
172
+ return false if dependency_source_details.nil?
173
+
174
+ dependency_source_details.fetch(:type) == "provider"
175
+ end
176
+
163
177
  def dependency_source_details
164
178
  sources =
165
179
  dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-terraform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.145.4
4
+ version: 0.148.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-10 00:00:00.000000000 Z
11
+ date: 2021-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.145.4
19
+ version: 0.148.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.145.4
26
+ version: 0.148.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.14.0
103
+ version: 1.15.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.14.0
110
+ version: 1.15.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -189,8 +189,10 @@ files:
189
189
  - lib/dependabot/terraform.rb
190
190
  - lib/dependabot/terraform/file_fetcher.rb
191
191
  - lib/dependabot/terraform/file_parser.rb
192
+ - lib/dependabot/terraform/file_selector.rb
192
193
  - lib/dependabot/terraform/file_updater.rb
193
194
  - lib/dependabot/terraform/metadata_finder.rb
195
+ - lib/dependabot/terraform/registry_client.rb
194
196
  - lib/dependabot/terraform/requirement.rb
195
197
  - lib/dependabot/terraform/requirements_updater.rb
196
198
  - lib/dependabot/terraform/update_checker.rb