dependabot-bundler 0.103.3 → 0.104.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 214bad1306bd5538779ee55ebeeb76af02b308953e71fe653d7a63b673c2dd3c
4
- data.tar.gz: 47e3c1131ef1081a2ef05c7cd999c03520a2379864e387d459a875fff67bef46
3
+ metadata.gz: b3955c8a3cb5756607028ee4f13ca8ffd2f8578f9b4c5b247fc56ccc7f4865d2
4
+ data.tar.gz: 5b18aa92559e79eab68c4f70e39213ed32aee3e6324ce0f7acf38693d7f0c4b3
5
5
  SHA512:
6
- metadata.gz: 52b483b4826f43a8c7df4f3cd063078928549ec89c412cea2767287a66ff11ae571657fecf1b1dc3f2603e8db184bb3a6895cf9ddfaa205d64611a04595172e6
7
- data.tar.gz: f30c7a957cfc0e0dd1104a6c0b29f46c63b1adf0b1d1957dce8a5eaac826f8df0493adadf90e0a63d564d22e46cf5b477d815d83c7a2e5a16df1eea5035626fa
6
+ metadata.gz: dadadec7982214f33fadacc7708b0a238b62ef1fc64d07cf2de1600194c0a28fc179d45909f98ae96e37012f26f5a5d151f310560e2b20bccb36b0a60e634c07
7
+ data.tar.gz: d8ad86d4c6899e16442f021fe69d9aaf4bfc15703ae5bc8609c4e032603cb243e35af7518e4d48d0cd21236ef23a42fc9adb80d9ff55d721fe87d1d29e983b3f
@@ -6,6 +6,7 @@ require "dependabot/bundler/file_updater/requirement_replacer"
6
6
  require "dependabot/bundler/version"
7
7
  require "dependabot/git_commit_checker"
8
8
 
9
+ # rubocop:disable Metrics/ClassLength
9
10
  module Dependabot
10
11
  module Bundler
11
12
  class UpdateChecker < Dependabot::UpdateCheckers::Base
@@ -27,6 +28,18 @@ module Dependabot
27
28
  latest_resolvable_version_details&.fetch(:version)
28
29
  end
29
30
 
31
+ def lowest_resolvable_security_fix_version
32
+ raise "Dependency not vulnerable!" unless vulnerable?
33
+ return latest_resolvable_version if git_dependency?
34
+
35
+ lowest_fix =
36
+ latest_version_finder(remove_git_source: false).
37
+ lowest_security_fix_version
38
+ return unless lowest_fix
39
+
40
+ resolvable?(lowest_fix) ? lowest_fix : latest_resolvable_version
41
+ end
42
+
30
43
  def latest_resolvable_version_with_no_unlock
31
44
  current_ver = dependency.version
32
45
  return current_ver if git_dependency? && git_commit_checker.pinned?
@@ -63,18 +76,15 @@ module Dependabot
63
76
  updated_source: updated_source,
64
77
  latest_version: latest_version_details&.fetch(:version)&.to_s,
65
78
  latest_resolvable_version:
66
- latest_resolvable_version_details&.fetch(:version)&.to_s
79
+ preferred_resolvable_version_details&.fetch(:version)&.to_s
67
80
  ).updated_requirements
68
81
  end
69
82
  end
70
83
 
71
84
  def requirements_unlocked_or_can_be?
72
85
  dependency.requirements.
73
- reject { |r| r[:requirement].nil? }.
86
+ select { |r| requirement_class.new(r[:requirement]).specific? }.
74
87
  all? do |req|
75
- requirement = requirement_class.new(req[:requirement])
76
- next true if requirement.satisfied_by?(Gem::Version.new("100000"))
77
-
78
88
  file = dependency_files.find { |f| f.name == req.fetch(:file) }
79
89
  updated = FileUpdater::RequirementReplacer.new(
80
90
  dependency: dependency,
@@ -118,10 +128,36 @@ module Dependabot
118
128
  force_updater.updated_dependencies
119
129
  end
120
130
 
131
+ def preferred_resolvable_version_details
132
+ if vulnerable?
133
+ return { version: lowest_resolvable_security_fix_version }
134
+ end
135
+
136
+ latest_resolvable_version_details
137
+ end
138
+
121
139
  def git_dependency?
122
140
  git_commit_checker.git_dependency?
123
141
  end
124
142
 
143
+ def resolvable?(version)
144
+ @resolvable ||= {}
145
+ @resolvable[version] ||=
146
+ begin
147
+ ForceUpdater.new(
148
+ dependency: dependency,
149
+ dependency_files: dependency_files,
150
+ credentials: credentials,
151
+ target_version: version,
152
+ requirements_update_strategy: requirements_update_strategy,
153
+ update_multiple_dependencies: false
154
+ ).updated_dependencies
155
+ true
156
+ rescue Dependabot::DependencyFileNotResolvable
157
+ false
158
+ end
159
+ end
160
+
125
161
  def latest_version_details(remove_git_source: false)
126
162
  @latest_version_details ||= {}
127
163
  @latest_version_details[remove_git_source] ||=
@@ -331,7 +367,8 @@ module Dependabot
331
367
  dependency: dependency,
332
368
  dependency_files: prepared_dependency_files,
333
369
  credentials: credentials,
334
- ignored_versions: ignored_versions
370
+ ignored_versions: ignored_versions,
371
+ security_advisories: security_advisories
335
372
  )
