dependabot-composer 0.105.8 → 0.106.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: be28bd77a9cda4096d77edf0b2b46cb754945675fcf94ff5116ddf2990bac0df
4
- data.tar.gz: 2cd021107559f066f1dad3e907be59d977845590ea6afe171649920affb38a9f
3
+ metadata.gz: 3ef9fd7de0b59eb9fe8816348a9e61fc7f0749a2c7c813b670f99d9e1905f0b5
4
+ data.tar.gz: 2f6efd24e91c16c8606c9f7bf0149fdce654507d46ed88fecd32cee7bef2b495
5
5
  SHA512:
6
- metadata.gz: c5d00e5f824b536a3a7ff91290fe70f210a15779d9440fa80afcf10e7b4418b7dcb1ef77ac8ce0fc7431b45e7be171985a618c3720b11193d106606b98254210
7
- data.tar.gz: 19fee1537ada8208738122bfb2f539466dc39d9369ae884adb42850fc1469667bbbe1f4b62ea1cfa0441c1963d97cf6e96e213a971cae1e69096b784d3db429e
6
+ metadata.gz: e69c5f676e953f3bb32a1f73c2c9b5c34bcfb27c7febcd1bdd5d0be1d2eb7f0e9b368a5c593753c862751fc422d4ef4c4d5c662ce548b32ce9a4f2fd1df3789e
7
+ data.tar.gz: e44e14d4a09c29121540359cf454f85400a658baf3eb4a435f6f94b77ae6d55e03dfbfd3e83cf1cc1594c26f662c08cca7285190a74466f0df81e76eb9a29e90
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "excon"
4
3
  require "json"
5
4
  require "dependabot/update_checkers"
6
5
  require "dependabot/update_checkers/base"
@@ -12,6 +11,7 @@ module Dependabot
12
11
  class UpdateChecker < Dependabot::UpdateCheckers::Base
13
12
  require_relative "update_checker/requirements_updater"
14
13
  require_relative "update_checker/version_resolver"
14
+ require_relative "update_checker/latest_version_finder"
15
15
 
16
16
  def latest_version
17
17
  return nil if path_dependency?
@@ -49,7 +49,6 @@ module Dependabot
49
49
  def updated_requirements
50
50
  RequirementsUpdater.new(
51
51
  requirements: dependency.requirements,
52
- latest_version: latest_version&.to_s,
53
52
  latest_resolvable_version: latest_resolvable_version&.to_s,
54
53
  update_strategy: requirements_update_strategy
55
54
  ).updated_requirements
@@ -72,30 +71,22 @@ module Dependabot
72
71
  false
73
72
  end
74
73
 
75
- def latest_version_from_registry
76
- versions =
77
- registry_versions.
78
- select { |version| version_class.correct?(version.gsub(/^v/, "")) }.
79
- map { |version| version_class.new(version.gsub(/^v/, "")) }
80
-
81
- versions.reject!(&:prerelease?) unless wants_prerelease?
82
- versions.reject! { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } }
83
- versions.max
74
+ def updated_dependencies_after_full_unlock
75
+ raise NotImplementedError
84
76
  end
85
77
 
86
- def wants_prerelease?
87
- current_version = dependency.version
88
- if current_version && version_class.new(current_version).prerelease?
89
- return true
90
- end
91
-
92
- dependency.requirements.any? do |req|
93
- req[:requirement].match?(/\d-[A-Za-z]/)
94
- end
78
+ def latest_version_from_registry
79
+ latest_version_finder.latest_version
95
80
  end
96
81
 
97
- def updated_dependencies_after_full_unlock
98
- raise NotImplementedError
82
+ def latest_version_finder
83
+ @latest_version_finder ||= LatestVersionFinder.new(
84
+ dependency: dependency,
85
+ dependency_files: dependency_files,
86
+ credentials: credentials,
87
+ ignored_versions: ignored_versions,
88
+ security_advisories: security_advisories
89
+ )
99
90
  end
100
91
 
101
92
  def path_dependency?
@@ -110,71 +101,9 @@ module Dependabot
110
101
  composer_file
111
102
  end
112
103
 
