dependabot-terraform 0.276.0 → 0.277.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: 9d1d53e1f7f48deae40823c178a8e34590dcb9a686605ac04b4a26b4b68c6b29
4
- data.tar.gz: a09a75e466ff9635927215cbbcd84ecef4e43a3814785801f676a4c00358d7a4
3
+ metadata.gz: ebe92edc7ae776761d9ddb633672c9ff260d86b40dd845c08307d7f30a4315c1
4
+ data.tar.gz: 1fb3fb264832e08f580e40157f3fac8e3de388bc700991cd2184b2ef3de0c025
5
5
  SHA512:
6
- metadata.gz: 642f839e7f70293587c940b3a30a8419080069d76ca10e8fd1439e3883f1da1d5c15cab7e1ac50e436d99e028235381a7a19ad5b682ddaf35619b35c0f50c90b
7
- data.tar.gz: a3e4d05af1d6c4567e45fc8e53516de2557d9805117b80c6adbf4255fc3633005b4e69d2f3e9524cfd37e4ac2be18586ecc4aa4e582690fbf42392f61e653f0b
6
+ metadata.gz: d0a06b41820076bf571c81d4bda05b0fac400e6853ab1264042cf425585c01c984eb1c4467fd0fbc9bf232afea18026cda47349fd9ede280693aa9cbd9e27da7
7
+ data.tar.gz: c885814bd5b0ddd9bd858b9d1e0eec2491ec45711e76a8f41c8955ff316e9b0a39b76db33b8b15a68d5ee1756e8d31a31844b04bd7c6e764efa9a9efa12499f9
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "cgi"
@@ -30,6 +30,7 @@ module Dependabot
30
30
  # https://www.terraform.io/docs/language/providers/requirements.html#source-addresses
31
31
  PROVIDER_SOURCE_ADDRESS = %r{\A((?<hostname>.+)/)?(?<namespace>.+)/(?<name>.+)\z}
32
32
 
33
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
33
34
  def parse
34
35
  dependency_set = DependencySet.new
35
36
 
@@ -42,6 +43,7 @@ module Dependabot
42
43
 
43
44
  private
44
45
 
46
+ sig { params(dependency_set: Dependabot::FileParsers::Base::DependencySet).void }
45
47
  def parse_terraform_files(dependency_set)
46
48
  terraform_files.each do |file|
47
49
  modules = parsed_file(file).fetch("module", {})
@@ -50,9 +52,9 @@ module Dependabot
50
52
 
51
53
  source = source_from(details)
52
54
  # Cannot update local path modules, skip
53
- next if source[:type] == "path"
55
+ next if source && source[:type] == "path"
54
56
 
55
- dependency_set << build_terraform_dependency(file, name, source, details)
57
+ dependency_set << build_terraform_dependency(file, name, T.must(source), details)
56
58
  end
57
59
 
58
60
  parsed_file(file).fetch("terraform", []).each do |terraform|
@@ -66,6 +68,7 @@ module Dependabot
66
68
  end
67
69
  end
68
70
 
71
+ sig { params(dependency_set: Dependabot::FileParsers::Base::DependencySet).void }
69
72
  def parse_terragrunt_files(dependency_set)
70
73
  terragrunt_files.each do |file|
71
74
  modules = parsed_file(file).fetch("terraform", [])
@@ -81,6 +84,15 @@ module Dependabot
81
84
  end
82
85
  end
83
86
 
87
+ sig do
88
+ params(
89
+ file: Dependabot::DependencyFile,
90
+ name: String,
91
+ source: T::Hash[Symbol, T.untyped],
92
+ details: T.untyped
93
+ )
94
+ .returns(Dependabot::Dependency)
95
+ end
84
96
  def build_terraform_dependency(file, name, source, details)
85
97
  # dep_name should be unique for a source, using the info derived from
86
98
  # the source or the source name provides this uniqueness
@@ -109,17 +121,25 @@ module Dependabot
109
121
  )
110
122
  end
111
123
 