336
373
  end
337
374
  end
@@ -349,6 +386,7 @@ module Dependabot
349
386
  end
350
387
  end
351
388
  end
389
+ # rubocop:enable Metrics/ClassLength
352
390
 
353
391
  Dependabot::UpdateCheckers.
354
392
  register("bundler", Dependabot::Bundler::UpdateChecker)
@@ -16,12 +16,14 @@ module Dependabot
16
16
  class UpdateChecker
17
17
  class ForceUpdater
18
18
  def initialize(dependency:, dependency_files:, credentials:,
19
- target_version:, requirements_update_strategy:)
19
+ target_version:, requirements_update_strategy:,
20
+ update_multiple_dependencies: true)
20
21
  @dependency = dependency
21
22
  @dependency_files = dependency_files
22
23
  @credentials = credentials
23
24
  @target_version = target_version
24
25
  @requirements_update_strategy = requirements_update_strategy
26
+ @update_multiple_dependencies = update_multiple_dependencies
25
27
  end
26
28
 
27
29
  def updated_dependencies
@@ -33,6 +35,10 @@ module Dependabot
33
35
  attr_reader :dependency, :dependency_files, :credentials,
34
36
  :target_version, :requirements_update_strategy
35
37
 
38
+ def update_multiple_dependencies?
39
+ @update_multiple_dependencies
40
+ end
41
+
36
42
  def force_update
37
43
  in_a_temporary_bundler_context do
38
44
  other_updates = []
@@ -43,6 +49,8 @@ module Dependabot
43
49
  specs = definition.resolve
44
50
  dependencies_from([dependency] + other_updates, specs)
45
51
  rescue ::Bundler::VersionConflict => e
52
+ raise unless update_multiple_dependencies?
53
+
46
54
  # TODO: Not sure this won't unlock way too many things...
47
55
  new_dependencies_to_unlock =
48
56
  new_dependencies_to_unlock_from(
@@ -19,82 +19,116 @@ module Dependabot
19
19
  include SharedBundlerHelpers
20
20
 
21
21
  def initialize(dependency:, dependency_files:, credentials:,
22
- ignored_versions:)
23
- @dependency = dependency
24
- @dependency_files = dependency_files
25
- @credentials = credentials
26
- @ignored_versions = ignored_versions
22
+ ignored_versions:, security_advisories:)
23
+ @dependency = dependency
24
+ @dependency_files = dependency_files
25
+ @credentials = credentials
26
+ @ignored_versions = ignored_versions
27
+ @security_advisories = security_advisories
27
28
  end
28
29
 
29
30
  def latest_version_details
30
31
  @latest_version_details ||= fetch_latest_version_details
31
32
  end
32
33
 
34
+ def lowest_security_fix_version
35
+ @lowest_security_fix_version ||= fetch_lowest_security_fix_version
36
+ end
37
+
33
38
  private
34
39
 
35
40
  attr_reader :dependency, :dependency_files, :credentials,
36
- :ignored_versions
41
+ :ignored_versions, :security_advisories
37
42
 
38
43
  def fetch_latest_version_details
39
- return latest_rubygems_version_details if dependency.name == "bundler"
40
-
41
- case dependency_source
42
- when NilClass then latest_rubygems_version_details
43
- when ::Bundler::Source::Rubygems
44
- if dependency_source.remotes.none? ||
45
- dependency_source.remotes.first.to_s == "https://rubygems.org/"
46
- latest_rubygems_version_details
47
- else
48
- latest_private_version_details
49
- end
50
- when ::Bundler::Source::Git then latest_git_version_details
44
+ if dependency_source.is_a?(::Bundler::Source::Git) &&
45
+ dependency.name != "bundler"
46
+ return latest_git_version_details
51
47
  end
48
+
49
+ relevant_versions = registry_versions
50
+ relevant_versions = filter_prerelease_versions(relevant_versions)
51
+ relevant_versions = filter_ignored_versions(relevant_versions)
52
+
53
+ relevant_versions.empty? ? nil : { version: relevant_versions.max }
52
54
  end
53
55
 