113
- def lockfile
114
- dependency_files.find { |f| f.name == "composer.lock" }
115
- end
116
-
117
- def registry_versions
118
- return @registry_versions unless @registry_versions.nil?
119
-
120
- repositories =
121
- JSON.parse(composer_file.content).
122
- fetch("repositories", []).
123
- select { |r| r.is_a?(Hash) }
124
-
125
- urls = repositories.
126
- select { |h| h["type"] == "composer" }.
127
- map { |h| h["url"] }.compact.
128
- map { |url| url.gsub(%r{\/$}, "") + "/packages.json" }
129
-
130
- unless repositories.any? { |rep| rep["packagist.org"] == false }
131
- urls << "https://packagist.org/p/#{dependency.name.downcase}.json"
132
- end
133
-
134
- @registry_versions = []
135
- urls.each do |url|
136
- @registry_versions += fetch_registry_versions_from_url(url)
137
- end
138
- @registry_versions.uniq
139
- end
140
-
141
- def fetch_registry_versions_from_url(url)
142
- cred = registry_credentials.find { |c| url.include?(c["registry"]) }
143
-
144
- response = Excon.get(
145
- url,
146
- idempotent: true,
147
- user: cred&.fetch("username", nil),
148
- password: cred&.fetch("password", nil),
149
- **SharedHelpers.excon_defaults
150
- )
151
-
152
- parse_registry_response(response, url)
153
- rescue Excon::Error::Socket, Excon::Error::Timeout
154
- []
155
- end
156
-
157
- def parse_registry_response(response, url)
158
- return [] unless response.status == 200
159
-
160
- listing = JSON.parse(response.body)
161
- return [] if listing.nil?
162
- return [] if listing.fetch("packages", []) == []
163
- return [] unless listing.dig("packages", dependency.name.downcase)
164
-
165
- listing.dig("packages", dependency.name.downcase).keys
166
- rescue JSON::ParserError
167
- msg = "'#{url}' does not contain valid JSON"
168
- raise DependencyFileNotResolvable, msg
169
- end
170
-
171
104
  def library?
172
105
  JSON.parse(composer_file.content)["type"] == "library"
173
106
  end
174
-
175
- def registry_credentials
176
- credentials.select { |cred| cred["type"] == "composer_repository" }
177
- end
178
107
  end
179
108
  end
180
109
  end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "excon"
4
+ require "json"
5
+
6
+ require "dependabot/composer/update_checker"
7
+ require "dependabot/shared_helpers"
8
+ require "dependabot/errors"
9
+
10
+ module Dependabot
11
+ module Composer
12
+ class UpdateChecker
13
+ class LatestVersionFinder
14
+ def initialize(dependency:, dependency_files:, credentials:,
15
+ ignored_versions:, security_advisories:)
16
+ @dependency = dependency
17
+ @dependency_files = dependency_files
18
+ @credentials = credentials
19
+ @ignored_versions = ignored_versions
20
+ @security_advisories = security_advisories
21
+ end
22
+
23
+ def latest_version
24
+ @latest_version ||= fetch_latest_version
25
+ end
26
+
27
+ def lowest_security_fix_version
28
+ @lowest_security_fix_version ||= fetch_lowest_security_fix_version
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :dependency, :dependency_files, :credentials,
34
+ :ignored_versions, :security_advisories
35
+
36
+ def fetch_latest_version
37
+ versions = available_versions
38
+ versions = filter_prerelease_versions(versions)
39
+ versions = filter_ignored_versions(versions)
40
+ versions.max
41
+ end
42
+
43
+ def fetch_lowest_security_fix_version
44
+ versions = available_versions
45
+ versions = filter_prerelease_versions(versions)
46
+ versions = filter_ignored_versions(versions)
47
+ versions = filter_vulnerable_versions(versions)
48
+ versions = filter_lower_versions(versions)
49
+ versions.min
50
+ end
51
+
52
+ def filter_prerelease_versions(versions_array)
53
+ return versions_array if wants_prerelease?
54
+
55
+ versions_array.reject(&:prerelease?)
56
+ end
57
+
58
+ def filter_ignored_versions(versions_array)
59
+ versions_array.
60
+ reject { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } }
61
+ end
62
+
63
+ def filter_vulnerable_versions(versions_array)
64
+ versions_array.
65
+ reject { |v| security_advisories.any? { |a| a.vulnerable?(v) } }
66
+ end
67
+
68
+ def filter_lower_versions(versions_array)
69
+ versions_array.
70
+ select { |version| version > version_class.new(dependency.version) }
71
+ end
72
+
73
+ def wants_prerelease?
74
+ current_version = dependency.version
75
+ if current_version && version_class.new(current_version).prerelease?
76
+ return true
77
+ end
78
+
79
+ dependency.requirements.any? do |req|
80
+ req[:requirement].match?(/\d-[A-Za-z]/)
81
+ end
82
+ end
83
+
84
+ def available_versions
85
+ registry_version_details.
86
+ select { |version| version_class.correct?(version.gsub(/^v/, "")) }.
87
+ map { |version| version_class.new(version.gsub(/^v/, "")) }
88
+ end
89
+
90
+ def registry_version_details
91
+ return @registry_version_details unless @registry_version_details.nil?
92
+
93
+ repositories =
94
+ JSON.parse(composer_file.content).
95
+ fetch("repositories", []).
96
+ select { |r| r.is_a?(Hash) }
97
+
98
+ urls = repositories.
99
+ select { |h| h["type"] == "composer" }.
100
+ map { |h| h["url"] }.compact.
101
+ map { |url| url.gsub(%r{\/$}, "") + "/packages.json" }
102
+
103
+ unless repositories.any? { |rep| rep["packagist.org"] == false }
104
+ urls << "https://packagist.org/p/#{dependency.name.downcase}.json"
105
+ end
106
+
107
+ @registry_version_details = []
108
+ urls.each do |url|
109
+ @registry_version_details += fetch_registry_versions_from_url(url)
110
+ end
111
+ @registry_version_details.uniq
112
+ end
113
+
114
+ def fetch_registry_versions_from_url(url)
115
+ cred = registry_credentials.find { |c| url.include?(c["registry"]) }
116
+
117
+ response = Excon.get(
118
+ url,
119
+ idempotent: true,
120
+ user: cred&.fetch("username", nil),
121
+ password: cred&.fetch("password", nil),
122
+ **SharedHelpers.excon_defaults
123
+ )
124
+
125
+ parse_registry_response(response, url)
126
+ rescue Excon::Error::Socket, Excon::Error::Timeout
127
+ []
128
+ end
129
+
130
+ def parse_registry_response(response, url)
131
+ return [] unless response.status == 200
132
+
133
+ listing = JSON.parse(response.body)
134
+ return [] if listing.nil?
135
+ return [] if listing.fetch("packages", []) == []
136
+ return [] unless listing.dig("packages", dependency.name.downcase)
137
+
138
+ listing.dig("packages", dependency.name.downcase).keys
139
+ rescue JSON::ParserError
140
+ msg = "'#{url}' does not contain valid JSON"
141
+ raise DependencyFileNotResolvable, msg
142
+ end
143
+
144
+ def registry_credentials
145
+ credentials.select { |cred| cred["type"] == "composer_repository" }
146
+ end
147
+
148
+ def composer_file
149
+ composer_file =
150
+ dependency_files.find { |f| f.name == "composer.json" }
151
+ raise "No composer.json!" unless composer_file
152
+
153
+ composer_file
154
+ end
155
+
156
+ def ignore_reqs
157
+ ignored_versions.map { |req| requirement_class.new(req.split(",")) }
158
+ end
159
+
160
+ def version_class
161
+ Utils.version_class_for_package_manager(dependency.package_manager)
162
+ end
163
+
164
+ def requirement_class
165
+ Utils.requirement_class_for_package_manager(
166
+ dependency.package_manager
167
+ )
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -24,13 +24,12 @@ module Dependabot
24
24
  %i(widen_ranges bump_versions bump_versions_if_necessary).freeze
25
25
 
26
26
  def initialize(requirements:, update_strategy:,
27
- latest_version:, latest_resolvable_version:)
27
+ latest_resolvable_version:)
28
28
  @requirements = requirements
29
29
  @update_strategy = update_strategy
30
30
 
31
31
  check_update_strategy
32
32
 
33
- @latest_version = version_class.new(latest_version) if latest_version
34
33
  return unless latest_resolvable_version
35
34
 
36
35
  @latest_resolvable_version =
@@ -46,7 +45,7 @@ module Dependabot
46
45
  private
47
46
 
48
47
  attr_reader :requirements, :update_strategy,
49
- :latest_version, :latest_resolvable_version
48
+ :latest_resolvable_version
50
49
 
51
50
  def check_update_strategy
52
51
  return if ALLOWED_UPDATE_STRATEGIES.include?(update_strategy)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-composer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.105.8
4
+ version: 0.106.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-19 00:00:00.000000000 Z
11
+ date: 2019-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.105.8
19
+ version: 0.106.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.105.8
26
+ version: 0.106.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -166,6 +166,7 @@ files:
166
166
  - lib/dependabot/composer/native_helpers.rb
167
167
  - lib/dependabot/composer/requirement.rb
168
168
  - lib/dependabot/composer/update_checker.rb
169
+ - lib/dependabot/composer/update_checker/latest_version_finder.rb
169
170
  - lib/dependabot/composer/update_checker/requirements_updater.rb
170
171
  - lib/dependabot/composer/update_checker/version_resolver.rb
171
172
  - lib/dependabot/composer/version.rb