dependabot-core 0.79.4 → 0.80.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/dependabot/file_fetchers.rb +0 -2
  4. data/lib/dependabot/file_parsers.rb +0 -2
  5. data/lib/dependabot/file_updaters.rb +0 -2
  6. data/lib/dependabot/file_updaters/ruby/.DS_Store +0 -0
  7. data/lib/dependabot/metadata_finders.rb +0 -2
  8. data/lib/dependabot/update_checkers.rb +0 -2
  9. data/lib/dependabot/utils.rb +0 -4
  10. data/lib/dependabot/version.rb +1 -1
  11. metadata +2 -20
  12. data/lib/dependabot/file_fetchers/dotnet/nuget.rb +0 -215
  13. data/lib/dependabot/file_fetchers/dotnet/nuget/import_paths_finder.rb +0 -51
  14. data/lib/dependabot/file_fetchers/dotnet/nuget/sln_project_paths_finder.rb +0 -55
  15. data/lib/dependabot/file_parsers/dotnet/nuget.rb +0 -85
  16. data/lib/dependabot/file_parsers/dotnet/nuget/packages_config_parser.rb +0 -65
  17. data/lib/dependabot/file_parsers/dotnet/nuget/project_file_parser.rb +0 -156
  18. data/lib/dependabot/file_parsers/dotnet/nuget/property_value_finder.rb +0 -131
  19. data/lib/dependabot/file_updaters/dotnet/nuget.rb +0 -151
  20. data/lib/dependabot/file_updaters/dotnet/nuget/packages_config_declaration_finder.rb +0 -69
  21. data/lib/dependabot/file_updaters/dotnet/nuget/project_file_declaration_finder.rb +0 -78
  22. data/lib/dependabot/file_updaters/dotnet/nuget/property_value_updater.rb +0 -64
  23. data/lib/dependabot/metadata_finders/dotnet/nuget.rb +0 -116
  24. data/lib/dependabot/update_checkers/dotnet/nuget.rb +0 -127
  25. data/lib/dependabot/update_checkers/dotnet/nuget/property_updater.rb +0 -97
  26. data/lib/dependabot/update_checkers/dotnet/nuget/repository_finder.rb +0 -232
  27. data/lib/dependabot/update_checkers/dotnet/nuget/requirements_updater.rb +0 -81
  28. data/lib/dependabot/update_checkers/dotnet/nuget/version_finder.rb +0 -231
  29. data/lib/dependabot/utils/dotnet/requirement.rb +0 -90
  30. data/lib/dependabot/utils/dotnet/version.rb +0 -22
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_parsers/dotnet/nuget"
4
- require "dependabot/update_checkers/base"
5
-
6
- module Dependabot
7
- module UpdateCheckers
8
- module Dotnet
9
- class Nuget < Dependabot::UpdateCheckers::Base
10
- require_relative "nuget/version_finder"
11
- require_relative "nuget/property_updater"
12
- require_relative "nuget/requirements_updater"
13
-
14
- def latest_version
15
- @latest_version = latest_version_details&.fetch(:version)
16
- end
17
-
18
- def latest_resolvable_version
19
- # TODO: Check version resolution!
20
- return nil if version_comes_from_multi_dependency_property?
21
-
22
- latest_version
23
- end
24
-
25
- def latest_resolvable_version_with_no_unlock
26
- # Irrelevant, since Nuget has a single dependency file
27
- nil
28
- end
29
-
30
- def updated_requirements
31
- RequirementsUpdater.new(
32
- requirements: dependency.requirements,
33
- latest_version: latest_version&.to_s,
34
- source_details: latest_version_details&.
35
- slice(:nuspec_url, :repo_url, :source_url)
36
- ).updated_requirements
37
- end
38
-
39
- def up_to_date?
40
- # If any requirements have an uninterpolated property in them then
41
- # that property couldn't be found, and we assume that the dependency
42
- # is up-to-date
43
- return true unless requirements_unlocked_or_can_be?
44
-
45
- super
46
- end
47
-
48
- def requirements_unlocked_or_can_be?
49
- # If any requirements have an uninterpolated property in them then
50
- # that property couldn't be found, and the requirement therefore
51
- # cannot be unlocked (since we can't update that property)
52
- namespace = FileParsers::Dotnet::Nuget::PropertyValueFinder
53
- dependency.requirements.none? do |req|
54
- req.fetch(:requirement)&.match?(namespace::PROPERTY_REGEX)
55
- end
56
- end
57
-
58
- private
59
-
60
- def latest_version_resolvable_with_full_unlock?
61
- return false unless version_comes_from_multi_dependency_property?
62
-
63
- property_updater.update_possible?
64
- end
65
-
66
- def updated_dependencies_after_full_unlock
67
- property_updater.updated_dependencies
68
- end
69
-
70
- def latest_version_details
71
- @latest_version_details ||= version_finder.latest_version_details
72
- end
73
-
74
- def version_finder
75
- @version_finder ||=
76
- VersionFinder.new(
77
- dependency: dependency,
78
- dependency_files: dependency_files,
79
- credentials: credentials,
80
- ignored_versions: ignored_versions
81
- )
82
- end
83
-
84
- def property_updater
85
- @property_updater ||=
86
- PropertyUpdater.new(
87
- dependency: dependency,
88
- dependency_files: dependency_files,
89
- target_version_details: latest_version_details,
90
- credentials: credentials,
91
- ignored_versions: ignored_versions
92
- )
93
- end
94
-
95
- def version_comes_from_multi_dependency_property?
96
- declarations_using_a_property.any? do |requirement|
97
- property_name = requirement.fetch(:metadata).fetch(:property_name)
98
-
99
- all_property_based_dependencies.any? do |dep|
100
- next false if dep.name == dependency.name
101
-
102
- dep.requirements.any? do |req|
103
- req.dig(:metadata, :property_name) == property_name
104
- end
105
- end
106
- end
107
- end
108
-
109
- def declarations_using_a_property
110
- @declarations_using_a_property ||=
111
- dependency.requirements.
112
- select { |req| req.dig(:metadata, :property_name) }
113
- end
114
-
115
- def all_property_based_dependencies
116
- @all_property_based_dependencies ||=
117
- FileParsers::Dotnet::Nuget.new(
118
- dependency_files: dependency_files,
119
- source: nil
120
- ).parse.select do |dep|
121
- dep.requirements.any? { |req| req.dig(:metadata, :property_name) }
122
- end
123
- end
124
- end
125
- end
126
- end
127
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/file_parsers/dotnet/nuget"
4
- require "dependabot/update_checkers/dotnet/nuget"
5
-
6
- module Dependabot
7
- module UpdateCheckers
8
- module Dotnet
9
- class Nuget
10
- class PropertyUpdater
11
- require_relative "version_finder"
12
- require_relative "requirements_updater"
13
-
14
- def initialize(dependency:, dependency_files:, credentials:,
15
- target_version_details:, ignored_versions:)
16
- @dependency = dependency
17
- @dependency_files = dependency_files
18
- @credentials = credentials
19
- @ignored_versions = ignored_versions
20
- @target_version = target_version_details&.fetch(:version)
21
- @source_details = target_version_details&.
22
- slice(:nuspec_url, :repo_url, :source_url)
23
- end
24
-
25
- def update_possible?
26
- return false unless target_version
27
-
28
- @update_possible ||=
29
- dependencies_using_property.all? do |dep|
30
- versions = VersionFinder.new(
31
- dependency: dep,
32
- dependency_files: dependency_files,
33
- credentials: credentials,
34
- ignored_versions: ignored_versions
35
- ).versions.map { |v| v.fetch(:version) }
36
-
37
- versions.include?(target_version) || versions.none?
38
- end
39
- end
40
-
41
- def updated_dependencies
42
- raise "Update not possible!" unless update_possible?
43
-
44
- @updated_dependencies ||=
45
- dependencies_using_property.map do |dep|
46
- Dependency.new(
47
- name: dep.name,
48
- version: target_version.to_s,
49
- requirements: updated_requirements(dep),
50
- previous_version: dep.version,
51
- previous_requirements: dep.requirements,
52
- package_manager: dep.package_manager
53
- )
54
- end
55
- end
56
-
57
- private
58
-
59
- attr_reader :dependency, :dependency_files, :target_version,
60
- :source_details, :credentials, :ignored_versions
61
-
62
- def dependencies_using_property
63
- @dependencies_using_property ||=
64
- FileParsers::Dotnet::Nuget.new(
65
- dependency_files: dependency_files,
66
- source: nil
67
- ).parse.select do |dep|
68
- dep.requirements.any? do |r|
69
- r.dig(:metadata, :property_name) == property_name
70
- end
71
- end
72
- end
73
-
74
- def property_name
75
- @property_name ||= dependency.requirements.
76
- find { |r| r.dig(:metadata, :property_name) }&.
77
- dig(:metadata, :property_name)
78
-
79
- raise "No requirement with a property name!" unless @property_name
80
-
81
- @property_name
82
- end
83
-
84
- def updated_requirements(dep)
85
- @updated_requirements ||= {}
86
- @updated_requirements[dep.name] ||=
87
- RequirementsUpdater.new(
88
- requirements: dep.requirements,
89
- latest_version: target_version,
90
- source_details: source_details
91
- ).updated_requirements
92
- end
93
- end
94
- end
95
- end
96
- end
97
- end
@@ -1,232 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "excon"
4
- require "nokogiri"
5
- require "dependabot/errors"
6
- require "dependabot/update_checkers/dotnet/nuget"
7
- require "dependabot/shared_helpers"
8
-
9
- module Dependabot
10
- module UpdateCheckers
11
- module Dotnet
12
- class Nuget
13
- class RepositoryFinder
14
- DEFAULT_REPOSITORY_URL = "https://api.nuget.org/v3/index.json"
15
-
16
- def initialize(dependency:, credentials:, config_file: nil)
17
- @dependency = dependency
18
- @credentials = credentials
19
- @config_file = config_file
20
- end
21
-
22
- def dependency_urls
23
- find_dependency_urls
24
- end
25
-
26
- private
27
-
28
- attr_reader :dependency, :credentials, :config_file
29
-
30
- def find_dependency_urls
31
- @find_dependency_urls ||=
32
- known_repositories.flat_map do |details|
33
- if details.fetch(:url) == DEFAULT_REPOSITORY_URL
34
- # Save a request for the default URL, since we already how
35
- # it addresses packages
36
- next default_repository_details
37
- end
38
-
39
- build_url_for_details(details)
40
- end.compact.uniq
41
- end
42
-
43
- def build_url_for_details(repo_details)
44
- response = get_repo_metadata(repo_details)
45
- check_repo_reponse(response, repo_details)
46
- return unless response.status == 200
47
-
48
- base_url = base_url_from_v3_metadata(JSON.parse(response.body))
49
- search_url = search_url_from_v3_metadata(JSON.parse(response.body))
50
-
51
- details = {
52
- repository_url: repo_details.fetch(:url),
53
- auth_header: auth_header_for_token(repo_details.fetch(:token)),
54
- repository_type: "v3"
55
- }
56
- if base_url
57
- details[:versions_url] =
58
- File.join(base_url, dependency.name.downcase, "index.json")
59
- end
60
- if search_url
61
- details[:search_url] =
62
- search_url + "?q=#{dependency.name.downcase}&prerelease=true"
63
- end
64
- details
65
- rescue JSON::ParserError
66
- build_v2_url(response, repo_details)
67
- rescue Excon::Error::Timeout, Excon::Error::Socket
68
- handle_timeout(repo_metadata_url: repo_details.fetch(:url))
69
- end
70
-
71
- def get_repo_metadata(repo_details)
72
- Excon.get(
73
- repo_details.fetch(:url),
74
- headers: auth_header_for_token(repo_details.fetch(:token)),
75
- idempotent: true,
76
- **SharedHelpers.excon_defaults
77
- )
78
- end
79
-
80
- def base_url_from_v3_metadata(metadata)
81
- metadata.
82
- fetch("resources", []).
83
- find { |r| r.fetch("@type") == "PackageBaseAddress/3.0.0" }&.
84
- fetch("@id")
85
- end
86
-
87
- def search_url_from_v3_metadata(metadata)
88
- metadata.
89
- fetch("resources", []).
90
- find { |r| r.fetch("@type") == "SearchQueryService" }&.
91
- fetch("@id")
92
- end
93
-
94
- def build_v2_url(response, repo_details)
95
- doc = Nokogiri::XML(response.body)
96
- doc.remove_namespaces!
97
- base_url = doc.at_xpath("service")&.attributes&.fetch("base")&.value
98
- return unless base_url
99
-
100
- {
101
- repository_url: base_url,
102
- versions_url: File.join(
103
- base_url,
104
- "FindPackagesById()?id='#{dependency.name}'"
105
- ),
106
- auth_header: auth_header_for_token(repo_details.fetch(:token)),
107
- repository_type: "v2"
108
- }
109
- end
110
-
111
- def check_repo_reponse(response, details)
112
- return unless [401, 402, 403].include?(response.status)
113
- raise if details.fetch(:url) == DEFAULT_REPOSITORY_URL
114
-
115
- raise PrivateSourceAuthenticationFailure, details.fetch(:url)
116
- end
117
-
118
- def handle_timeout(repo_metadata_url:)
119
- raise if repo_metadata_url == DEFAULT_REPOSITORY_URL
120
-
121
- raise PrivateSourceTimedOut, repo_metadata_url
122
- end
123
-
124
- def known_repositories
125
- return @known_repositories if @known_repositories
126
-
127
- @known_repositories = []
128
- @known_repositories += credential_repositories
129
- @known_repositories += config_file_repositories
130
-
131
- if @known_repositories.empty?
132
- @known_repositories << { url: DEFAULT_REPOSITORY_URL, token: nil }
133
- end
134
-
135
- @known_repositories.uniq
136
- end
137
-
138
- def credential_repositories
139
- @credential_repositories ||=
140
- credentials.
141
- select { |cred| cred["type"] == "nuget_feed" }.
142
- map { |c| { url: c.fetch("url"), token: c["token"] } }
143
- end
144
-
145
- def config_file_repositories
146
- return [] unless config_file
147
-
148
- doc = Nokogiri::XML(config_file.content)
149
- doc.remove_namespaces!
150
- sources =
151
- doc.css("configuration > packageSources > add").map do |node|
152
- {
153
- key:
154
- node.attribute("key")&.value&.strip ||
155
- node.at_xpath("./key")&.content&.strip,
156
- url:
157
- node.attribute("value")&.value&.strip ||
158
- node.at_xpath("./value")&.content&.strip
159
- }
160
- end
161
-
162
- sources.reject! do |s|
163
- known_urls = credential_repositories.map { |cr| cr.fetch(:url) }
164
- known_urls.include?(s.fetch(:url))
165
- end
166
-
167
- add_config_file_credentials(sources: sources, doc: doc)
168
- sources.each { |details| details.delete(:key) }
169
-
170
- sources
171
- end
172
-
173
- def default_repository_details
174
- {
175
- repository_url: DEFAULT_REPOSITORY_URL,
176
- versions_url: "https://api.nuget.org/v3-flatcontainer/"\
177
- "#{dependency.name.downcase}/index.json",
178
- search_url: "https://api-v2v3search-0.nuget.org/query"\
179
- "?q=#{dependency.name.downcase}&prerelease=true",
180
- auth_header: {},
181
- repository_type: "v3"
182
- }
183
- end
184
-
185
- def add_config_file_credentials(sources:, doc:)
186
- sources.each do |source_details|
187
- key = source_details.fetch(:key)
188
- next source_details[:token] = nil unless key
189
- next source_details[:token] = nil if key.match?(/^\d/)
190
-
191
- tag = key.gsub(" ", "_x0020_")
192
- creds_nodes = doc.css("configuration > packageSourceCredentials "\
193
- "> #{tag} > add")
194
-
195
- username =
196
- creds_nodes.
197
- find { |n| n.attribute("key")&.value == "Username" }&.
198
- attribute("value")&.value
199
- password =
200
- creds_nodes.
201
- find { |n| n.attribute("key")&.value == "ClearTextPassword" }&.
202
- attribute("value")&.value
203
-
204
- # Note: We have to look for plain text passwords, as we have no
205
- # way of decrypting encrypted passwords. For the same reason we
206
- # don't fetch API keys from the nuget.config at all.
207
- next source_details[:token] = nil unless username && password
208
-
209
- source_details[:token] = "#{username}:#{password}"
210
- end
211
-
212
- sources
213
- end
214
-
215
- def auth_header_for_token(token)
216
- return {} unless token
217
-
218
- if token.include?(":")
219
- encoded_token = Base64.encode64(token).delete("\n")
220
- { "Authorization" => "Basic #{encoded_token}" }
221
- elsif Base64.decode64(token).ascii_only? &&
222
- Base64.decode64(token).include?(":")
223
- { "Authorization" => "Basic #{token.delete("\n")}" }
224
- else
225
- { "Authorization" => "Bearer #{token}" }
226
- end
227
- end
228
- end
229
- end
230
- end
231
- end
232
- end