54
- def latest_rubygems_version_details
55
- response = Excon.get(
56
- "https://rubygems.org/api/v1/versions/#{dependency.name}.json",
57
- idempotent: true,
58
- **SharedHelpers.excon_defaults
59
- )
56
+ def fetch_lowest_security_fix_version
57
+ return if dependency_source.is_a?(::Bundler::Source::Git)
60
58
 
61
- relevant_versions =
62
- JSON.parse(response.body).
63
- reject do |d|
64
- version = Gem::Version.new(d["number"])
65
- next true if version.prerelease? && !wants_prerelease?
66
- next true if ignore_reqs.any? { |r| r.satisfied_by?(version) }
59
+ relevant_versions = registry_versions
60
+ relevant_versions = filter_prerelease_versions(relevant_versions)
61
+ relevant_versions = filter_ignored_versions(relevant_versions)
62
+ relevant_versions = filter_vulnerable_versions(relevant_versions)
63
+ relevant_versions = filter_lower_versions(relevant_versions)
67
64
 
68
- false
69
- end
65
+ relevant_versions.min
66
+ end
70
67
 
71
- dep = relevant_versions.max_by { |d| Gem::Version.new(d["number"]) }
72
- return unless dep
68
+ def filter_prerelease_versions(versions_array)
69
+ versions_array.
70
+ reject { |v| v.prerelease? && !wants_prerelease? }
71
+ end
72
+
73
+ def filter_ignored_versions(versions_array)
74
+ versions_array.
75
+ reject { |v| ignore_reqs.any? { |r| r.satisfied_by?(v) } }
76
+ end
77
+
78
+ def filter_vulnerable_versions(versions_array)
79
+ arr = versions_array
80
+
81
+ security_advisories.each do |advisory|
82
+ arr = arr.reject { |v| advisory.vulnerable?(v) }
83
+ end
84
+
85
+ arr
86
+ end
73
87
 
74
- {
75
- version: Gem::Version.new(dep["number"]),
76
- sha: dep["sha"]
77
- }
88
+ def filter_lower_versions(versions_array)
89
+ versions_array.
90
+ select { |version| version > Gem::Version.new(dependency.version) }
91
+ end
92
+
93
+ def registry_versions
94
+ return rubygems_versions if dependency.name == "bundler"
95
+ return rubygems_versions unless dependency_source
96
+ return [] unless dependency_source.is_a?(::Bundler::Source::Rubygems)
97
+
98
+ remote = dependency_source.remotes.first
99
+ return rubygems_versions if remote.nil?
100
+ return rubygems_versions if remote.to_s == "https://rubygems.org/"
101
+
102
+ private_registry_versions
103
+ end
104
+
105
+ def rubygems_versions
106
+ @rubygems_versions ||=
107
+ begin
108
+ response = Excon.get(
109
+ "https://rubygems.org/api/v1/versions/#{dependency.name}.json",
110
+ idempotent: true,
111
+ **SharedHelpers.excon_defaults
112
+ )
113
+
114
+ JSON.parse(response.body).
115
+ map { |d| Gem::Version.new(d["number"]) }
116
+ end
78
117
  rescue JSON::ParserError, Excon::Error::Timeout
79
- nil
118
+ @rubygems_versions = []
80
119
  end
81
120
 
82
- def latest_private_version_details
83
- in_a_temporary_bundler_context do
84
- spec =
121
+ def private_registry_versions
122
+ @private_registry_versions ||=
123
+ in_a_temporary_bundler_context do
85
124
  dependency_source.
86
- fetchers.flat_map do |fetcher|
87
- fetcher.
88
- specs_with_retry([dependency.name], dependency_source).
89
- search_all(dependency.name).
90
- reject { |s| s.version.prerelease? && !wants_prerelease? }.
91
- reject do |s|
92
- ignore_reqs.any? { |r| r.satisfied_by?(s.version) }
93
- end
94
- end.
95
- max_by(&:version)
96
- spec.nil? ? nil : { version: spec.version }
97
- end
125
+ fetchers.flat_map do |fetcher|
126
+ fetcher.
127
+ specs_with_retry([dependency.name], dependency_source).
128
+ search_all(dependency.name)
129
+ end.
130
+ map(&:version)
131
+ end
98
132
  end
99
133
 
100
134
  def latest_git_version_details
@@ -270,7 +270,8 @@ module Dependabot
270
270
  dependency: dependency,
271
271
  dependency_files: dependency_files,
272
272
  credentials: credentials,
273
- ignored_versions: ignored_versions
273
+ ignored_versions: ignored_versions,
274
+ security_advisories: []
274
275
  ).latest_version_details
275
276
  end
276
277
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.103.3
4
+ version: 0.104.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-14 00:00:00.000000000 Z
11
+ date: 2019-04-16 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.103.3
19
+ version: 0.104.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.103.3
26
+ version: 0.104.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement