dependabot-cargo 0.332.0 → 0.333.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: 6b32ce25ebd9d7d1f9e9aeff3570a6aa5e47cfaf185f50de5bd489f4260af9fb
4
- data.tar.gz: 29017d4973b7f791c554f48dce854d4fee46459c2ace075d0bcadf2819412707
3
+ metadata.gz: '091190197e180945f1979a4102768e43519a054c4dcccfad73bebd41d6f08abe'
4
+ data.tar.gz: 3bc3403ebacc832ea65c9e7cce7fcf8bd39728548bf8bf9c516bf6d07594d9f0
5
5
  SHA512:
6
- metadata.gz: 0a8a6fcbe7f0838c02e8c8297e72950ccea7caca991a77186f3c7156909a65e2f9923b4e06cff4eb8ba6e4a50d419b6892b502c611216da67d98ae13853508c6
7
- data.tar.gz: 7d0cc93881ef4f77cef16362801e12c2ba05bb38a6d104b83cd34d64a3511edf322c6104e7b6e24808af308597d4a13b29f95539e2b7a64ae41505d34a20d1ea
6
+ metadata.gz: 3aef8d8668764a7849ea0b03ce683103151b1cbed29d8c0b405767d45805295358328e9a1105b990a8b70413f74bd1e2b045b884311ea7a0a8e6ac6f937e8a03
7
+ data.tar.gz: c62c275d2fee1f4477db333d62ed8bcf1a5f2eea1045356e4150a0afccdcda5a65a819b6cb5630d0943e6ebb0a49a9fc7ff82dba3fc1783dc432970de8d27294
@@ -7,6 +7,7 @@ require "toml-rb"
7
7
 
8
8
  require "dependabot/file_fetchers"
9
9
  require "dependabot/file_fetchers/base"
10
+ require "dependabot/file_filtering"
10
11
  require "dependabot/cargo/file_parser"
11
12
 
12
13
  # Docs on Cargo workspaces:
@@ -30,7 +31,7 @@ module Dependabot
30
31
  sig { override.returns(T.nilable(T::Hash[Symbol, T.untyped])) }
31
32
  def ecosystem_versions
32
33
  channel = if rust_toolchain
33
- TomlRB.parse(T.must(rust_toolchain).content).fetch("toolchain", nil)&.fetch("channel", nil)
34
+ TomlRB.parse(T.must(rust_toolchain).content).dig("toolchain", "channel")
34
35
  else
35
36
  "default"
36
37
  end
@@ -55,7 +56,13 @@ module Dependabot
55
56
  fetched_files << T.must(cargo_config) if cargo_config
56
57
  fetched_files << T.must(rust_toolchain) if rust_toolchain
57
58
  fetched_files += fetch_path_dependency_and_workspace_files
58
- fetched_files.uniq
59
+
60
+ # Filter excluded files from final collection
61
+ filtered_files = fetched_files.reject do |file|
62
+ Dependabot::FileFiltering.should_exclude_path?(file.name, "file from final collection", @exclude_paths)
63
+ end
64
+
65
+ filtered_files.uniq
59
66
  end
60
67
 
61
68
  private
@@ -125,6 +132,8 @@ module Dependabot
125
132
  next if previously_fetched_files.map(&:name).include?(path)
126
133
  next if file.name == path
127
134
 
135
+ next if Dependabot::FileFiltering.should_exclude_path?(path, "file from final collection", @exclude_paths)
136
+
128
137
  fetched_file = fetch_file_from_host(path, fetch_submodules: true)
129
138
  previously_fetched_files << fetched_file
130
139
  grandchild_requirement_files =
@@ -160,6 +169,8 @@ module Dependabot
160
169
  next if previously_fetched_files.map(&:name).include?(path)
161
170
  next if file.name == path
162
171
 
172
+ next if Dependabot::FileFiltering.should_exclude_path?(path, "file from final collection", @exclude_paths)
173
+
163
174
  fetched_file = fetch_file_from_host(path, fetch_submodules: true)
164
175
  .tap { |f| f.support_file = true }
165
176
  previously_fetched_files << fetched_file
@@ -16,6 +16,7 @@ module Dependabot
16
16
  # rubocop:disable Metrics/ClassLength
17
17
  class LockfileUpdater
18
18
  extend T::Sig
19
+
19
20
  LOCKFILE_ENTRY_REGEX = /
20
21
  \[\[package\]\]\n
21
22
  (?:(?!^\[(?:\[package|metadata)).)+
@@ -123,7 +124,7 @@ module Dependabot
123
124
  dependency.version
124
125
  end
125
126
 
126
- if ver && spec_options.count { |s| s.end_with?(ver) } == 1
127
+ if ver && spec_options.one? { |s| s.end_with?(ver) }
127
128
  @custom_specification = spec_options.find { |s| s.end_with?(ver) }
128
129
  return true
129
130
  elsif ver && spec_options.count { |s| s.end_with?(ver) } > 1
@@ -1,22 +1,38 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
5
+
6
+ require "dependabot/dependency"
7
+ require "dependabot/dependency_file"
4
8
  require "dependabot/cargo/file_updater"
5
9
 
6
10
  module Dependabot
7
11
  module Cargo
8
12
  class FileUpdater
9
13
  class ManifestUpdater
14
+ extend T::Sig
15
+
16
+ sig do
17
+ params(
18
+ dependencies: T::Array[Dependabot::Dependency],
19
+ manifest: Dependabot::DependencyFile
20
+ ).void
21
+ end
10
22
  def initialize(dependencies:, manifest:)
11
- @dependencies = dependencies
12
- @manifest = manifest
23
+ @dependencies = T.let(dependencies, T::Array[Dependabot::Dependency])
24
+ @manifest = T.let(manifest, Dependabot::DependencyFile)
13
25
  end
14
26
 
27
+ sig { returns(String) }
15
28
  def updated_manifest_content
29
+ content = manifest.content
30
+ raise "Manifest has no content" if content.nil?
31
+
16
32
  dependencies
17
33
  .select { |dep| requirement_changed?(manifest, dep) }
18
- .reduce(manifest.content.dup) do |content, dep|
19
- updated_content = content
34
+ .reduce(content.dup) do |current_content, dep|
35
+ updated_content = current_content
20
36
 
21
37
  updated_content = update_requirements(
22
38
  content: updated_content,
@@ -30,7 +46,7 @@ module Dependabot
30
46
  dependency: dep
31
47
  )
32
48
 
33
- raise "Expected content to change!" if content == updated_content
49
+ raise "Expected content to change!" if current_content == updated_content
34
50
 
35
51
  updated_content
36
52
  end
@@ -38,42 +54,51 @@ module Dependabot
38
54
 
39
55
  private
40
56
 
57
+ sig { returns(T::Array[Dependabot::Dependency]) }
41
58
  attr_reader :dependencies
59
+
60
+ sig { returns(Dependabot::DependencyFile) }
42
61
  attr_reader :manifest
43
62
 
63
+ sig { params(file: Dependabot::DependencyFile, dependency: Dependabot::Dependency).returns(T::Boolean) }
44
64
  def requirement_changed?(file, dependency)
45
65
  changed_requirements =
46
- dependency.requirements - dependency.previous_requirements
66
+ dependency.requirements - (dependency.previous_requirements || [])
47
67
 
48
68
  changed_requirements.any? { |f| f[:file] == file.name }
49
69
  end
50
70
 
71
+ sig { params(content: String, filename: String, dependency: Dependabot::Dependency).returns(String) }
51
72
  def update_requirements(content:, filename:, dependency:)
52
- updated_content = content.dup
73
+ updated_content = T.let(content.dup, String)
53
74
 
54
75
  # The UpdateChecker ensures the order of requirements is preserved
55
76
  # when updating, so we can zip them together in new/old pairs.
56
77
  reqs = dependency.requirements
57
- .zip(dependency.previous_requirements)
78
+ .zip(dependency.previous_requirements || [])
58
79
  .reject { |new_req, old_req| new_req == old_req }
59
80
 
60
81
  # Loop through each changed requirement
61
82
  reqs.each do |new_req, old_req|
83
+ next if old_req.nil?
84
+
62
85
  raise "Bad req match" unless new_req[:file] == old_req[:file]
63
86
  next if new_req[:requirement] == old_req[:requirement]
64
87
  next unless new_req[:file] == filename
65
88
 
66
- updated_content = update_manifest_req(
67
- content: updated_content,
68
- dep: dependency,
69
- old_req: old_req.fetch(:requirement),
70
- new_req: new_req.fetch(:requirement)
71
- )
89
+ updated_content =
90
+ update_manifest_req(
91
+ content: updated_content,
92
+ dep: dependency,
93
+ old_req: old_req.fetch(:requirement),
94
+ new_req: new_req.fetch(:requirement)
95
+ )
72
96
  end
73
97
 
74
98
  updated_content
75
99
  end
76
100
 
101
+ sig { params(content: String, filename: String, dependency: Dependabot::Dependency).returns(String) }
77
102
  def update_git_pin(content:, filename:, dependency:)
78
103
  updated_pin =
79
104
  dependency.requirements
@@ -82,7 +107,7 @@ module Dependabot
82
107
 
83
108
  old_pin =
84
109
  dependency.previous_requirements
85
- .find { |r| r[:file] == filename }
110
+ &.find { |r| r[:file] == filename }
86
111
  &.dig(:source, :ref)
87
112
 
88
113
  return content unless old_pin
@@ -95,21 +120,31 @@ module Dependabot
95
120
  )
96
121
  end
97
122
 
123
+ sig do
124
+ params(
125
+ content: String,
126
+ dep: Dependabot::Dependency,
127
+ old_req: String,
128
+ new_req: String
129
+ ).returns(String)
130
+ end
98
131
  def update_manifest_req(content:, dep:, old_req:, new_req:)
99
132
  simple_declaration = content.scan(declaration_regex(dep))
100
133
  .find { |m| m.include?(old_req) }
101
134
 
102
135
  if simple_declaration
103
136
  simple_declaration_regex =
104
- /(?:^|["'])#{Regexp.escape(simple_declaration)}/
137
+ /(?:^|["'])#{Regexp.escape(T.cast(simple_declaration, String))}/
105
138
  old_req_escaped = Regexp.escape(old_req)
106
139
  content.gsub(simple_declaration_regex) do |line|
107
140
  line.gsub(/.+=.*\K(#{old_req_escaped})/, new_req)
108
141
  end
109
142
  elsif content.match?(feature_declaration_version_regex(dep))
110
143
  content.gsub(feature_declaration_version_regex(dep)) do |part|
111
- line = content.match(feature_declaration_version_regex(dep))
112
- .named_captures.fetch("version_declaration")
144
+ match_data = content.match(feature_declaration_version_regex(dep))
145
+ line = T.must(match_data).named_captures.fetch("version_declaration")
146
+ return content if line.nil?
147
+
113
148
  new_line = line.gsub(old_req, new_req)
114
149
  part.gsub(line, new_line)
115
150
  end
@@ -118,20 +153,31 @@ module Dependabot
118
153
  end
119
154
  end
120
155
 
156
+ sig do
157
+ params(
158
+ content: String,
159
+ dep: Dependabot::Dependency,
160
+ old_pin: String,
161
+ new_pin: String
162
+ )
163
+ .returns(String)
164
+ end
121
165
  def update_manifest_pin(content:, dep:, old_pin:, new_pin:)
122
166
  simple_declaration = content.scan(declaration_regex(dep))
123
167
  .find { |m| m.include?(old_pin) }
124
168
 
125
169
  if simple_declaration
126
170
  simple_declaration_regex =
127
- /(?:^|["'])#{Regexp.escape(simple_declaration)}/
171
+ /(?:^|["'])#{Regexp.escape(T.cast(simple_declaration, String))}/
128
172
  content.gsub(simple_declaration_regex) do |line|
129
173
  line.gsub(old_pin, new_pin)
130
174
  end
131
175
  elsif content.match?(feature_declaration_pin_regex(dep))
132
176
  content.gsub(feature_declaration_pin_regex(dep)) do |part|
133
- line = content.match(feature_declaration_pin_regex(dep))
134
- .named_captures.fetch("pin_declaration")
177
+ match_data = content.match(feature_declaration_pin_regex(dep))
178
+ line = T.must(match_data).named_captures.fetch("pin_declaration")
179
+ return content if line.nil?
180
+
135
181
  new_line = line.gsub(old_pin, new_pin)
136
182
  part.gsub(line, new_line)
137
183
  end
@@ -140,10 +186,12 @@ module Dependabot
140
186
  end
141
187
  end
142
188
 
189
+ sig { params(dep: Dependabot::Dependency).returns(Regexp) }
143
190
  def declaration_regex(dep)
144
191
  /(?:^|^\s*|["'])#{Regexp.escape(dep.name)}["']?(?:\s*\.version)?\s*=.*$/i
145
192
  end
146
193
 
194
+ sig { params(dep: Dependabot::Dependency).returns(Regexp) }
147
195
  def feature_declaration_version_regex(dep)
148
196
  /
149
197
  #{Regexp.quote("dependencies.#{dep.name}]")}
@@ -152,6 +200,7 @@ module Dependabot
152
200
  /mx
153
201
  end
154
202
 
203
+ sig { params(dep: Dependabot::Dependency).returns(Regexp) }
155
204
  def feature_declaration_pin_regex(dep)
156
205
  /
157
206
  #{Regexp.quote("dependencies.#{dep.name}]")}
@@ -1,7 +1,9 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "excon"
5
+ require "sorbet-runtime"
6
+
5
7
  require "dependabot/metadata_finders"
6
8
  require "dependabot/metadata_finders/base"
7
9
  require "dependabot/registry_client"
@@ -9,11 +11,20 @@ require "dependabot/registry_client"
9
11
  module Dependabot
10
12
  module Cargo
11
13
  class MetadataFinder < Dependabot::MetadataFinders::Base
14
+ extend T::Sig
15
+
12
16
  SOURCE_KEYS = %w(repository homepage documentation).freeze
13
17
  CRATES_IO_API = "https://crates.io/api/v1/crates"
14
18
 
19
+ sig { params(dependency: Dependabot::Dependency, credentials: T::Array[Dependabot::Credential]).void }
20
+ def initialize(dependency:, credentials:)
21
+ super
22
+ @crates_listing = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
23
+ end
24
+
15
25
  private
16
26
 
27
+ sig { override.returns(T.nilable(Dependabot::Source)) }
17
28
  def look_up_source
18
29
  case new_source_type
19
30
  when "default" then find_source_from_crates_listing
@@ -23,19 +34,22 @@ module Dependabot
23
34
  end
24
35
  end
25
36
 
37
+ sig { returns(T.nilable(String)) }
26
38
  def new_source_type
27
39
  dependency.source_type
28
40
  end
29
41
 
42
+ sig { returns(T.nilable(Dependabot::Source)) }
30
43
  def find_source_from_crates_listing
31
44
  potential_source_urls =
32
45
  SOURCE_KEYS
33
- .filter_map { |key| crates_listing.dig("crate", key) }
46
+ .filter_map { |key| T.must(crates_listing).dig("crate", key) }
34
47
 
35
48
  source_url = potential_source_urls.find { |url| Source.from_url(url) }
36
49
  Source.from_url(source_url)
37
50
  end
38
51
 
52
+ sig { returns(T.nilable(Dependabot::Source)) }
39
53
  def find_source_from_git_url
40
54
  info = dependency.requirements.filter_map { |r| r[:source] }.first
41
55
 
@@ -43,6 +57,7 @@ module Dependabot
43
57
  Source.from_url(url)
44
58
  end
45
59
 
60
+ sig { returns(T.nilable(T::Hash[String, T.untyped])) }
46
61
  def crates_listing
47
62
  return @crates_listing unless @crates_listing.nil?
48
63
 
@@ -56,17 +71,21 @@ module Dependabot
56
71
  @crates_listing = parse_response(response, index)
57
72
  end
58
73
 
74
+ sig { params(index: String, info: T.nilable(T::Hash[String, T.untyped])).returns(T::Hash[String, String]) }
59
75
  def build_headers(index, info)
60
76
  hdrs = { "User-Agent" => "Dependabot (dependabot.com)" }
61
77
  return hdrs if index == CRATES_IO_API
62
78
 
63
- credentials.find { |cred| cred["type"] == "cargo_registry" && cred["registry"] == info[:name] }&.tap do |cred|
79
+ return hdrs if info.nil?
80
+
81
+ credentials.find { |cred| cred["type"] == "cargo_registry" && cred["registry"] == info["name"] }&.tap do |cred|
64
82
  hdrs["Authorization"] = "Token #{cred['token']}"
65
83
  end
66
84
 
67
85
  hdrs
68
86
  end
69
87
 
88
+ sig { params(url: String, headers: T::Hash[String, String]).returns(Excon::Response) }
70
89
  def fetch_metadata(url, headers)
71
90
  Excon.get(
72
91
  url,
@@ -75,6 +94,7 @@ module Dependabot
75
94
  )
76
95
  end
77
96
 
97
+ sig { params(response: Excon::Response, index: String).returns(T::Hash[String, T.untyped]) }
78
98
  def parse_response(response, index)
79
99
  if index.start_with?("sparse+")
80
100
  parsed_response = response.body.lines.map { |line| JSON.parse(line) }
@@ -84,6 +104,7 @@ module Dependabot
84
104
  end
85
105
  end
86
106
 
107
+ sig { params(dependency: Dependabot::Dependency, index: String).returns(String) }
87
108
  def metadata_fetch_url(dependency, index)
88
109
  return "#{index}/#{dependency.name}" if index == CRATES_IO_API
89
110
 
@@ -89,7 +89,7 @@ module Dependabot
89
89
  return req_string if parts.count >= 3
90
90
 
91
91
  # If we have no parts then the version is completely unlocked
92
- return ">= 0" if parts.count.zero?
92
+ return ">= 0" if parts.none?
93
93
 
94
94
  # If we have fewer than three parts we do a partial match
95
95
  parts << "0"
@@ -1,7 +1,9 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "toml-rb"
6
+
5
7
  require "dependabot/dependency_file"
6
8
  require "dependabot/cargo/file_parser"
7
9
  require "dependabot/cargo/update_checker"
@@ -12,6 +14,18 @@ module Dependabot
12
14
  # This class takes a set of dependency files and sanitizes them for use
13
15
  # in UpdateCheckers::Rust::Cargo.
14
16
  class FilePreparer
17
+ extend T::Sig
18
+
19
+ sig do
20
+ params(
21
+ dependency_files: T::Array[Dependabot::DependencyFile],
22
+ dependency: Dependabot::Dependency,
23
+ unlock_requirement: T::Boolean,
24
+ replacement_git_pin: T.nilable(String),
25
+ latest_allowable_version: T.nilable(T.any(String, Gem::Version))
26
+ )
27
+ .void
28
+ end
15
29
  def initialize(dependency_files:, dependency:,
16
30
  unlock_requirement: true,
17
31
  replacement_git_pin: nil,
@@ -21,8 +35,13 @@ module Dependabot
21
35
  @unlock_requirement = unlock_requirement
22
36
  @replacement_git_pin = replacement_git_pin
23
37
  @latest_allowable_version = latest_allowable_version
38
+ @lower_bound_version = T.let(nil, T.nilable(T.any(String, Integer)))
39
+ @manifest_files = T.let(nil, T.nilable(T::Array[Dependabot::DependencyFile]))
40
+ @lockfile = T.let(nil, T.nilable(Dependabot::DependencyFile))
41
+ @toolchain = T.let(nil, T.nilable(Dependabot::DependencyFile))
24
42
  end
25
43
 
44
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
26
45
  def prepared_dependency_files
27
46
  files = []
28
47
  files += manifest_files.map do |file|
@@ -39,21 +58,31 @@ module Dependabot
39
58
 
40
59
  private
41
60
 
61
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
42
62
  attr_reader :dependency_files
63
+
64
+ sig { returns(Dependabot::Dependency) }
43
65
  attr_reader :dependency
66
+
67
+ sig { returns(T.nilable(String)) }
44
68
  attr_reader :replacement_git_pin
69
+
70
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
45
71
  attr_reader :latest_allowable_version
46
72
 
73
+ sig { returns(T::Boolean) }
47
74
  def unlock_requirement?
48
75
  @unlock_requirement
49
76
  end
50
77
 
78
+ sig { returns(T::Boolean) }
51
79
  def replace_git_pin?
52
80
  !replacement_git_pin.nil?
53
81
  end
54
82
 
83
+ sig { params(file: Dependabot::DependencyFile).returns(String) }
55
84
  def manifest_content_for_update_check(file)
56
- content = file.content
85
+ content = T.must(file.content)
57
86
 
58
87
  unless file.support_file?
59
88
  content = replace_version_constraint(content, file.name)
@@ -67,6 +96,7 @@ module Dependabot
67
96
 
68
97
  # NOTE: We don't need to care about formatting in this method, since
69
98
  # we're only using the manifest to find the latest resolvable version
99
+ sig { params(content: String, filename: String).returns(String) }
70
100
  def replace_version_constraint(content, filename)
71
101
  parsed_manifest = TomlRB.parse(content)
72
102
 
@@ -89,6 +119,7 @@ module Dependabot
89
119
  TomlRB.dump(parsed_manifest)
90
120
  end
91
121
 
122
+ sig { params(parsed_manifest: T::Hash[String, T.untyped], filename: String).void }
92
123
  def replace_req_on_target_specific_deps!(parsed_manifest, filename)
93
124
  parsed_manifest.fetch("target", {}).each do |target, _|
94
125
  Cargo::FileParser::DEPENDENCY_TYPES.each do |type|
@@ -114,6 +145,7 @@ module Dependabot
114
145
  end
115
146
  end
116
147
 
148
+ sig { params(content: String).returns(String) }
117
149
  def replace_git_pin(content)
118
150
  parsed_manifest = TomlRB.parse(content)
119
151
 
@@ -121,7 +153,7 @@ module Dependabot
121
153
  dependency_names_for_type(parsed_manifest, type).each do |name|
122
154
  req = parsed_manifest.dig(type, name)
123
155
  next unless req.is_a?(Hash)
124
- next unless [req["tag"], req["rev"]].compact.uniq.count == 1
156
+ next unless [req["tag"], req["rev"]].compact.uniq.one?
125
157
 
126
158
  parsed_manifest[type][name]["tag"] = replacement_git_pin if req["tag"]
127
159
 
@@ -134,6 +166,7 @@ module Dependabot
134
166
  TomlRB.dump(parsed_manifest)
135
167
  end
136
168
 
169
+ sig { params(parsed_manifest: T::Hash[String, T.untyped]).void }
137
170
  def replace_git_pin_on_target_specific_deps!(parsed_manifest)
138
171
  parsed_manifest.fetch("target", {}).each do |target, _|
139
172
  Cargo::FileParser::DEPENDENCY_TYPES.each do |type|
@@ -146,7 +179,7 @@ module Dependabot
146
179
  dependency_names.each do |name|
147
180
  req = parsed_manifest.dig("target", target, type, name)
148
181
  next unless req.is_a?(Hash)
149
- next unless [req["tag"], req["rev"]].compact.uniq.count == 1
182
+ next unless [req["tag"], req["rev"]].compact.uniq.one?
150
183
 
151
184
  if req["tag"]
152
185
  parsed_manifest["target"][target][type][name]["tag"] =
@@ -162,6 +195,7 @@ module Dependabot
162
195
  end
163
196
  end
164
197
 
198
+ sig { params(content: String).returns(String) }
165
199
  def replace_ssh_urls(content)
166
200
  parsed_manifest = TomlRB.parse(content)
167
201
 
@@ -178,6 +212,7 @@ module Dependabot
178
212
  TomlRB.dump(parsed_manifest)
179
213
  end
180
214
 
215
+ sig { params(filename: String).returns(String) }
181
216
  def temporary_requirement_for_resolution(filename)
182
217
  original_req = dependency.requirements
183
218
  .find { |r| r.fetch(:file) == filename }
@@ -201,6 +236,7 @@ module Dependabot
201
236
  end
202
237
 
203
238
  # rubocop:disable Metrics/PerceivedComplexity
239
+ sig { returns(T.any(String, Integer)) }
204
240
  def lower_bound_version
205
241
  @lower_bound_version ||=
206
242
  if git_dependency? && git_dependency_version
@@ -221,16 +257,18 @@ module Dependabot
221
257
  end
222
258
  # rubocop:enable Metrics/PerceivedComplexity
223
259
 
260
+ sig { returns(T.nilable(String)) }
224
261
  def git_dependency_version
225
262
  return unless lockfile
226
263
 
227
- TomlRB.parse(lockfile.content)
264
+ TomlRB.parse(T.must(lockfile).content)
228
265
  .fetch("package", [])
229
266
  .select { |p| p["name"] == dependency.name }
230
267
  .find { |p| p["source"].end_with?(dependency.version) }
231
268
  .fetch("version")
232
269
  end
233
270
 
271
+ sig { params(parsed_manifest: T::Hash[String, T.untyped], type: String).returns(T::Array[String]) }
234
272
  def dependency_names_for_type(parsed_manifest, type)
235
273
  names = []
236
274
  parsed_manifest.fetch(type, {}).each do |nm, req|
@@ -241,6 +279,9 @@ module Dependabot
241
279
  names
242
280
  end
243
281
 
282
+ sig do
283
+ params(parsed_manifest: T::Hash[String, T.untyped], type: String, target: String).returns(T::Array[String])
284
+ end
244
285
  def dependency_names_for_type_and_target(parsed_manifest, type, target)
245
286
  names = []
246
287
  (parsed_manifest.dig("target", target, type) || {}).each do |nm, req|
@@ -251,13 +292,16 @@ module Dependabot
251
292
  names
252
293
  end
253
294
 
295
+ sig { params(name: String, declaration: T.untyped).returns(String) }
254
296
  def name_from_declaration(name, declaration)
255
297
  return name if declaration.is_a?(String)
298
+
256
299
  raise "Unexpected dependency declaration: #{declaration}" unless declaration.is_a?(Hash)
257
300
 
258
301
  declaration.fetch("package", name)
259
302
  end
260
303
 
304
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
261
305
  def manifest_files
262
306
  @manifest_files ||=
263
307
  dependency_files.select { |f| f.name.end_with?("Cargo.toml") }
@@ -267,15 +311,18 @@ module Dependabot
267
311
  @manifest_files
268
312
  end
269
313
 
314
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
270
315
  def lockfile
271
316
  @lockfile ||= dependency_files.find { |f| f.name == "Cargo.lock" }
272
317
  end
273
318
 
319
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
274
320
  def toolchain
275
321
  @toolchain ||=
276
322
  dependency_files.find { |f| f.name == "rust-toolchain" }
277
323
  end
278
324
 
325
+ sig { returns(T::Boolean) }
279
326
  def git_dependency?
280
327
  GitCommitChecker
281
328
  .new(dependency: dependency, credentials: [])
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  ################################################################################
@@ -25,26 +25,35 @@ module Dependabot
25
25
  VERSION_REGEX = /[0-9]+(?:\.[A-Za-z0-9\-*]+)*/
26
26
  ALLOWED_UPDATE_STRATEGIES = T.let(
27
27
  [
28
- RequirementsUpdateStrategy::LockfileOnly,
29
- RequirementsUpdateStrategy::BumpVersions,
30
- RequirementsUpdateStrategy::BumpVersionsIfNecessary
28
+ Dependabot::RequirementsUpdateStrategy::LockfileOnly,
29
+ Dependabot::RequirementsUpdateStrategy::BumpVersions,
30
+ Dependabot::RequirementsUpdateStrategy::BumpVersionsIfNecessary
31
31
  ].freeze,
32
32
  T::Array[Dependabot::RequirementsUpdateStrategy]
33
33
  )
34
34
 
35
+ sig do
36
+ params(
37
+ requirements: T::Array[T::Hash[Symbol, T.untyped]],
38
+ updated_source: T.nilable(T::Hash[T.any(String, Symbol), T.untyped]),
39
+ update_strategy: Dependabot::RequirementsUpdateStrategy,
40
+ target_version: T.nilable(T.any(String, Gem::Version))
41
+ ).void
42
+ end
35
43
  def initialize(requirements:, updated_source:, update_strategy:,
36
44
  target_version:)
37
- @requirements = requirements
38
- @updated_source = updated_source
39
- @update_strategy = update_strategy
45
+ @requirements = T.let(requirements, T::Array[T::Hash[Symbol, T.untyped]])
46
+ @updated_source = T.let(updated_source, T.nilable(T::Hash[T.any(String, Symbol), T.untyped]))
47
+ @update_strategy = T.let(update_strategy, Dependabot::RequirementsUpdateStrategy)
40
48
 
41
49
  check_update_strategy
42
50
 
43
51
  return unless target_version && version_class.correct?(target_version)
44
52
 
45
- @target_version = version_class.new(target_version)
53
+ @target_version = T.let(version_class.new(target_version), Gem::Version)
46
54
  end
47
55
 
56
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
48
57
  def updated_requirements
49
58
  return requirements if update_strategy.lockfile_only?
50
59
 
@@ -57,7 +66,7 @@ module Dependabot
57
66
  next req if req[:requirement].nil?
58
67
 
59
68
  # TODO: Add a RequirementsUpdateStrategy::WidenRanges options
60
- if update_strategy == RequirementsUpdateStrategy::BumpVersionsIfNecessary
69
+ if update_strategy == Dependabot::RequirementsUpdateStrategy::BumpVersionsIfNecessary
61
70
  update_version_requirement_if_needed(req)
62
71
  else
63
72
  update_version_requirement(req)
@@ -67,17 +76,26 @@ module Dependabot
67
76
 
68
77
  private
69
78
 
79
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
70
80
  attr_reader :requirements
81
+
82
+ sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.untyped])) }
71
83
  attr_reader :updated_source
84
+
85
+ sig { returns(Dependabot::RequirementsUpdateStrategy) }
72
86
  attr_reader :update_strategy
87
+
88
+ sig { returns(T.nilable(Gem::Version)) }
73
89
  attr_reader :target_version
74
90
 
91
+ sig { void }
75
92
  def check_update_strategy
76
93
  return if ALLOWED_UPDATE_STRATEGIES.include?(update_strategy)
77
94
 
78
95
  raise "Unknown update strategy: #{update_strategy}"
79
96
  end
80
97
 
98
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
81
99
  def update_version_requirement(req)
82
100
  string_reqs = req[:requirement].split(",").map(&:strip)
83
101
 
@@ -100,15 +118,17 @@ module Dependabot
100
118
  req.merge(requirement: new_requirement)
101
119
  end
102
120
 
121
+ sig { params(req: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
103
122
  def update_version_requirement_if_needed(req)
104
123
  string_reqs = req[:requirement].split(",").map(&:strip)
105
- ruby_reqs = string_reqs.map { |r| Cargo::Requirement.new(r) }
124
+ ruby_reqs = string_reqs.map { |r| Dependabot::Cargo::Requirement.new(r) }
106
125
 
107
126
  return req if ruby_reqs.all? { |r| r.satisfied_by?(target_version) }
108
127
 
109
128
  update_version_requirement(req)
110
129
  end
111
130
 
131
+ sig { params(req_string: String).returns(String) }
112
132
  def update_version_string(req_string)
113
133
  new_target_parts = target_version.to_s.sub(/\+.*/, "").split(".")
114
134
  req_string.sub(VERSION_REGEX) do |old_version|
@@ -123,19 +143,22 @@ module Dependabot
123
143
  end
124
144
  end
125
145
 
146
+ sig { params(string_reqs: T::Array[String]).returns(T.nilable(String)) }
126
147
  def non_range_req(string_reqs)
127
148
  string_reqs.find { |r| r.include?("*") || r.match?(/^[\d~^]/) }
128
149
  end
129
150
 
151
+ sig { params(string_reqs: T::Array[String]).returns(T.nilable(String)) }
130
152
  def exact_req(string_reqs)
131
- string_reqs.find { |r| Cargo::Requirement.new(r).exact? }
153
+ string_reqs.find { |r| Dependabot::Cargo::Requirement.new(r).exact? }
132
154
  end
133
155
 
156
+ sig { params(string_reqs: T::Array[String]).returns(T.any(String, Symbol)) }
134
157
  def update_range_requirements(string_reqs)
135
158
  string_reqs.map do |req|
136
159
  next req unless req.match?(/[<>]/)
137
160
 
138
- ruby_req = Cargo::Requirement.new(req)
161
+ ruby_req = Dependabot::Cargo::Requirement.new(req)
139
162
  next req if ruby_req.satisfied_by?(target_version)
140
163
 
141
164
  raise UnfixableRequirement if req.start_with?(">")
@@ -144,7 +167,7 @@ module Dependabot
144
167
  if req.start_with?("<=")
145
168
  update_version_string(old_version)
146
169
  else
147
- update_greatest_version(old_version, target_version)
170
+ update_greatest_version(old_version, T.must(target_version))
148
171
  end
149
172
  end
150
173
  end.join(", ")
@@ -152,26 +175,28 @@ module Dependabot
152
175
  :unfixable
153
176
  end
154
177
 
178
+ sig { params(old_version: String, version_to_be_permitted: Gem::Version).returns(String) }
155
179
  def update_greatest_version(old_version, version_to_be_permitted)
156
180
  version = version_class.new(old_version)
157
181
  version = version.release if version.prerelease?
158
182
 
159
183
  index_to_update =
160
- version.segments.map.with_index { |seg, i| seg.zero? ? 0 : i }.max
184
+ version.segments.map.with_index { |seg, i| seg.to_i.zero? ? 0 : i }.max
161
185
 
162
186
  version.segments.map.with_index do |_, index|
163
187
  if index < index_to_update
164
188
  version_to_be_permitted.segments[index]
165
189
  elsif index == index_to_update
166
- version_to_be_permitted.segments[index] + 1
190
+ version_to_be_permitted.segments[index].to_i + 1
167
191
  else
168
192
  0
169
193
  end
170
194
  end.join(".")
171
195
  end
172
196
 
197
+ sig { returns(T.class_of(Dependabot::Cargo::Version)) }
173
198
  def version_class
174
- Cargo::Version
199
+ Dependabot::Cargo::Version
175
200
  end
176
201
  end
177
202
  end
@@ -14,6 +14,7 @@ module Dependabot
14
14
  class UpdateChecker
15
15
  class VersionResolver # rubocop:disable Metrics/ClassLength
16
16
  extend T::Sig
17
+
17
18
  UNABLE_TO_UPDATE = /Unable to update (?<url>.*?)$/
18
19
  BRANCH_NOT_FOUND_REGEX = /#{UNABLE_TO_UPDATE}.*to find branch `(?<branch>[^`]+)`/m
19
20
  REVSPEC_PATTERN = /revspec '.*' not found/
@@ -133,7 +134,7 @@ module Dependabot
133
134
  dependency.version
134
135
  end
135
136
 
136
- if spec_options.count { |s| s.end_with?(T.must(ver)) } == 1
137
+ if spec_options.one? { |s| s.end_with?(T.must(ver)) }
137
138
  @custom_specification = spec_options.find { |s| s.end_with?(T.must(ver)) }
138
139
  return true
139
140
  elsif spec_options.count { |s| s.end_with?(T.must(ver)) } > 1
@@ -1,6 +1,8 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
5
+
4
6
  require "dependabot/git_commit_checker"
5
7
  require "dependabot/requirements_update_strategy"
6
8
  require "dependabot/update_checkers"
@@ -9,15 +11,18 @@ require "dependabot/update_checkers/base"
9
11
  module Dependabot
10
12
  module Cargo
11
13
  class UpdateChecker < Dependabot::UpdateCheckers::Base
14
+ extend T::Sig
15
+
12
16
  require_relative "update_checker/latest_version_finder"
13
17
  require_relative "update_checker/requirements_updater"
14
18
  require_relative "update_checker/version_resolver"
15
19
  require_relative "update_checker/file_preparer"
16
20
 
21
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
17
22
  def latest_version
18
23
  return if path_dependency?
19
24
 
20
- @latest_version =
25
+ @latest_version = T.let(
21
26
  if git_dependency?
22
27
  latest_version_for_git_dependency
23
28
  elsif git_subdependency?
@@ -26,48 +31,64 @@ module Dependabot
26
31
  nil
27
32
  else
28
33
  latest_version_finder.latest_version
29
- end
34
+ end,
35
+ T.nilable(T.any(String, Gem::Version))
36
+ )
30
37
  end
31
38
 
39
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
32
40
  def latest_resolvable_version
33
41
  return if path_dependency?
34
42
 
35
- @latest_resolvable_version ||=
36
- if git_dependency?
37
- latest_resolvable_version_for_git_dependency
38
- elsif git_subdependency?
39
- # TODO: Dependabot can't update git sub-dependencies yet, because
40
- # they can't be passed to GitCommitChecker.
41
- nil
42
- else
43
- fetch_latest_resolvable_version(unlock_requirement: true)
44
- end
43
+ @latest_resolvable_version = T.let(
44
+ @latest_resolvable_version ||
45
+ if git_dependency?
46
+ latest_resolvable_version_for_git_dependency
47
+ elsif git_subdependency?
48
+ # TODO: Dependabot can't update git sub-dependencies yet, because
49
+ # they can't be passed to GitCommitChecker.
50
+ nil
51
+ else
52
+ fetch_latest_resolvable_version(unlock_requirement: true)
53
+ end,
54
+ T.nilable(T.any(String, Gem::Version))
55
+ )
45
56
  end
46
57
 
58
+ sig { override.returns(T.nilable(Gem::Version)) }
47
59
  def lowest_security_fix_version
48
60
  latest_version_finder.lowest_security_fix_version
49
61
  end
50
62
 
63
+ sig { override.returns(T.nilable(Gem::Version)) }
51
64
  def lowest_resolvable_security_fix_version
52
65
  raise "Dependency not vulnerable!" unless vulnerable?
53
66
 
54
67
  return @lowest_resolvable_security_fix_version if defined?(@lowest_resolvable_security_fix_version)
55
68
 
56
- @lowest_resolvable_security_fix_version =
57
- fetch_lowest_resolvable_security_fix_version
69
+ result = fetch_lowest_resolvable_security_fix_version
70
+ @lowest_resolvable_security_fix_version = T.let(
71
+ result.is_a?(Gem::Version) ? result : nil,
72
+ T.nilable(Gem::Version)
73
+ )
58
74
  end
59
75
 
76
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
60
77
  def latest_resolvable_version_with_no_unlock
61
78
  return if path_dependency?
62
79
 
63
- @latest_resolvable_version_with_no_unlock ||=
64
- if git_dependency?
65
- latest_resolvable_commit_with_unchanged_git_source
66
- else
67
- fetch_latest_resolvable_version(unlock_requirement: false)
68
- end
80
+ @latest_resolvable_version_with_no_unlock = T.let(
81
+ @latest_resolvable_version_with_no_unlock ||
82
+ if git_dependency?
83
+ latest_resolvable_commit_with_unchanged_git_source
84
+ else
85
+ fetch_latest_resolvable_version(unlock_requirement: false)
86
+ end,
87
+ T.nilable(T.any(String, Gem::Version))
88
+ )
69
89
  end
70
90
 
91
+ sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
71
92
  def updated_requirements
72
93
  RequirementsUpdater.new(
73
94
  requirements: dependency.requirements,
@@ -77,10 +98,12 @@ module Dependabot
77
98
  ).updated_requirements
78
99
  end
79
100
 
101
+ sig { override.returns(T::Boolean) }
80
102
  def requirements_unlocked_or_can_be?
81
103
  !requirements_update_strategy.lockfile_only?
82
104
  end
83
105
 
106
+ sig { returns(Dependabot::RequirementsUpdateStrategy) }
84
107
  def requirements_update_strategy
85
108
  # If passed in as an option (in the base class) honour that option
86
109
  return @requirements_update_strategy if @requirements_update_strategy
@@ -91,15 +114,18 @@ module Dependabot
91
114
 
92
115
  private
93
116
 
117
+ sig { override.returns(T::Boolean) }
94
118
  def latest_version_resolvable_with_full_unlock?
95
119
  # Full unlock checks aren't implemented for Rust (yet)
96
120
  false
97
121
  end
98
122
 
123
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
99
124
  def updated_dependencies_after_full_unlock
100
125
  raise NotImplementedError
101
126
  end
102
127
 
128
+ sig { returns(T.nilable(String)) }
103
129
  def target_version
104
130
  # Unless we can resolve a new version, don't try to update to a latest
105
131
  # version (even for a library) as we rely on a resolvable version being
@@ -109,29 +135,37 @@ module Dependabot
109
135
  library? ? latest_version&.to_s : preferred_resolvable_version.to_s
110
136
  end
111
137
 
138
+ sig { returns(T::Boolean) }
112
139
  def library?
113
140
  # If it has a lockfile, treat it as an application. Otherwise treat it
114
141
  # as a library.
115
142
  dependency_files.none? { |f| f.name == "Cargo.lock" }
116
143
  end
117
144
 
145
+ sig { returns(LatestVersionFinder) }
118
146
  def latest_version_finder
119
- @latest_version_finder ||=
120
- LatestVersionFinder.new(
121
- dependency: dependency,
122
- dependency_files: dependency_files,
123
- credentials: credentials,
124
- ignored_versions: ignored_versions,
125
- security_advisories: security_advisories,
126
- cooldown_options: update_cooldown,
127
- raise_on_ignored: raise_on_ignored
128
- )
147
+ @latest_version_finder = T.let(
148
+ @latest_version_finder ||
149
+ LatestVersionFinder.new(
150
+ dependency: dependency,
151
+ dependency_files: dependency_files,
152
+ credentials: credentials,
153
+ ignored_versions: ignored_versions,
154
+ security_advisories: security_advisories,
155
+ cooldown_options: update_cooldown,
156
+ raise_on_ignored: raise_on_ignored
157
+ ),
158
+ T.nilable(LatestVersionFinder)
159
+ )
160
+ T.must(@latest_version_finder)
129
161
  end
130
162
 
163
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
131
164
  def latest_version_for_git_dependency
132
165
  latest_git_version_sha
133
166
  end
134
167
 
168
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
135
169
  def latest_git_version_sha
136
170
  # If the gem isn't pinned, the latest version is just the latest
137
171
  # commit for the specified branch.
@@ -150,6 +184,7 @@ module Dependabot
150
184
  dependency.version
151
185
  end
152
186
 
187
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
153
188
  def latest_resolvable_version_for_git_dependency
154
189
  # If the gem isn't pinned, the latest version is just the latest
155
190
  # commit for the specified branch.
@@ -161,21 +196,28 @@ module Dependabot
161
196
  if git_commit_checker.pinned_ref_looks_like_version? &&
162
197
  latest_git_tag_is_resolvable?
163
198
  new_tag = git_commit_checker.local_tag_for_latest_version
164
- return new_tag.fetch(:commit_sha)
199
+ return T.must(new_tag).fetch(:commit_sha)
165
200
  end
166
201
 
167
202
  # If the dependency is pinned then there's nothing we can do.
168
203
  dependency.version
169
204
  end
170
205
 
206
+ sig { returns(T::Boolean) }
171
207
  def latest_git_tag_is_resolvable?
172
- return @git_tag_resolvable if @latest_git_tag_is_resolvable_checked
208
+ unless defined?(@latest_git_tag_is_resolvable_checked)
209
+ @latest_git_tag_is_resolvable_checked = T.let(nil,
210
+ T.nilable(T::Boolean))
211
+ end
212
+ @git_tag_resolvable = T.let(nil, T.nilable(T::Boolean)) unless defined?(@git_tag_resolvable)
213
+
214
+ return T.must(@git_tag_resolvable) if @latest_git_tag_is_resolvable_checked
173
215
 
174
216
  @latest_git_tag_is_resolvable_checked = true
175
217
 
176
218
  return false if git_commit_checker.local_tag_for_latest_version.nil?
177
219
 
178
- replacement_tag = git_commit_checker.local_tag_for_latest_version
220
+ replacement_tag = T.must(git_commit_checker.local_tag_for_latest_version)
179
221
 
180
222
  prepared_files = FilePreparer.new(
181
223
  dependency_files: dependency_files,
@@ -197,6 +239,7 @@ module Dependabot
197
239
  @git_tag_resolvable = false
198
240
  end
199
241
 
242
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
200
243
  def latest_resolvable_commit_with_unchanged_git_source
201
244
  fetch_latest_resolvable_version(unlock_requirement: false)
202
245
  rescue SharedHelpers::HelperSubprocessFailed => e
@@ -207,6 +250,7 @@ module Dependabot
207
250
  raise e
208
251
  end
209
252
 
253
+ sig { params(unlock_requirement: T::Boolean).returns(T.nilable(T.any(String, Gem::Version))) }
210
254
  def fetch_latest_resolvable_version(unlock_requirement:)
211
255
  prepared_files = FilePreparer.new(
212
256
  dependency_files: dependency_files,
@@ -223,6 +267,7 @@ module Dependabot
223
267
  ).latest_resolvable_version
224
268
  end
225
269
 
270
+ sig { returns(T.nilable(T.any(String, Gem::Version))) }
226
271
  def fetch_lowest_resolvable_security_fix_version
227
272
  fix_version = lowest_security_fix_version
228
273
  return latest_resolvable_version if fix_version.nil?
@@ -248,6 +293,7 @@ module Dependabot
248
293
  latest_resolvable_version
249
294
  end
250
295
 
296
+ sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.untyped])) }
251
297
  def updated_source
252
298
  # Never need to update source, unless a git_dependency
253
299
  return dependency_source_details unless git_dependency?
@@ -255,38 +301,47 @@ module Dependabot
255
301
  # Update the git tag if updating a pinned version
256
302
  if git_commit_checker.pinned_ref_looks_like_version? &&
257
303
  latest_git_tag_is_resolvable?
258
- new_tag = git_commit_checker.local_tag_for_latest_version
259
- return dependency_source_details.merge(ref: new_tag.fetch(:tag))
304
+ new_tag = T.must(git_commit_checker.local_tag_for_latest_version)
305
+ return T.must(dependency_source_details).merge(ref: new_tag.fetch(:tag))
260
306
  end
261
307
 
262
308
  # Otherwise return the original source
263
309
  dependency_source_details
264
310
  end
265
311
 
312
+ sig { returns(T.nilable(T::Hash[T.any(String, Symbol), T.untyped])) }
266
313
  def dependency_source_details
267
314
  dependency.source_details
268
315
  end
269
316
 
317
+ sig { returns(T::Boolean) }
270
318
  def git_dependency?
271
319
  git_commit_checker.git_dependency?
272
320
  end
273
321
 
322
+ sig { returns(T::Boolean) }
274
323
  def git_subdependency?
275
324
  return false if dependency.top_level?
276
325
 
277
326
  !version_class.correct?(dependency.version)
278
327
  end
279
328
 
329
+ sig { returns(T::Boolean) }
280
330
  def path_dependency?
281
331
  dependency.source_type == "path"
282
332
  end
283
333
 
334
+ sig { returns(GitCommitChecker) }
284
335
  def git_commit_checker
285
- @git_commit_checker ||=
286
- GitCommitChecker.new(
287
- dependency: dependency,
288
- credentials: credentials
289
- )
336
+ @git_commit_checker = T.let(
337
+ @git_commit_checker ||
338
+ GitCommitChecker.new(
339
+ dependency: dependency,
340
+ credentials: credentials
341
+ ),
342
+ T.nilable(GitCommitChecker)
343
+ )
344
+ T.must(@git_commit_checker)
290
345
  end
291
346
  end
292
347
  end
@@ -1,6 +1,7 @@
1
- # typed: true
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "dependabot/version"
5
6
  require "dependabot/utils"
6
7
 
@@ -11,26 +12,32 @@ require "dependabot/utils"
11
12
  module Dependabot
12
13
  module Cargo
13
14
  class Version < Dependabot::Version
15
+ extend T::Sig
16
+
14
17
  VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*' \
15
18
  '(-[0-9A-Za-z-]+(\.[0-9a-zA-Z-]+)*)?' \
16
19
  '(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?'
17
20
  ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/
18
21
 
22
+ sig { override.params(version: VersionParameter).void }
19
23
  def initialize(version)
20
- @version_string = version.to_s
24
+ @version_string = T.let(version.to_s, String)
21
25
  version = version.to_s.split("+").first if version.to_s.include?("+")
22
26
 
23
27
  super
24
28
  end
25
29
 
30
+ sig { override.returns(String) }
26
31
  def to_s
27
32
  @version_string
28
33
  end
29
34
 
35
+ sig { override.returns(String) }
30
36
  def inspect # :nodoc:
31
37
  "#<#{self.class} #{@version_string}>"
32
38
  end
33
39
 
40
+ sig { override.params(version: VersionParameter).returns(T::Boolean) }
34
41
  def self.correct?(version)
35
42
  return false if version.nil?
36
43
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-cargo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.332.0
4
+ version: 0.333.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.332.0
18
+ version: 0.333.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.332.0
25
+ version: 0.333.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -211,14 +211,14 @@ dependencies:
211
211
  requirements:
212
212
  - - "~>"
213
213
  - !ruby/object:Gem::Version
214
- version: '3.18'
214
+ version: '3.25'
215
215
  type: :development
216
216
  prerelease: false
217
217
  version_requirements: !ruby/object:Gem::Requirement
218
218
  requirements:
219
219
  - - "~>"
220
220
  - !ruby/object:Gem::Version
221
- version: '3.18'
221
+ version: '3.25'
222
222
  - !ruby/object:Gem::Dependency
223
223
  name: webrick
224
224
  requirement: !ruby/object:Gem::Requirement
@@ -266,7 +266,7 @@ licenses:
266
266
  - MIT
267
267
  metadata:
268
268
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
269
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.332.0
269
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.333.0
270
270
  rdoc_options: []
271
271
  require_paths:
272
272
  - lib