dependabot-cargo 0.325.0 → 0.326.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 +4 -4
- data/lib/dependabot/cargo/file_parser.rb +83 -35
- data/lib/dependabot/cargo/update_checker/version_resolver.rb +101 -47
- metadata +4 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 65f2f1c55ac562ad6abef01b525db3cbb33619731e81c0a076e3b568534fc113
         | 
| 4 | 
            +
              data.tar.gz: b4b855731c6b90017d6a5a8edc77adaded62251983b94ccd0c772733bd5e57dd
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 98f0de7da1e05b555a23953c5e3e23253fe62c0a6e9f17e0cc87a0a9c8028cf5d787189bf1436e908922fddb4cf04383fb113c0fae95f487ed40995c6f79a31e
         | 
| 7 | 
            +
              data.tar.gz: bf20aa8c3ce3317ebb2588f320400abb6857db6b40dbb61a8e7897722bda77f11a44adb76bdd6319ffb1fcca7b8405c0584111bb7c03d7caa9e52d95c45912b2
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # typed:  | 
| 1 | 
            +
            # typed: strict
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 3 |  | 
| 4 4 | 
             
            require "toml-rb"
         | 
| @@ -25,6 +25,7 @@ module Dependabot | |
| 25 25 | 
             
                  DEPENDENCY_TYPES =
         | 
| 26 26 | 
             
                    %w(dependencies dev-dependencies build-dependencies).freeze
         | 
| 27 27 |  | 
| 28 | 
            +
                  sig { override.returns(T::Array[Dependabot::Dependency]) }
         | 
| 28 29 | 
             
                  def parse
         | 
| 29 30 | 
             
                    check_rust_workspace_root
         | 
| 30 31 |  | 
| @@ -88,10 +89,14 @@ module Dependabot | |
| 88 89 | 
             
                    end, T.nilable(String))
         | 
| 89 90 | 
             
                  end
         | 
| 90 91 |  | 
| 92 | 
            +
                  sig { void }
         | 
| 91 93 | 
             
                  def check_rust_workspace_root
         | 
| 92 94 | 
             
                    cargo_toml = dependency_files.find { |f| f.name == "Cargo.toml" }
         | 