124
+ sig do
125
+ params(
126
+ file: Dependabot::DependencyFile,
127
+ name: String,
128
+ details: T.any(String, T::Hash[String, T.untyped])
129
+ )
130
+ .returns(Dependabot::Dependency)
131
+ end
112
132
  def build_provider_dependency(file, name, details = {})
113
133
  deprecated_provider_error(file) if deprecated_provider?(details)
114
134
 
115
- source_address = details.fetch("source", nil)
135
+ source_address = T.cast(details, T::Hash[String, T.untyped]).fetch("source", nil)
116
136
  version_req = details["version"]&.strip
117
137
  hostname, namespace, name = provider_source_from(source_address, name)
118
138
  dependency_name = source_address ? "#{namespace}/#{name}" : name
119
139
 
120
140
  Dependency.new(
121
- name: dependency_name,
122
- version: determine_version_for(hostname, namespace, name, version_req),
141
+ name: T.must(dependency_name),
142
+ version: determine_version_for(T.must(hostname), T.must(namespace), T.must(name), version_req),
123
143
  package_manager: "terraform",
124
144
  requirements: [
125
145
  requirement: version_req,
@@ -134,6 +154,7 @@ module Dependabot
134
154
  )
135
155
  end
136
156
 
157
+ sig { params(file: Dependabot::DependencyFile).returns(T.noreturn) }
137
158
  def deprecated_provider_error(file)
138
159
  raise Dependabot::DependencyFileNotParseable.new(
139
160
  file.path,
@@ -143,18 +164,20 @@ module Dependabot
143
164
  )
144
165
  end
145
166
 
167
+ sig { params(details: Object).returns(T::Boolean) }
146
168
  def deprecated_provider?(details)
147
169
  # The old syntax for terraform providers v0.12- looked like
148
170
  # "tls ~> 2.1" which gets parsed as a string instead of a hash
149
171
  details.is_a?(String)
150
172
  end
151
173
 
174
+ sig { params(file: Dependabot::DependencyFile, source: T::Hash[Symbol, String]).returns(Dependabot::Dependency) }
152
175
  def build_terragrunt_dependency(file, source)
153
176
  dep_name = Source.from_url(source[:url]) ? T.must(Source.from_url(source[:url])).repo : source[:url]
154
177
  version = version_from_ref(source[:ref])
155
178
 
156
179
  Dependency.new(
157
- name: dep_name,
180
+ name: T.must(dep_name),
158
181
  version: version,
159
182
  package_manager: "terraform",
160
183
  requirements: [
@@ -167,6 +190,7 @@ module Dependabot
167
190
  end
168
191
 
169
192
  # Full docs at https://www.terraform.io/docs/modules/sources.html
193
+ sig { params(details_hash: T::Hash[String, String]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
170
194
  def source_from(details_hash)
171
195
  raw_source = details_hash.fetch("source")
172
196
  bare_source = RegistryClient.get_proxied_source(raw_source)
@@ -183,10 +207,11 @@ module Dependabot
183
207
  return nil
184
208
  end
185
209
 
186
- source_details[:proxy_url] = raw_source if raw_source != bare_source
210
+ T.must(source_details)[:proxy_url] = raw_source if raw_source != bare_source
187
211
  source_details
188
212
  end
189
213
 
214
+ sig { params(source_address: T.nilable(String), name: String).returns(T::Array[String]) }
190
215
  def provider_source_from(source_address, name)
191
216
  matches = source_address&.match(PROVIDER_SOURCE_ADDRESS)
192
217
  matches = {} if matches.nil?
@@ -198,6 +223,7 @@ module Dependabot
198
223
  ]
199
224
  end
200
225
 
226
+ sig { params(source_string: T.untyped).returns(T::Hash[Symbol, String]) }
201
227
  def registry_source_details_from(source_string)
202
228
  parts = source_string.split("//").first.split("/")
203
229
 
@@ -219,6 +245,7 @@ module Dependabot
219
245
  end
220
246
  end
221
247
 
248
+ sig { params(name: String, source: T::Hash[Symbol, T.untyped]).returns(String) }
222
249
  def git_dependency_name(name, source)
223
250
  git_source = Source.from_url(source[:url])
224
251
  if git_source && source[:ref]
@@ -233,13 +260,14 @@ module Dependabot
233
260
  end
234
261
  end
235
262
 
263
+ sig { params(source_string: String).returns(T::Hash[Symbol, T.nilable(String)]) }
236
264
  def git_source_details_from(source_string)
237
265
  git_url = source_string.strip.gsub(/^git::/, "")
238
266
  git_url = "https://" + git_url unless git_url.start_with?("git@") || git_url.include?("://")
239
267
 
240
268
  bare_uri =
241
269
  if git_url.include?("git@")
242
- git_url.split("git@").last.sub(":", "/")
270
+ T.must(git_url.split("git@").last).sub(":", "/")
243
271
  else
244
272
  git_url.sub(%r{.*?://}, "")
245
273
  end
@@ -255,14 +283,16 @@ module Dependabot
255
283
  }
256
284
  end
257
285
 
286
+ sig { params(ref: T.nilable(String)).returns(T.nilable(String)) }
258
287
  def version_from_ref(ref)
259
288
  version_regex = GitCommitChecker::VERSION_REGEX
260
289
  return unless ref&.match?(version_regex)
261
290
 
262
- ref.match(version_regex).named_captures.fetch("version")
291
+ ref.match(version_regex)&.named_captures&.fetch("version")
263
292
  end
264
293
 
265
294
  # rubocop:disable Metrics/PerceivedComplexity
295
+ sig { params(source_string: String).returns(Symbol) }
266
296
  def source_type(source_string)
267
297
  return :interpolation if source_string.include?("${")
268
298
  return :path if source_string.start_with?(".")
@@ -272,11 +302,11 @@ module Dependabot
272
302
  return :mercurial if source_string.start_with?("hg::")
273
303
  return :s3 if source_string.start_with?("s3::")
274
304
 
275
- raise "Unknown src: #{source_string}" if source_string.split("/").first.include?("::")
305
+ raise "Unknown src: #{source_string}" if source_string.split("/").first&.include?("::")
276
306
 
277
307
  return :registry unless source_string.start_with?("http")
278
308
 
279
- path_uri = URI.parse(source_string.split(%r{(?<!:)//}).first)
309
+ path_uri = URI.parse(T.must(source_string.split(%r{(?<!:)//}).first))
280
310
  query_uri = URI.parse(source_string)
281
311
  return :http_archive if path_uri.path.end_with?(*RegistryClient::ARCHIVE_EXTENSIONS)
282
312
  return :http_archive if query_uri.query&.include?("archive=")
@@ -307,8 +337,9 @@ module Dependabot
307
337
  # }
308
338
  # ],
309
339
  # }
340
+ sig { params(file: Dependabot::DependencyFile).returns(T::Hash[String, T.untyped]) }
310
341
  def parsed_file(file)
311
- @parsed_buildfile ||= {}
342
+ @parsed_buildfile ||= T.let({}, T.nilable(T::Hash[String, T.untyped]))
312
343
  @parsed_buildfile[file.name] ||= SharedHelpers.in_a_temporary_directory do
313
344
  File.write("tmp.tf", file.content)
314
345
 
@@ -335,27 +366,40 @@ module Dependabot
335
366
  raise Dependabot::DependencyFileNotParseable.new(file.path, msg)
336
367
  end
337
368
 
369
+ sig { returns(String) }
338
370
  def terraform_parser_path
339
371
  helper_bin_dir = File.join(native_helpers_root, "terraform/bin")
340
372
  Pathname.new(File.join(helper_bin_dir, "json2hcl")).cleanpath.to_path
341
373
  end
342
374
 
375
+ sig { returns(String) }
343
376
  def terraform_hcl2_parser_path
344
377
  helper_bin_dir = File.join(native_helpers_root, "terraform/bin")
345
378
  Pathname.new(File.join(helper_bin_dir, "hcl2json")).cleanpath.to_path
346
379
  end
347
380
 
381
+ sig { returns(String) }
348
382
  def native_helpers_root
349
383
  default_path = File.join(__dir__, "../../../helpers/install-dir")
350
384
  ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", default_path)
351
385
  end
352
386
 
387
+ sig { override.void }
353
388
  def check_required_files
354
389
  return if [*terraform_files, *terragrunt_files].any?
355
390
 
356
391
  raise "No Terraform configuration file!"
357
392
  end
358
393
 
394
+ sig do
395
+ params(
396
+ hostname: String,
397
+ namespace: String,
398
+ name: String,
399
+ constraint: T.nilable(String)
400
+ )
401
+ .returns(T.nilable(String))
402
+ end
359
403
  def determine_version_for(hostname, namespace, name, constraint)
360
404
  return constraint if constraint&.match?(/\A\d/)
361
405
 
@@ -363,14 +407,17 @@ module Dependabot
363
407
  .dig("provider", "#{hostname}/#{namespace}/#{name}", 0, "version")
364
408
  end
365
409
 
410
+ sig { returns(T::Hash[String, T.untyped]) }
366
411
  def lockfile_content
367
- @lockfile_content ||=
412
+ @lockfile_content ||= T.let(
368
413
  begin
369
414
  lockfile = dependency_files.find do |file|
370
415
  file.name == ".terraform.lock.hcl"
371
416
  end
372
417
  lockfile ? parsed_file(lockfile) : {}
373
- end
418
+ end,
419
+ T.nilable(T::Hash[String, T.untyped])
420
+ )
374
421
  end
375
422
  end
376
423
  end
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  ####################################################################
@@ -6,6 +6,8 @@
6
6
  # https://www.terraform.io/docs/modules/usage.html#module-versions #
7
7
  ####################################################################
8
8
 
9
+ require "sorbet-runtime"
10
+
9
11
  require "dependabot/terraform/version"
10
12
  require "dependabot/terraform/requirement"
11
13
 
@@ -46,9 +48,18 @@ module Dependabot
46
48
  # }
47
49
  # }
48
50
  class RequirementsUpdater
51
+ extend T::Sig
52
+
49
53
  # @param requirements [Hash{Symbol => String, Array, Hash}]
50
54
  # @param latest_version [Dependabot::Terraform::Version]
51
55
  # @param tag_for_latest_version [String, NilClass]
56
+ sig do
57
+ params(
58
+ requirements: T::Array[T::Hash[Symbol, T.untyped]],
59
+ latest_version: T.nilable(Dependabot::Version::VersionParameter),
60
+ tag_for_latest_version: T.nilable(String)
61
+ ).void
62
+ end
52
63
  def initialize(requirements:, latest_version:, tag_for_latest_version:)
53
64
  @requirements = requirements
54
65
  @tag_for_latest_version = tag_for_latest_version
@@ -56,7 +67,7 @@ module Dependabot
56
67
  return unless latest_version
57
68
  return unless version_class.correct?(latest_version)
58
69
 
59
- @latest_version = version_class.new(latest_version)
70
+ @latest_version = T.let(version_class.new(latest_version), Dependabot::Terraform::Version)
60
71
  end
61
72
 
62
73
  # @return requirements [Hash{Symbol => String, Array, Hash}]
@@ -64,9 +75,8 @@ module Dependabot
64
75
  # * groups [Array] no-op for terraform
65
76
  # * file [String] the file that specified this dependency
66
77
  # * source [Hash{Symbol => String}] The updated git or registry source details
78
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
67
79
  def updated_requirements
68
- return requirements unless latest_version
69
-
70
80
  # NOTE: Order is important here. The FileUpdater needs the updated
71
81
  # requirement at index `i` to correspond to the previous requirement
72
82
  # at the same index.
@@ -81,10 +91,16 @@ module Dependabot
81
91
 
82
92
  private
83
93
 
94
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
84
95
  attr_reader :requirements
96
+
97
+ sig { returns(Dependabot::Terraform::Version) }
85
98
  attr_reader :latest_version
99
+
100
+ sig { returns(T.nilable(String)) }
86
101
  attr_reader :tag_for_latest_version
87
102
 
103
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
88
104
  def update_git_requirement(req)
89
105
  return req unless req.dig(:source, :ref)
90
106
  return req unless tag_for_latest_version
@@ -92,6 +108,7 @@ module Dependabot
92
108
  req.merge(source: req[:source].merge(ref: tag_for_latest_version))
93
109
  end
94
110
 
111
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
95
112
  def update_registry_requirement(req)
96
113
  return req if req.fetch(:requirement).nil?
97
114
 
@@ -111,6 +128,7 @@ module Dependabot
111
128
  end
112
129
 
113
130
  # Updates the version in a "~>" constraint to allow the given version
131
+ sig { params(req_string: String).returns(String) }
114
132
  def update_twiddle_version(req_string)
115
133
  old_version = requirement_class.new(req_string)
116
134
  .requirements.first.last
@@ -118,6 +136,7 @@ module Dependabot
118
136
  req_string.sub(old_version.to_s, updated_version)
119
137
  end
120
138
 
139
+ sig { params(req_string: String).returns(T::Array[Dependabot::Terraform::Requirement]) }
121
140
  def update_range(req_string)
122
141
  requirement_class.new(req_string).requirements.flat_map do |r|
123
142
  ruby_req = requirement_class.new(r.join(" "))
@@ -131,6 +150,13 @@ module Dependabot
131
150
  end
132
151
  end
133
152
 
153
+ sig do
154
+ params(
155
+ new_version: Dependabot::Terraform::Version,
156
+ old_version: Dependabot::Terraform::Version
157
+ )
158
+ .returns(String)
159
+ end
134
160
  def at_same_precision(new_version, old_version)
135
161
  release_precision =
136
162
  old_version.to_s.split(".").count { |i| i.match?(/^\d+$/) }
@@ -149,6 +175,13 @@ module Dependabot
149
175
 
150
176
  # Updates the version in a "<" or "<=" constraint to allow the given
151
177
  # version
178
+ sig do
179
+ params(
180
+ requirement: Dependabot::Requirement,
181
+ version_to_be_permitted: T.any(String, Dependabot::Terraform::Version)
182
+ )
183
+ .returns(Dependabot::Terraform::Requirement)
184
+ end
152
185
  def update_greatest_version(requirement, version_to_be_permitted)
153
186
  if version_to_be_permitted.is_a?(String)
154
187
  version_to_be_permitted =
@@ -164,7 +197,7 @@ module Dependabot
164
197
  if index < index_to_update
165
198
  version_to_be_permitted.segments[index]
166
199
  elsif index == index_to_update
167
- version_to_be_permitted.segments[index] + 1
200
+ version_to_be_permitted.segments[index].to_i + 1
168
201
  else
169
202
  0
170
203
  end
@@ -173,10 +206,12 @@ module Dependabot
173
206
  requirement_class.new("#{op} #{new_segments.join('.')}")
174
207
  end
175
208
 
209
+ sig { returns(T.class_of(Dependabot::Terraform::Version)) }
176
210
  def version_class
177
211
  Version
178
212
  end
179
213
 
214
+ sig { returns(T.class_of(Dependabot::Terraform::Requirement)) }
180
215
  def requirement_class
181
216
  Requirement
182
217
  end
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.276.0
4
+ version: 0.277.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-19 00:00:00.000000000 Z
11
+ date: 2024-09-23 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.276.0
19
+ version: 0.277.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.276.0
26
+ version: 0.277.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -260,7 +260,7 @@ licenses:
260
260
  - MIT
261
261
  metadata:
262
262
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
263
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.276.0
263
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.277.0
264
264
  post_install_message:
265
265
  rdoc_options: []
266
266
  require_paths: