|
1 |
| -# typed: true |
| 1 | +# typed: strict |
2 | 2 | # frozen_string_literal: true
|
3 | 3 |
|
4 | 4 | require "dependabot/python/requirement_parser"
|
5 | 5 | require "dependabot/python/file_updater"
|
6 | 6 | require "dependabot/shared_helpers"
|
7 | 7 | require "dependabot/python/native_helpers"
|
| 8 | +require "sorbet-runtime" |
8 | 9 |
|
9 | 10 | module Dependabot
|
10 | 11 | module Python
|
11 | 12 | class FileUpdater
|
12 | 13 | class RequirementFileUpdater
|
| 14 | + extend T::Sig |
| 15 | + |
13 | 16 | require_relative "requirement_replacer"
|
14 | 17 |
|
15 |
| - attr_reader :dependencies |
| 18 | + sig { returns(T::Array[Dependabot::DependencyFile]) } |
16 | 19 | attr_reader :dependency_files
|
| 20 | + |
| 21 | + sig { returns(T::Array[Dependabot::Credential]) } |
17 | 22 | attr_reader :credentials
|
18 | 23 |
|
| 24 | + sig { returns(T::Array[Dependabot::Dependency]) } |
| 25 | + attr_reader :dependencies |
| 26 | + |
| 27 | + sig do |
| 28 | + params( |
| 29 | + dependencies: T::Array[Dependabot::Dependency], |
| 30 | + dependency_files: T::Array[Dependabot::DependencyFile], |
| 31 | + credentials: T::Array[Dependabot::Credential], |
| 32 | + index_urls: T.nilable(T::Array[String]) |
| 33 | + ).void |
| 34 | + end |
19 | 35 | def initialize(dependencies:, dependency_files:, credentials:, index_urls: nil)
|
20 | 36 | @dependencies = dependencies
|
21 | 37 | @dependency_files = dependency_files
|
22 | 38 | @credentials = credentials
|
23 | 39 | @index_urls = index_urls
|
24 | 40 | end
|
25 | 41 |
|
| 42 | + sig { returns(T::Array[Dependabot::DependencyFile]) } |
26 | 43 | def updated_dependency_files
|
27 |
| - @updated_dependency_files ||= fetch_updated_dependency_files |
| 44 | + @updated_dependency_files ||= T.let( |
| 45 | + fetch_updated_dependency_files, |
| 46 | + T.nilable(T::Array[DependencyFile]) |
| 47 | + ) |
28 | 48 | end
|
29 | 49 |
|
30 | 50 | private
|
31 | 51 |
|
| 52 | + sig { returns(Dependabot::Dependency) } |
32 | 53 | def dependency
|
33 | 54 | # For now, we'll only ever be updating a single dependency
|
34 |
| - dependencies.first |
| 55 | + T.must(dependencies.first) |
35 | 56 | end
|
36 | 57 |
|
| 58 | + sig { returns(T::Array[Dependabot::DependencyFile]) } |
37 | 59 | def fetch_updated_dependency_files
|
38 |
| - reqs = dependency.requirements.zip(dependency.previous_requirements) |
| 60 | + reqs = dependency.requirements.zip(dependency.previous_requirements || []) |
39 | 61 |
|
40 | 62 | reqs.filter_map do |(new_req, old_req)|
|
41 | 63 | next if new_req == old_req
|
42 | 64 |
|
43 | 65 | file = get_original_file(new_req.fetch(:file)).dup
|
44 | 66 | updated_content =
|
45 | 67 | updated_requirement_or_setup_file_content(new_req, old_req)
|
46 |
| - next if updated_content == file.content |
| 68 | + next if updated_content == file&.content |
47 | 69 |
|
48 |
| - file.content = updated_content |
| 70 | + file&.content = updated_content |
49 | 71 | file
|
50 | 72 | end
|
51 | 73 | end
|
52 | 74 |
|
| 75 | + sig do |
| 76 | + params( |
| 77 | + new_req: T::Hash[Symbol, T.untyped], |
| 78 | + old_req: T.nilable(T::Hash[Symbol, T.untyped]) |
| 79 | + ).returns(T.nilable(String)) |
| 80 | + end |
53 | 81 | def updated_requirement_or_setup_file_content(new_req, old_req)
|
54 | 82 | original_file = get_original_file(new_req.fetch(:file))
|
55 | 83 | raise "Could not find a dependency file for #{new_req}" unless original_file
|
56 | 84 |
|
| 85 | + original_content = original_file.content |
| 86 | + return original_content if original_content.nil? |
| 87 | + |
57 | 88 | RequirementReplacer.new(
|
58 |
| - content: original_file.content, |
| 89 | + content: original_content, |
59 | 90 | dependency_name: dependency.name,
|
60 |
| - old_requirement: old_req.fetch(:requirement), |
| 91 | + old_requirement: old_req&.fetch(:requirement), |
61 | 92 | new_requirement: new_req.fetch(:requirement),
|
62 | 93 | new_hash_version: dependency.version,
|
63 | 94 | index_urls: @index_urls
|
64 | 95 | ).updated_content
|
65 | 96 | end
|
66 | 97 |
|
| 98 | + sig do |
| 99 | + params(filename: String) |
| 100 | + .returns(T.nilable(Dependabot::DependencyFile)) |
| 101 | + end |
67 | 102 | def get_original_file(filename)
|
68 | 103 | dependency_files.find { |f| f.name == filename }
|
69 | 104 | end
|
|
0 commit comments