| 93 | 
            -
                    workspace_root = parsed_file( | 
| 94 | 
            -
                    return unless workspace_root
         | 
| 95 | 
            +
                    workspace_root = parsed_file(T.must(cargo_toml))
         | 
| 96 | 
            +
                    return unless workspace_root.is_a?(Hash)
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                    workspace_config = workspace_root.dig("package", "workspace")
         | 
| 99 | 
            +
                    return unless workspace_config
         | 
| 95 100 |  | 
| 96 101 | 
             
                    msg = "This project is part of a Rust workspace but is not the " \
         | 
| 97 102 | 
             
                          "workspace root." \
         | 
| @@ -106,19 +111,23 @@ module Dependabot | |
| 106 111 | 
             
                  # rubocop:disable Metrics/AbcSize
         | 
| 107 112 | 
             
                  # rubocop:disable Metrics/CyclomaticComplexity
         | 
| 108 113 | 
             
                  # rubocop:disable Metrics/PerceivedComplexity
         | 
| 114 | 
            +
                  sig { returns(DependencySet) }
         | 
| 109 115 | 
             
                  def manifest_dependencies
         | 
| 110 116 | 
             
                    dependency_set = DependencySet.new
         | 
| 111 117 |  | 
| 112 118 | 
             
                    manifest_files.each do |file|
         | 
| 119 | 
            +
                      parsed_content = parsed_file(file)
         | 
| 120 | 
            +
                      next unless parsed_content.is_a?(Hash)
         | 
| 121 | 
            +
             | 
| 113 122 | 
             
                      DEPENDENCY_TYPES.each do |type|
         | 
| 114 | 
            -
                         | 
| 123 | 
            +
                        parsed_content.fetch(type, {}).each do |name, requirement|
         | 
| 115 124 | 
             
                          next unless name == name_from_declaration(name, requirement)
         | 
| 116 125 | 
             
                          next if lockfile && !version_from_lockfile(name, requirement)
         | 
| 117 126 |  | 
| 118 127 | 
             
                          dependency_set << build_dependency(name, requirement, type, file)
         | 
| 119 128 | 
             
                        end
         | 
| 120 129 |  | 
| 121 | 
            -
                         | 
| 130 | 
            +
                        parsed_content.fetch("target", {}).each do |_, t_details|
         | 
| 122 131 | 
             
                          t_details.fetch(type, {}).each do |name, requirement|
         | 
| 123 132 | 
             
                            next unless name == name_from_declaration(name, requirement)
         | 
| 124 133 | 
             
                            next if lockfile && !version_from_lockfile(name, requirement)
         | 
| @@ -129,7 +138,7 @@ module Dependabot | |
| 129 138 | 
             
                        end
         | 
| 130 139 | 
             
                      end
         | 
| 131 140 |  | 
| 132 | 
            -
                      workspace =  | 
| 141 | 
            +
                      workspace = parsed_content.fetch("workspace", {})
         | 
| 133 142 | 
             
                      workspace.fetch("dependencies", {}).each do |name, requirement|
         | 
| 134 143 | 
             
                        next unless name == name_from_declaration(name, requirement)
         | 
| 135 144 | 
             
                        next if lockfile && !version_from_lockfile(name, requirement)
         | 
| @@ -145,6 +154,10 @@ module Dependabot | |
| 145 154 | 
             
                  # rubocop:enable Metrics/CyclomaticComplexity
         | 
| 146 155 | 
             
                  # rubocop:enable Metrics/PerceivedComplexity
         | 
| 147 156 |  | 
| 157 | 
            +
                  sig do
         | 
| 158 | 
            +
                    params(name: String, requirement: T.any(String, T::Hash[String, String]), type: String,
         | 
| 159 | 
            +
                           file: Dependabot::DependencyFile).returns(Dependency)
         | 
| 160 | 
            +
                  end
         | 
| 148 161 | 
             
                  def build_dependency(name, requirement, type, file)
         | 
| 149 162 | 
             
                    Dependency.new(
         | 
| 150 163 | 
             
                      name: name,
         | 
| @@ -159,11 +172,15 @@ module Dependabot | |
| 159 172 | 
             
                    )
         | 
| 160 173 | 
             
                  end
         | 
| 161 174 |  | 
| 175 | 
            +
                  sig { returns(DependencySet) }
         | 
| 162 176 | 
             
                  def lockfile_dependencies
         | 
| 163 177 | 
             
                    dependency_set = DependencySet.new
         | 
| 164 178 | 
             
                    return dependency_set unless lockfile
         | 
| 165 179 |  | 
| 166 | 
            -
                    parsed_file( | 
| 180 | 
            +
                    lockfile_content = parsed_file(T.must(lockfile))
         | 
| 181 | 
            +
                    return dependency_set unless lockfile_content.is_a?(Hash)
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                    lockfile_content.fetch("package", []).each do |package_details|
         | 
| 167 184 | 
             
                      next unless package_details["source"]
         | 
| 168 185 |  | 
| 169 186 | 
             
                      # TODO: This isn't quite right, as it will only give us one
         | 
| @@ -179,40 +196,49 @@ module Dependabot | |
| 179 196 | 
             
                    dependency_set
         | 
| 180 197 | 
             
                  end
         | 
| 181 198 |  | 
| 199 | 
            +
                  sig { returns(T::Array[String]) }
         | 
| 182 200 | 
             
                  def patched_dependencies
         | 
| 183 201 | 
             
                    root_manifest = manifest_files.find { |f| f.name == "Cargo.toml" }
         | 
| 184 | 
            -
                     | 
| 202 | 
            +
                    parsed_content = parsed_file(T.must(root_manifest))
         | 
| 203 | 
            +
                    return [] unless parsed_content.is_a?(Hash)
         | 
| 204 | 
            +
                    return [] unless parsed_content["patch"]
         | 
| 185 205 |  | 
| 186 | 
            -
                     | 
| 206 | 
            +
                    parsed_content["patch"].values.flat_map(&:keys)
         | 
| 187 207 | 
             
                  end
         | 
| 188 208 |  | 
| 209 | 
            +
                  sig { params(declaration: T.any(String, T::Hash[String, String])).returns(T.nilable(String)) }
         | 
| 189 210 | 
             
                  def requirement_from_declaration(declaration)
         | 
| 190 211 | 
             
                    if declaration.is_a?(String)
         | 
| 191 | 
            -
                       | 
| 192 | 
            -
                     | 
| 193 | 
            -
             | 
| 194 | 
            -
                    return declaration["version"] if declaration["version"].is_a?(String) && declaration["version"] != ""
         | 
| 212 | 
            +
                      declaration == "" ? nil : declaration
         | 
| 213 | 
            +
                    else
         | 
| 214 | 
            +
                      return declaration["version"] if declaration["version"].is_a?(String) && declaration["version"] != ""
         | 
| 195 215 |  | 
| 196 | 
            -
             | 
| 216 | 
            +
                      nil
         | 
| 217 | 
            +
                    end
         | 
| 197 218 | 
             
                  end
         | 
| 198 219 |  | 
| 220 | 
            +
                  sig { params(name: String, declaration: T.any(String, T::Hash[String, String])).returns(String) }
         | 
| 199 221 | 
             
                  def name_from_declaration(name, declaration)
         | 
| 200 | 
            -
                     | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 222 | 
            +
                    if declaration.is_a?(String)
         | 
| 223 | 
            +
                      name
         | 
| 224 | 
            +
                    else
         | 
| 225 | 
            +
                      declaration.fetch("package", name)
         | 
| 226 | 
            +
                    end
         | 
| 204 227 | 
             
                  end
         | 
| 205 228 |  | 
| 229 | 
            +
                  sig { params(declaration: T.any(String, T::Hash[String, String])).returns(T.nilable(T::Hash[Symbol, String])) }
         | 
| 206 230 | 
             
                  def source_from_declaration(declaration)
         | 
| 207 | 
            -
                     | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 211 | 
            -
             | 
| 231 | 
            +
                    if declaration.is_a?(String)
         | 
| 232 | 
            +
                      nil
         | 
| 233 | 
            +
                    else
         | 
| 234 | 
            +
                      return git_source_details(declaration) if declaration["git"]
         | 
| 235 | 
            +
                      return { type: "path" } if declaration["path"]
         | 
| 212 236 |  | 
| 213 | 
            -
             | 
| 237 | 
            +
                      registry_source_details(declaration)
         | 
| 238 | 
            +
                    end
         | 
| 214 239 | 
             
                  end
         | 
| 215 240 |  | 
| 241 | 
            +
                  sig { params(declaration: T.any(String, T::Hash[String, String])).returns(T.nilable(T::Hash[Symbol, String])) }
         | 
| 216 242 | 
             
                  def registry_source_details(declaration)
         | 
| 217 243 | 
             
                    registry_name = declaration["registry"]
         | 
| 218 244 | 
             
                    return if registry_name.nil?
         | 
| @@ -242,6 +268,7 @@ module Dependabot | |
| 242 268 | 
             
                    end
         | 
| 243 269 | 
             
                  end
         | 
| 244 270 |  | 
| 271 | 
            +
                  sig { params(registry_name: String, index_url: String).returns(T::Hash[Symbol, String]) }
         | 
| 245 272 | 
             
                  def sparse_registry_source_details(registry_name, index_url)
         | 
| 246 273 | 
             
                    token = credentials.find do |cred|
         | 
| 247 274 | 
             
                      cred["type"] == "cargo_registry" && cred["registry"] == registry_name
         | 
| @@ -268,25 +295,35 @@ module Dependabot | |
| 268 295 |  | 
| 269 296 | 
             
                  # Looks up dotted key name in cargo config
         | 
| 270 297 | 
             
                  # e.g. "registries.my_registry.index"
         | 
| 298 | 
            +
                  sig { params(key_name: String).returns(T.nilable(String)) }
         | 
| 271 299 | 
             
                  def cargo_config_field(key_name)
         | 
| 272 300 | 
             
                    cargo_config_from_env(key_name) || cargo_config_from_file(key_name)
         | 
| 273 301 | 
             
                  end
         | 
| 274 302 |  | 
| 303 | 
            +
                  sig { params(key_name: String).returns(T.nilable(String)) }
         | 
| 275 304 | 
             
                  def cargo_config_from_env(key_name)
         | 
| 276 305 | 
             
                    env_var = "CARGO_#{key_name.upcase.tr('-.', '_')}"
         | 
| 277 306 | 
             
                    ENV.fetch(env_var, nil)
         | 
| 278 307 | 
             
                  end
         | 
| 279 308 |  | 
| 309 | 
            +
                  sig { params(key_name: String).returns(T.nilable(String)) }
         | 
| 280 310 | 
             
                  def cargo_config_from_file(key_name)
         | 
| 281 | 
            -
                     | 
| 311 | 
            +
                    config_file = cargo_config
         | 
| 312 | 
            +
                    return nil unless config_file
         | 
| 313 | 
            +
             | 
| 314 | 
            +
                    parsed_file(config_file).dig(*key_name.split("."))
         | 
| 282 315 | 
             
                  end
         | 
| 283 316 |  | 
| 317 | 
            +
                  sig { params(name: String, declaration: T.any(String, T::Hash[String, String])).returns(T.nilable(String)) }
         | 
| 284 318 | 
             
                  def version_from_lockfile(name, declaration)
         | 
| 285 319 | 
             
                    return unless lockfile
         | 
| 286 320 |  | 
| 321 | 
            +
                    lockfile_content = parsed_file(T.must(lockfile))
         | 
| 322 | 
            +
                    return unless lockfile_content.is_a?(Hash)
         | 
| 323 | 
            +
             | 
| 287 324 | 
             
                    candidate_packages =
         | 
| 288 | 
            -
                       | 
| 289 | 
            -
             | 
| 325 | 
            +
                      lockfile_content.fetch("package", [])
         | 
| 326 | 
            +
                                      .select { |p| p["name"] == name }
         | 
| 290 327 |  | 
| 291 328 | 
             
                    if (req = requirement_from_declaration(declaration))
         | 
| 292 329 | 
             
                      req = Cargo::Requirement.new(req)
         | 
| @@ -311,10 +348,12 @@ module Dependabot | |
| 311 348 | 
             
                    version_from_lockfile_details(package)
         | 
| 312 349 | 
             
                  end
         | 
| 313 350 |  | 
| 351 | 
            +
                  sig { params(declaration: T.any(String, T::Hash[String, String])).returns(T::Boolean) }
         | 
| 314 352 | 
             
                  def git_req?(declaration)
         | 
| 315 353 | 
             
                    source_from_declaration(declaration)&.fetch(:type, nil) == "git"
         | 
| 316 354 | 
             
                  end
         | 
| 317 355 |  | 
| 356 | 
            +
                  sig { params(declaration: T.any(String, T::Hash[String, String])).returns(T::Hash[Symbol, String]) }
         | 
| 318 357 | 
             
                  def git_source_details(declaration)
         | 
| 319 358 | 
             
                    {
         | 
| 320 359 | 
             
                      type: "git",
         | 
| @@ -324,38 +363,47 @@ module Dependabot | |
| 324 363 | 
             
                    }
         | 
| 325 364 | 
             
                  end
         | 
| 326 365 |  | 
| 366 | 
            +
                  sig { params(package_details: T::Hash[String, String]).returns(String) }
         | 
| 327 367 | 
             
                  def version_from_lockfile_details(package_details)
         | 
| 328 | 
            -
                    return package_details["version"] unless package_details["source"]&.start_with?("git+")
         | 
| 368 | 
            +
                    return T.must(package_details["version"]) unless package_details["source"]&.start_with?("git+")
         | 
| 329 369 |  | 
| 330 | 
            -
                    package_details["source"].split("#").last
         | 
| 370 | 
            +
                    T.must(T.must(package_details["source"]).split("#").last)
         | 
| 331 371 | 
             
                  end
         | 
| 332 372 |  | 
| 373 | 
            +
                  sig { override.void }
         | 
| 333 374 | 
             
                  def check_required_files
         | 
| 334 375 | 
             
                    raise "No Cargo.toml!" unless get_original_file("Cargo.toml")
         | 
| 335 376 | 
             
                  end
         | 
| 336 377 |  | 
| 378 | 
            +
                  sig { params(file: DependencyFile).returns(T.untyped) }
         | 
| 337 379 | 
             
                  def parsed_file(file)
         | 
| 338 | 
            -
                    @parsed_file ||= {}
         | 
| 380 | 
            +
                    @parsed_file ||= T.let({}, T.untyped)
         | 
| 339 381 | 
             
                    @parsed_file[file.name] ||= TomlRB.parse(file.content)
         | 
| 340 382 | 
             
                  rescue TomlRB::ParseError, TomlRB::ValueOverwriteError
         | 
| 341 383 | 
             
                    raise Dependabot::DependencyFileNotParseable, file.path
         | 
| 342 384 | 
             
                  end
         | 
| 343 385 |  | 
| 386 | 
            +
                  sig { returns(T::Array[Dependabot::DependencyFile]) }
         | 
| 344 387 | 
             
                  def manifest_files
         | 
| 345 | 
            -
                    @manifest_files ||=
         | 
| 388 | 
            +
                    @manifest_files ||= T.let(
         | 
| 346 389 | 
             
                      dependency_files
         | 
| 347 | 
            -
             | 
| 348 | 
            -
             | 
| 390 | 
            +
                              .select { |f| f.name.end_with?("Cargo.toml") }
         | 
| 391 | 
            +
                              .reject(&:support_file?),
         | 
| 392 | 
            +
                      T.nilable(T::Array[Dependabot::DependencyFile])
         | 
| 393 | 
            +
                    )
         | 
| 349 394 | 
             
                  end
         | 
| 350 395 |  | 
| 396 | 
            +
                  sig { returns(T.nilable(Dependabot::DependencyFile)) }
         | 
| 351 397 | 
             
                  def lockfile
         | 
| 352 | 
            -
                    @lockfile ||= get_original_file("Cargo.lock")
         | 
| 398 | 
            +
                    @lockfile ||= T.let(get_original_file("Cargo.lock"), T.nilable(Dependabot::DependencyFile))
         | 
| 353 399 | 
             
                  end
         | 
| 354 400 |  | 
| 401 | 
            +
                  sig { returns(T.nilable(Dependabot::DependencyFile)) }
         | 
| 355 402 | 
             
                  def cargo_config
         | 
| 356 | 
            -
                    @cargo_config ||= get_original_file(".cargo/config.toml")
         | 
| 403 | 
            +
                    @cargo_config ||= T.let(get_original_file(".cargo/config.toml"), T.nilable(Dependabot::DependencyFile))
         | 
| 357 404 | 
             
                  end
         | 
| 358 405 |  | 
| 406 | 
            +
                  sig { returns(T.class_of(Dependabot::Version)) }
         | 
| 359 407 | 
             
                  def version_class
         | 
| 360 408 | 
             
                    Cargo::Version
         | 
| 361 409 | 
             
                  end
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # typed:  | 
| 1 | 
            +
            # typed: strict
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 3 |  | 
| 4 4 | 
             
            require "toml-rb"
         | 
| @@ -12,7 +12,8 @@ require "dependabot/errors" | |
| 12 12 | 
             
            module Dependabot
         | 
| 13 13 | 
             
              module Cargo
         | 
| 14 14 | 
             
                class UpdateChecker
         | 
| 15 | 
            -
                  class VersionResolver
         | 
| 15 | 
            +
                  class VersionResolver # rubocop:disable Metrics/ClassLength
         | 
| 16 | 
            +
                    extend T::Sig
         | 
| 16 17 | 
             
                    UNABLE_TO_UPDATE = /Unable to update (?<url>.*?)$/
         | 
| 17 18 | 
             
                    BRANCH_NOT_FOUND_REGEX = /#{UNABLE_TO_UPDATE}.*to find branch `(?<branch>[^`]+)`/m
         | 
| 18 19 | 
             
                    REVSPEC_PATTERN = /revspec '.*' not found/
         | 
| @@ -26,31 +27,52 @@ module Dependabot | |
| 26 27 | 
             
                    NOT_OUR_REF = /fatal: remote error: upload-pack: not our ref/
         | 
| 27 28 | 
             
                    NOT_OUR_REF_REGEX = /#{NOT_OUR_REF}.*#{UNABLE_TO_UPDATE}/m
         | 
| 28 29 |  | 
| 30 | 
            +
                    sig do
         | 
| 31 | 
            +
                      params(
         | 
| 32 | 
            +
                        dependency: Dependabot::Dependency,
         | 
| 33 | 
            +
                        credentials: T::Array[Dependabot::Credential],
         | 
| 34 | 
            +
                        original_dependency_files: T::Array[Dependabot::DependencyFile],
         | 
| 35 | 
            +
                        prepared_dependency_files: T::Array[Dependabot::DependencyFile]
         | 
| 36 | 
            +
                      ).void
         | 
| 37 | 
            +
                    end
         | 
| 29 38 | 
             
                    def initialize(dependency:, credentials:,
         | 
| 30 39 | 
             
                                   original_dependency_files:, prepared_dependency_files:)
         | 
| 31 40 | 
             
                      @dependency = dependency
         | 
| 32 41 | 
             
                      @prepared_dependency_files = prepared_dependency_files
         | 
| 33 42 | 
             
                      @original_dependency_files = original_dependency_files
         | 
| 34 43 | 
             
                      @credentials = credentials
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      # Initialize instance variables with proper T.let declarations
         | 
| 46 | 
            +
                      @prepared_manifest_files = T.let(nil, T.nilable(T::Array[DependencyFile]))
         | 
| 47 | 
            +
                      @original_manifest_files = T.let(nil, T.nilable(T::Array[DependencyFile]))
         | 
| 35 48 | 
             
                    end
         | 
| 36 49 |  | 
| 50 | 
            +
                    sig { returns(T.nilable(T.any(String, Gem::Version))) }
         | 
| 37 51 | 
             
                    def latest_resolvable_version
         | 
| 38 52 | 
             
                      return @latest_resolvable_version if defined?(@latest_resolvable_version)
         | 
| 39 53 |  | 
| 40 | 
            -
                      @latest_resolvable_version = fetch_latest_resolvable_version
         | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 54 | 
            +
                      @latest_resolvable_version = T.let(fetch_latest_resolvable_version, T.nilable(T.any(String, Gem::Version)))
         | 
| 55 | 
            +
                    rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e
         | 
| 56 | 
            +
                      raise Dependabot::DependencyFileNotResolvable, e.message
         | 
| 43 57 | 
             
                    end
         | 
| 44 58 |  | 
| 45 59 | 
             
                    private
         | 
| 46 60 |  | 
| 61 | 
            +
                    sig { returns(Dependency) }
         | 
| 47 62 | 
             
                    attr_reader :dependency
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    sig { returns(T::Array[Credential]) }
         | 
| 48 65 | 
             
                    attr_reader :credentials
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    sig { returns(T::Array[DependencyFile]) }
         | 
| 49 68 | 
             
                    attr_reader :prepared_dependency_files
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    sig { returns(T::Array[DependencyFile]) }
         | 
| 50 71 | 
             
                    attr_reader :original_dependency_files
         | 
| 51 72 |  | 
| 73 | 
            +
                    sig { returns(T.nilable(T.any(String, Gem::Version))) }
         | 
| 52 74 | 
             
                    def fetch_latest_resolvable_version
         | 
| 53 | 
            -
                      base_directory = prepared_dependency_files.first.directory
         | 
| 75 | 
            +
                      base_directory = T.must(prepared_dependency_files.first).directory
         | 
| 54 76 | 
             
                      SharedHelpers.in_a_temporary_directory(base_directory) do
         | 
| 55 77 | 
             
                        write_temporary_dependency_files
         | 
| 56 78 |  | 
| @@ -68,8 +90,10 @@ module Dependabot | |
| 68 90 | 
             
                    rescue SharedHelpers::HelperSubprocessFailed => e
         | 
| 69 91 | 
             
                      retry if better_specification_needed?(e)
         | 
| 70 92 | 
             
                      handle_cargo_errors(e)
         | 
| 93 | 
            +
                      nil
         | 
| 71 94 | 
             
                    end
         | 
| 72 95 |  | 
| 96 | 
            +
                    sig { returns(T.nilable(T.any(String, Gem::Version))) }
         | 
| 73 97 | 
             
                    def fetch_version_from_new_lockfile
         | 
| 74 98 | 
             
                      check_rust_workspace_root unless File.exist?("Cargo.lock")
         | 
| 75 99 | 
             
                      lockfile_content = File.read("Cargo.lock")
         | 
| @@ -95,6 +119,7 @@ module Dependabot | |
| 95 119 | 
             
                    # rubocop:disable Metrics/PerceivedComplexity
         | 
| 96 120 | 
             
                    # rubocop:disable Metrics/CyclomaticComplexity
         | 
| 97 121 | 
             
                    # rubocop:disable Metrics/AbcSize
         | 
| 122 | 
            +
                    sig { params(error: StandardError).returns(T::Boolean) }
         | 
| 98 123 | 
             
                    def better_specification_needed?(error)
         | 
| 99 124 | 
             
                      return false if @custom_specification
         | 
| 100 125 | 
             
                      return false unless error.message.match?(/specification .* is ambigu/)
         | 
| @@ -108,25 +133,26 @@ module Dependabot | |
| 108 133 | 
             
                              dependency.version
         | 
| 109 134 | 
             
                            end
         | 
| 110 135 |  | 
| 111 | 
            -
                      if spec_options.count { |s| s.end_with?(ver) } == 1
         | 
| 112 | 
            -
                        @custom_specification = spec_options.find { |s| s.end_with?(ver) }
         | 
| 136 | 
            +
                      if spec_options.count { |s| s.end_with?(T.must(ver)) } == 1
         | 
| 137 | 
            +
                        @custom_specification = spec_options.find { |s| s.end_with?(T.must(ver)) }
         | 
| 113 138 | 
             
                        return true
         | 
| 114 | 
            -
                      elsif spec_options.count { |s| s.end_with?(ver) } > 1
         | 
| 115 | 
            -
                        spec_options.select! { |s| s.end_with?(ver) }
         | 
| 139 | 
            +
                      elsif spec_options.count { |s| s.end_with?(T.must(ver)) } > 1
         | 
| 140 | 
            +
                        spec_options.select! { |s| s.end_with?(T.must(ver)) }
         | 
| 116 141 | 
             
                      end
         | 
| 117 142 |  | 
| 118 143 | 
             
                      if git_dependency? && git_source_url &&
         | 
| 119 | 
            -
                         spec_options.count { |s| s.include?(git_source_url) } >= 1
         | 
| 120 | 
            -
                        spec_options.select! { |s| s.include?(git_source_url) }
         | 
| 144 | 
            +
                         spec_options.count { |s| s.include?(T.must(git_source_url)) } >= 1
         | 
| 145 | 
            +
                        spec_options.select! { |s| s.include?(T.must(git_source_url)) }
         | 
| 121 146 | 
             
                      end
         | 
| 122 147 |  | 
| 123 | 
            -
                      @custom_specification = spec_options.first
         | 
| 148 | 
            +
                      @custom_specification = T.let(spec_options.first, T.nilable(String))
         | 
| 124 149 | 
             
                      true
         | 
| 125 150 | 
             
                    end
         | 
| 126 151 | 
             
                    # rubocop:enable Metrics/AbcSize
         | 
| 127 152 | 
             
                    # rubocop:enable Metrics/CyclomaticComplexity
         | 
| 128 153 | 
             
                    # rubocop:enable Metrics/PerceivedComplexity
         | 
| 129 154 |  | 
| 155 | 
            +
                    sig { returns(String) }
         | 
| 130 156 | 
             
                    def dependency_spec
         | 
| 131 157 | 
             
                      return @custom_specification if @custom_specification
         | 
| 132 158 |  | 
| @@ -143,6 +169,7 @@ module Dependabot | |
| 143 169 |  | 
| 144 170 | 
             
                    # Shell out to Cargo, which handles everything for us, and does
         | 
| 145 171 | 
             
                    # so without doing an install (so it's fast).
         | 
| 172 | 
            +
                    sig { void }
         | 
| 146 173 | 
             
                    def run_cargo_update_command
         | 
| 147 174 | 
             
                      run_cargo_command(
         | 
| 148 175 | 
             
                        "cargo update -p #{dependency_spec} -vv",
         | 
| @@ -150,6 +177,7 @@ module Dependabot | |
| 150 177 | 
             
                      )
         | 
| 151 178 | 
             
                    end
         | 
| 152 179 |  | 
| 180 | 
            +
                    sig { params(command: String, fingerprint: T.nilable(String)).void }
         | 
| 153 181 | 
             
                    def run_cargo_command(command, fingerprint: nil)
         | 
| 154 182 | 
             
                      start = Time.now
         | 
| 155 183 | 
             
                      command = SharedHelpers.escape_command(command)
         | 
| @@ -176,40 +204,43 @@ module Dependabot | |
| 176 204 | 
             
                      )
         | 
| 177 205 | 
             
                    end
         | 
| 178 206 |  | 
| 207 | 
            +
                    sig { params(prepared: T::Boolean).returns(T.nilable(Integer)) }
         | 
| 179 208 | 
             
                    def write_temporary_dependency_files(prepared: true)
         | 
| 180 209 | 
             
                      write_manifest_files(prepared: prepared)
         | 
| 181 210 |  | 
| 182 | 
            -
                      File.write(lockfile.name, lockfile.content) if lockfile
         | 
| 183 | 
            -
                      File.write(toolchain.name, toolchain.content) if toolchain
         | 
| 211 | 
            +
                      File.write(T.must(lockfile).name, T.must(lockfile).content) if lockfile
         | 
| 212 | 
            +
                      File.write(T.must(toolchain).name, T.must(toolchain).content) if toolchain
         | 
| 184 213 | 
             
                      return unless config
         | 
| 185 214 |  | 
| 186 | 
            -
                      FileUtils.mkdir_p(File.dirname(config.name))
         | 
| 187 | 
            -
                      File.write(config.name, config.content)
         | 
| 215 | 
            +
                      FileUtils.mkdir_p(File.dirname(T.must(config).name))
         | 
| 216 | 
            +
                      File.write(T.must(config).name, T.must(config).content)
         | 
| 188 217 | 
             
                    end
         | 
| 189 218 |  | 
| 219 | 
            +
                    sig { void }
         | 
| 190 220 | 
             
                    def check_rust_workspace_root
         | 
| 191 221 | 
             
                      cargo_toml = original_dependency_files
         | 
| 192 222 | 
             
                                   .select { |f| f.name.end_with?("../Cargo.toml") }
         | 
| 193 223 | 
             
                                   .max_by { |f| f.name.length }
         | 
| 194 | 
            -
                      return unless TomlRB.parse(cargo_toml.content)["workspace"]
         | 
| 224 | 
            +
                      return unless TomlRB.parse(T.must(cargo_toml).content)["workspace"]
         | 
| 195 225 |  | 
| 196 226 | 
             
                      msg = "This project is part of a Rust workspace but is not the " \
         | 
| 197 227 | 
             
                            "workspace root." \
         | 
| 198 228 |  | 
| 199 | 
            -
                      if cargo_toml.directory != "/"
         | 
| 229 | 
            +
                      if T.must(cargo_toml).directory != "/"
         | 
| 200 230 | 
             
                        msg += "Please update your settings so Dependabot points at the " \
         | 
| 201 | 
            -
                               "workspace root instead of #{cargo_toml.directory}."
         | 
| 231 | 
            +
                               "workspace root instead of #{T.must(cargo_toml).directory}."
         | 
| 202 232 | 
             
                      end
         | 
| 203 233 | 
             
                      raise Dependabot::DependencyFileNotResolvable, msg
         | 
| 204 234 | 
             
                    end
         | 
| 205 235 |  | 
| 206 236 | 
             
                    # rubocop:disable Metrics/AbcSize
         | 
| 207 237 | 
             
                    # rubocop:disable Metrics/PerceivedComplexity
         | 
| 238 | 
            +
                    sig { params(error: StandardError).void }
         | 
| 208 239 | 
             
                    def handle_cargo_errors(error)
         | 
| 209 240 | 
             
                      if error.message.include?("does not have these features")
         | 
| 210 241 | 
             
                        # TODO: Ideally we should update the declaration not to ask
         | 
| 211 242 | 
             
                        # for the specified features
         | 
| 212 | 
            -
                        return | 
| 243 | 
            +
                        return
         | 
| 213 244 | 
             
                      end
         | 
| 214 245 |  | 
| 215 246 | 
             
                      if error.message.include?("authenticate when downloading repo") ||
         | 
| @@ -218,22 +249,24 @@ module Dependabot | |
| 218 249 | 
             
                        # consistent error)
         | 
| 219 250 | 
             
                        urls = unreachable_git_urls
         | 
| 220 251 |  | 
| 221 | 
            -
                        if urls.none?
         | 
| 222 | 
            -
                          url = error.message.match(UNABLE_TO_UPDATE)
         | 
| 223 | 
            -
             | 
| 224 | 
            -
                          raise if reachable_git_urls.include?(url)
         | 
| 252 | 
            +
                        if T.must(urls).none?
         | 
| 253 | 
            +
                          url = T.must(T.must(error.message.match(UNABLE_TO_UPDATE))
         | 
| 254 | 
            +
                                        .named_captures.fetch("url")).split(/[#?]/).first
         | 
| 255 | 
            +
                          raise if T.must(reachable_git_urls).include?(url)
         | 
| 225 256 |  | 
| 226 | 
            -
                           | 
| 257 | 
            +
                          # Fix: Wrap url in T.must since split().first can return nil
         | 
| 258 | 
            +
                          T.must(urls) << T.must(url)
         | 
| 227 259 | 
             
                        end
         | 
| 228 260 |  | 
| 229 | 
            -
                        raise Dependabot::GitDependenciesNotReachable, urls
         | 
| 261 | 
            +
                        raise Dependabot::GitDependenciesNotReachable, T.must(urls)
         | 
| 230 262 | 
             
                      end
         | 
| 231 263 |  | 
| 232 264 | 
             
                      [BRANCH_NOT_FOUND_REGEX, REF_NOT_FOUND_REGEX, GIT_REF_NOT_FOUND_REGEX, NOT_OUR_REF_REGEX].each do |regex|
         | 
| 233 265 | 
             
                        next unless error.message.match?(regex)
         | 
| 234 266 |  | 
| 235 | 
            -
                        dependency_url = error.message.match(regex).named_captures.fetch("url").split(/[#?]/).first
         | 
| 236 | 
            -
                         | 
| 267 | 
            +
                        dependency_url = T.must(T.must(error.message.match(regex)).named_captures.fetch("url")).split(/[#?]/).first
         | 
| 268 | 
            +
                        # Fix: Wrap dependency_url in T.must since split().first can return nil
         | 
| 269 | 
            +
                        raise Dependabot::GitDependencyReferenceNotFound, T.must(dependency_url)
         | 
| 237 270 | 
             
                      end
         | 
| 238 271 |  | 
| 239 272 | 
             
                      if workspace_native_library_update_error?(error.message)
         | 
| @@ -268,8 +301,9 @@ module Dependabot | |
| 268 301 | 
             
                    # rubocop:enable Metrics/AbcSize
         | 
| 269 302 | 
             
                    # rubocop:enable Metrics/PerceivedComplexity
         | 
| 270 303 |  | 
| 304 | 
            +
                    sig { params(message: T.nilable(String)).returns(T.any(Dependabot::Version, T::Boolean)) }
         | 
| 271 305 | 
             
                    def using_old_toolchain?(message)
         | 
| 272 | 
            -
                      return true if message.include?("usage of sparse registries requires `-Z sparse-registry`")
         | 
| 306 | 
            +
                      return true if T.must(message).include?("usage of sparse registries requires `-Z sparse-registry`")
         | 
| 273 307 |  | 
| 274 308 | 
             
                      version_log = /rust version (?<version>\d.\d+)/.match(message)
         | 
| 275 309 | 
             
                      return false unless version_log
         | 
| @@ -277,11 +311,12 @@ module Dependabot | |
| 277 311 | 
             
                      version_class.new(version_log[:version]) < version_class.new("1.68")
         | 
| 278 312 | 
             
                    end
         | 
| 279 313 |  | 
| 314 | 
            +
                    sig { returns(T.nilable(T::Array[String])) }
         | 
| 280 315 | 
             
                    def unreachable_git_urls
         | 
| 281 316 | 
             
                      return @unreachable_git_urls if defined?(@unreachable_git_urls)
         | 
| 282 317 |  | 
| 283 | 
            -
                      @unreachable_git_urls = []
         | 
| 284 | 
            -
                      @reachable_git_urls = []
         | 
| 318 | 
            +
                      @unreachable_git_urls = T.let([], T.nilable(T::Array[String]))
         | 
| 319 | 
            +
                      @reachable_git_urls = T.let([], T.nilable(T::Array[String]))
         | 
| 285 320 |  | 
| 286 321 | 
             
                      dependencies = FileParser.new(
         | 
| 287 322 | 
             
                        dependency_files: original_dependency_files,
         | 
| @@ -295,19 +330,20 @@ module Dependabot | |
| 295 330 | 
             
                        )
         | 
| 296 331 | 
             
                        next unless checker.git_dependency?
         | 
| 297 332 |  | 
| 298 | 
            -
                        url = dep.requirements.find { |r| r.dig(:source, :type) == "git" }
         | 
| 299 | 
            -
             | 
| 333 | 
            +
                        url = T.must(dep.requirements.find { |r| r.dig(:source, :type) == "git" })
         | 
| 334 | 
            +
                               .fetch(:source).fetch(:url)
         | 
| 300 335 |  | 
| 301 336 | 
             
                        if checker.git_repo_reachable?
         | 
| 302 | 
            -
                          @reachable_git_urls << url
         | 
| 337 | 
            +
                          T.must(@reachable_git_urls) << url
         | 
| 303 338 | 
             
                        else
         | 
| 304 | 
            -
                          @unreachable_git_urls << url
         | 
| 339 | 
            +
                          T.must(@unreachable_git_urls) << url
         | 
| 305 340 | 
             
                        end
         | 
| 306 341 | 
             
                      end
         | 
| 307 342 |  | 
| 308 343 | 
             
                      @unreachable_git_urls
         | 
| 309 344 | 
             
                    end
         | 
| 310 345 |  | 
| 346 | 
            +
                    sig { returns(T.nilable(T::Array[String])) }
         | 
| 311 347 | 
             
                    def reachable_git_urls
         | 
| 312 348 | 
             
                      return @reachable_git_urls if defined?(@reachable_git_urls)
         | 
| 313 349 |  | 
| @@ -315,6 +351,7 @@ module Dependabot | |
| 315 351 | 
             
                      @reachable_git_urls
         | 
| 316 352 | 
             
                    end
         | 
| 317 353 |  | 
| 354 | 
            +
                    sig { params(message: String).returns(T::Boolean) }
         | 
| 318 355 | 
             
                    def resolvability_error?(message)
         | 
| 319 356 | 
             
                      return true if message.include?("failed to parse lock")
         | 
| 320 357 | 
             
                      return true if message.include?("believes it's in a workspace")
         | 
| @@ -330,8 +367,9 @@ module Dependabot | |
| 330 367 | 
             
                      !original_requirements_resolvable
         | 
| 331 368 | 
             
                    end
         | 
| 332 369 |  | 
| 370 | 
            +
                    sig { returns(T.any(TrueClass, FalseClass, Symbol)) }
         | 
| 333 371 | 
             
                    def original_requirements_resolvable?
         | 
| 334 | 
            -
                      base_directory = original_dependency_files.first.directory
         | 
| 372 | 
            +
                      base_directory = T.must(original_dependency_files.first).directory
         | 
| 335 373 | 
             
                      SharedHelpers.in_a_temporary_directory(base_directory) do
         | 
| 336 374 | 
             
                        write_temporary_dependency_files(prepared: false)
         | 
| 337 375 |  | 
| @@ -353,10 +391,11 @@ module Dependabot | |
| 353 391 | 
             
                      end
         | 
| 354 392 | 
             
                    end
         | 
| 355 393 |  | 
| 394 | 
            +
                    sig { params(message: String).returns(T::Boolean) }
         | 
| 356 395 | 
             
                    def workspace_native_library_update_error?(message)
         | 
| 357 396 | 
             
                      return false unless message.include?("native library")
         | 
| 358 397 |  | 
| 359 | 
            -
                      library_count = prepared_manifest_files.count do |file|
         | 
| 398 | 
            +
                      library_count = T.must(prepared_manifest_files).count do |file|
         | 
| 360 399 | 
             
                        package_name = TomlRB.parse(file.content).dig("package", "name")
         | 
| 361 400 | 
             
                        next false unless package_name
         | 
| 362 401 |  | 
| @@ -366,17 +405,18 @@ module Dependabot | |
| 366 405 | 
             
                      library_count >= 2
         | 
| 367 406 | 
             
                    end
         | 
| 368 407 |  | 
| 408 | 
            +
                    sig { params(prepared: T::Boolean).returns(T.nilable(T::Array[Dependabot::DependencyFile])) }
         | 
| 369 409 | 
             
                    def write_manifest_files(prepared: true)
         | 
| 370 410 | 
             
                      manifest_files = if prepared then prepared_manifest_files
         | 
| 371 411 | 
             
                                       else
         | 
| 372 412 | 
             
                                         original_manifest_files
         | 
| 373 413 | 
             
                                       end
         | 
| 374 414 |  | 
| 375 | 
            -
                      manifest_files.each do |file|
         | 
| 415 | 
            +
                      T.must(manifest_files).each do |file|
         | 
| 376 416 | 
             
                        path = file.name
         | 
| 377 417 | 
             
                        dir = Pathname.new(path).dirname
         | 
| 378 418 | 
             
                        FileUtils.mkdir_p(dir)
         | 
| 379 | 
            -
                        File.write(file.name, sanitized_manifest_content(file.content))
         | 
| 419 | 
            +
                        File.write(file.name, sanitized_manifest_content(T.must(file.content)))
         | 
| 380 420 |  | 
| 381 421 | 
             
                        next if virtual_manifest?(file)
         | 
| 382 422 |  | 
| @@ -388,26 +428,30 @@ module Dependabot | |
| 388 428 | 
             
                      end
         | 
| 389 429 | 
             
                    end
         | 
| 390 430 |  | 
| 431 | 
            +
                    sig { returns(T.nilable(String)) }
         | 
| 391 432 | 
             
                    def git_dependency_version
         | 
| 392 433 | 
             
                      return unless lockfile
         | 
| 393 434 |  | 
| 394 | 
            -
                      TomlRB.parse(lockfile.content)
         | 
| 435 | 
            +
                      TomlRB.parse(T.must(lockfile).content)
         | 
| 395 436 | 
             
                            .fetch("package", [])
         | 
| 396 437 | 
             
                            .select { |p| p["name"] == dependency.name }
         | 
| 397 438 | 
             
                            .find { |p| p["source"].end_with?(dependency.version) }
         | 
| 398 439 | 
             
                            .fetch("version")
         | 
| 399 440 | 
             
                    end
         | 
| 400 441 |  | 
| 442 | 
            +
                    sig { returns(T.nilable(String)) }
         | 
| 401 443 | 
             
                    def git_source_url
         | 
| 402 444 | 
             
                      dependency.requirements
         | 
| 403 445 | 
             
                                .find { |r| r.dig(:source, :type) == "git" }
         | 
| 404 446 | 
             
                                &.dig(:source, :url)
         | 
| 405 447 | 
             
                    end
         | 
| 406 448 |  | 
| 449 | 
            +
                    sig { returns(String) }
         | 
| 407 450 | 
             
                    def dummy_app_content
         | 
| 408 451 | 
             
                      %{fn main() {\nprintln!("Hello, world!");\n}}
         | 
| 409 452 | 
             
                    end
         | 
| 410 453 |  | 
| 454 | 
            +
                    sig { params(content: String).returns(String) }
         | 
| 411 455 | 
             
                    def sanitized_manifest_content(content)
         | 
| 412 456 | 
             
                      object = TomlRB.parse(content)
         | 
| 413 457 |  | 
| @@ -424,32 +468,40 @@ module Dependabot | |
| 424 468 | 
             
                      TomlRB.dump(object)
         | 
| 425 469 | 
             
                    end
         | 
| 426 470 |  | 
| 471 | 
            +
                    sig { returns(T.nilable(T::Array[DependencyFile])) }
         | 
| 427 472 | 
             
                    def prepared_manifest_files
         | 
| 428 473 | 
             
                      @prepared_manifest_files ||=
         | 
| 429 474 | 
             
                        prepared_dependency_files
         | 
| 430 475 | 
             
                        .select { |f| f.name.end_with?("Cargo.toml") }
         | 
| 431 476 | 
             
                    end
         | 
| 432 477 |  | 
| 478 | 
            +
                    sig { returns(T.nilable(T::Array[DependencyFile])) }
         | 
| 433 479 | 
             
                    def original_manifest_files
         | 
| 434 480 | 
             
                      @original_manifest_files ||=
         | 
| 435 481 | 
             
                        original_dependency_files
         | 
| 436 482 | 
             
                        .select { |f| f.name.end_with?("Cargo.toml") }
         | 
| 437 483 | 
             
                    end
         | 
| 438 484 |  | 
| 485 | 
            +
                    sig { returns(T.nilable(DependencyFile)) }
         | 
| 439 486 | 
             
                    def lockfile
         | 
| 440 | 
            -
                      @lockfile ||= prepared_dependency_files
         | 
| 441 | 
            -
             | 
| 487 | 
            +
                      @lockfile ||= T.let(prepared_dependency_files
         | 
| 488 | 
            +
                                            .find { |f| f.name == "Cargo.lock" }, T.nilable(Dependabot::DependencyFile))
         | 
| 442 489 | 
             
                    end
         | 
| 443 490 |  | 
| 491 | 
            +
                    sig { returns(T.nilable(DependencyFile)) }
         | 
| 444 492 | 
             
                    def toolchain
         | 
| 445 | 
            -
                      @toolchain ||= original_dependency_files
         | 
| 446 | 
            -
             | 
| 493 | 
            +
                      @toolchain ||= T.let(original_dependency_files
         | 
| 494 | 
            +
                                             .find { |f| f.name == "rust-toolchain" }, T.nilable(Dependabot::DependencyFile))
         | 
| 447 495 | 
             
                    end
         | 
| 448 496 |  | 
| 497 | 
            +
                    sig { returns(T.nilable(DependencyFile)) }
         | 
| 449 498 | 
             
                    def config
         | 
| 450 | 
            -
                      @config ||= original_dependency_files.find  | 
| 499 | 
            +
                      @config ||= T.let(original_dependency_files.find do |f|
         | 
| 500 | 
            +
                        f.name == ".cargo/config.toml"
         | 
| 501 | 
            +
                      end, T.nilable(Dependabot::DependencyFile))
         | 
| 451 502 | 
             
                    end
         | 
| 452 503 |  | 
| 504 | 
            +
                    sig { returns(T::Boolean) }
         | 
| 453 505 | 
             
                    def git_dependency?
         | 
| 454 506 | 
             
                      GitCommitChecker.new(
         | 
| 455 507 | 
             
                        dependency: dependency,
         | 
| @@ -460,10 +512,12 @@ module Dependabot | |
| 460 512 | 
             
                    # When the package table is not present in a workspace manifest, it is
         | 
| 461 513 | 
             
                    # called a virtual manifest: https://doc.rust-lang.org/cargo/reference/
         | 
| 462 514 | 
             
                    # manifest.html#virtual-manifest
         | 
| 515 | 
            +
                    sig { params(file: DependencyFile).returns(T::Boolean) }
         | 
| 463 516 | 
             
                    def virtual_manifest?(file)
         | 
| 464 | 
            -
                      !file.content.include?("[package]")
         | 
| 517 | 
            +
                      !T.must(file.content).include?("[package]")
         | 
| 465 518 | 
             
                    end
         | 
| 466 519 |  | 
| 520 | 
            +
                    sig { returns(T.class_of(Dependabot::Version)) }
         | 
| 467 521 | 
             
                    def version_class
         | 
| 468 522 | 
             
                      dependency.version_class
         | 
| 469 523 | 
             
                    end
         | 
    
        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. | 
| 4 | 
            +
              version: 0.326.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. | 
| 18 | 
            +
                    version: 0.326.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. | 
| 25 | 
            +
                    version: 0.326.0
         | 
| 26 26 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 27 27 | 
             
              name: debug
         | 
| 28 28 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -265,7 +265,7 @@ licenses: | |
| 265 265 | 
             
            - MIT
         | 
| 266 266 | 
             
            metadata:
         | 
| 267 267 | 
             
              bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
         | 
| 268 | 
            -
              changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0. | 
| 268 | 
            +
              changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.326.0
         | 
| 269 269 | 
             
            rdoc_options: []
         | 
| 270 270 | 
             
            require_paths:
         | 
| 271 271 | 
             
            - lib
         |