dependabot-bundler 0.95.5 → 0.95.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. metadata +4 -38
  3. data/helpers/Makefile +0 -9
  4. data/helpers/build +0 -26
  5. data/lib/dependabot/bundler.rb +0 -27
  6. data/lib/dependabot/bundler/file_fetcher.rb +0 -216
  7. data/lib/dependabot/bundler/file_fetcher/child_gemfile_finder.rb +0 -68
  8. data/lib/dependabot/bundler/file_fetcher/gemspec_finder.rb +0 -96
  9. data/lib/dependabot/bundler/file_fetcher/path_gemspec_finder.rb +0 -112
  10. data/lib/dependabot/bundler/file_fetcher/require_relative_finder.rb +0 -65
  11. data/lib/dependabot/bundler/file_parser.rb +0 -297
  12. data/lib/dependabot/bundler/file_parser/file_preparer.rb +0 -84
  13. data/lib/dependabot/bundler/file_parser/gemfile_checker.rb +0 -46
  14. data/lib/dependabot/bundler/file_updater.rb +0 -125
  15. data/lib/dependabot/bundler/file_updater/gemfile_updater.rb +0 -114
  16. data/lib/dependabot/bundler/file_updater/gemspec_dependency_name_finder.rb +0 -50
  17. data/lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb +0 -298
  18. data/lib/dependabot/bundler/file_updater/gemspec_updater.rb +0 -62
  19. data/lib/dependabot/bundler/file_updater/git_pin_replacer.rb +0 -78
  20. data/lib/dependabot/bundler/file_updater/git_source_remover.rb +0 -100
  21. data/lib/dependabot/bundler/file_updater/lockfile_updater.rb +0 -387
  22. data/lib/dependabot/bundler/file_updater/requirement_replacer.rb +0 -221
  23. data/lib/dependabot/bundler/metadata_finder.rb +0 -204
  24. data/lib/dependabot/bundler/requirement.rb +0 -29
  25. data/lib/dependabot/bundler/update_checker.rb +0 -334
  26. data/lib/dependabot/bundler/update_checker/file_preparer.rb +0 -279
  27. data/lib/dependabot/bundler/update_checker/force_updater.rb +0 -259
  28. data/lib/dependabot/bundler/update_checker/latest_version_finder.rb +0 -165
  29. data/lib/dependabot/bundler/update_checker/requirements_updater.rb +0 -281
  30. data/lib/dependabot/bundler/update_checker/ruby_requirement_setter.rb +0 -113
  31. data/lib/dependabot/bundler/update_checker/shared_bundler_helpers.rb +0 -244
  32. data/lib/dependabot/bundler/update_checker/version_resolver.rb +0 -272
  33. data/lib/dependabot/bundler/version.rb +0 -13
  34. data/lib/dependabot/monkey_patches/bundler/definition_bundler_version_patch.rb +0 -15
  35. data/lib/dependabot/monkey_patches/bundler/definition_ruby_version_patch.rb +0 -14
  36. data/lib/dependabot/monkey_patches/bundler/git_source_patch.rb +0 -27
@@ -1,112 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "pathname"
4
- require "parser/current"
5
- require "dependabot/bundler/file_fetcher"
6
- require "dependabot/errors"
7
-
8
- module Dependabot
9
- module Bundler
10
- class FileFetcher
11
- # Finds the paths of any gemspecs declared using `path: ` in the
12
- # passed Gemfile.
13
- class PathGemspecFinder
14
- def initialize(gemfile:)
15
- @gemfile = gemfile
16
- end
17
-
18
- def path_gemspec_paths
19
- ast = Parser::CurrentRuby.parse(gemfile.content)
20
- find_path_gemspec_paths(ast)
21
- rescue Parser::SyntaxError
22
- raise Dependabot::DependencyFileNotParseable, gemfile.path
23
- end
24
-
25
- private
26
-
27
- attr_reader :gemfile
28
-
29
- # rubocop:disable Security/Eval
30
- def find_path_gemspec_paths(node)
31
- return [] unless node.is_a?(Parser::AST::Node)
32
-
33
- if declares_path_dependency?(node)
34
- path_node = path_node_for_gem_declaration(node)
35
-
36
- begin
37
- # We use eval here, but we know what we're doing. The
38
- # FileFetchers helper method should only ever be run in an
39
- # isolated environment
40
- path = eval(path_node.loc.expression.source)
41
- rescue StandardError
42
- return []
43
- end
44
- return [clean_path(path)]
45
- end
46
-
47
- relevant_child_nodes(node).flat_map do |child_node|
48
- find_path_gemspec_paths(child_node)
49
- end
50
- end
51
- # rubocop:enable Security/Eval
52
-
53
- def current_dir
54
- @current_dir ||= gemfile.name.rpartition("/").first
55
- @current_dir = nil if @current_dir == ""
56
- @current_dir
57
- end
58
-
59
- def declares_path_dependency?(node)
60
- return false unless node.is_a?(Parser::AST::Node)
61
- return false unless node.children[1] == :gem
62
-
63
- !path_node_for_gem_declaration(node).nil?
64
- end
65
-
66
- def clean_path(path)
67
- if Pathname.new(path).absolute?
68
- base_path = Pathname.new(File.expand_path(Dir.pwd))
69
- path = Pathname.new(path).relative_path_from(base_path).to_s
70
- end
71
- path = File.join(current_dir, path) unless current_dir.nil?
72
- Pathname.new(path).cleanpath
73
- end
74
-
75
- # rubocop:disable Security/Eval
76
- def relevant_child_nodes(node)
77
- return [] unless node.is_a?(Parser::AST::Node)
78
- return node.children unless node.type == :if
79
-
80
- begin
81
- if eval(node.children.first.loc.expression.source)
82
- [node.children[1]]
83
- else
84
- [node.children[2]]
85
- end
86
- rescue StandardError
87
- return node.children
88
- end
89
- end
90
- # rubocop:enable Security/Eval
91
-
92
- def path_node_for_gem_declaration(node)
93
- return unless node.children.last.type == :hash
94
-
95
- kwargs_node = node.children.last
96
-
97
- path_hash_pair =
98
- kwargs_node.children.
99
- find { |hash_pair| key_from_hash_pair(hash_pair) == :path }
100
-
101
- return unless path_hash_pair
102
-
103
- path_hash_pair.children.last
104
- end
105
-
106
- def key_from_hash_pair(node)
107
- node.children.first.children.first.to_sym
108
- end
109
- end
110
- end
111
- end
112
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "pathname"
4
- require "parser/current"
5
- require "dependabot/bundler/file_fetcher"
6
- require "dependabot/errors"
7
-
8
- module Dependabot
9
- module Bundler
10
- class FileFetcher
11
- # Finds the paths of any files included using `require_relative` in the
12
- # passed file.
13
- class RequireRelativeFinder
14
- def initialize(file:)
15
- @file = file
16
- end
17
-
18
- def require_relative_paths
19
- ast = Parser::CurrentRuby.parse(file.content)
20
- find_require_relative_paths(ast)
21
- rescue Parser::SyntaxError
22
- raise Dependabot::DependencyFileNotParseable, file.path
23
- end
24
-
25
- private
26
-
27
- attr_reader :file
28
-
29
- # rubocop:disable Security/Eval
30
- def find_require_relative_paths(node)
31
- return [] unless node.is_a?(Parser::AST::Node)
32
-
33
- if declares_require_relative?(node)
34
- # We use eval here, but we know what we're doing. The FileFetchers
35
- # helper method should only ever be run in an isolated environment
36
- source = node.children[2].loc.expression.source
37
- begin
38
- path = eval(source)
39
- rescue StandardError
40
- return []
41
- end
42
-
43
- path = File.join(current_dir, path) unless current_dir.nil?
44
- return [Pathname.new(path + ".rb").cleanpath.to_path]
45
- end
46
-
47
- node.children.flat_map do |child_node|
48
- find_require_relative_paths(child_node)
49
- end
50
- end
51
- # rubocop:enable Security/Eval
52
-
53
- def current_dir
54
- @current_dir ||= file.name.split("/")[0..-2].last
55
- end
56
-
57
- def declares_require_relative?(node)
58
- return false unless node.is_a?(Parser::AST::Node)
59
-
60
- node.children[1] == :require_relative
61
- end
62
- end
63
- end
64
- end
65
- end
@@ -1,297 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/dependency"
4
- require "dependabot/file_parsers"
5
- require "dependabot/file_parsers/base"
6
- require "dependabot/bundler/file_updater/lockfile_updater"
7
- require "dependabot/bundler/version"
8
- require "dependabot/shared_helpers"
9
- require "dependabot/errors"
10
-
11
- module Dependabot
12
- module Bundler
13
- class FileParser < Dependabot::FileParsers::Base
14
- require "dependabot/file_parsers/base/dependency_set"
15
- require "dependabot/bundler/file_parser/file_preparer"
16
- require "dependabot/bundler/file_parser/gemfile_checker"
17
-
18
- def parse
19
- dependency_set = DependencySet.new
20
- dependency_set += gemfile_dependencies
21
- dependency_set += gemspec_dependencies
22
- dependency_set += lockfile_dependencies
23
- dependency_set.dependencies
24
- end
25
-
26
- private
27
-
28
- # Can't be a constant because some of these don't exist in bundler
29
- # 1.15, which Heroku uses, which causes an exception on boot.
30
- def sources
31
- [
32
- NilClass,
33
- ::Bundler::Source::Rubygems,
34
- ::Bundler::Source::Git,
35
- ::Bundler::Source::Path,
36
- ::Bundler::Source::Gemspec,
37
- ::Bundler::Source::Metadata
38
- ]
39
- end
40
-
41
- def gemfile_dependencies
42
- dependencies = DependencySet.new
43
-
44
- return dependencies unless gemfile
45
-
46
- [gemfile, *evaled_gemfiles].each do |file|
47
- parsed_gemfile.each do |dep|
48
- next unless dependency_in_gemfile?(gemfile: file, dependency: dep)
49
-
50
- dependencies <<
51
- Dependency.new(
52
- name: dep.name,
53
- version: dependency_version(dep.name)&.to_s,
54
- requirements: [{
55
- requirement: dep.requirement.to_s,
56
- groups: dep.groups,
57
- source: source_for(dep),
58
- file: file.name
59
- }],
60
- package_manager: "bundler"
61
- )
62
- end
63
- end
64
-
65
- dependencies
66
- end
67
-
68
- def gemspec_dependencies
69
- dependencies = DependencySet.new
70
-
71
- gemspecs.each do |gemspec|
72
- parsed_gemspec(gemspec).dependencies.each do |dependency|
73
- dependencies <<
74
- Dependency.new(
75
- name: dependency.name,
76
- version: dependency_version(dependency.name)&.to_s,
77
- requirements: [{
78
- requirement: dependency.requirement.to_s,
79
- groups: dependency.runtime? ? ["runtime"] : ["development"],
80
- source: nil,
81
- file: gemspec.name
82
- }],
83
- package_manager: "bundler"
84
- )
85
- end
86
- end
87
-
88
- dependencies
89
- end
90
-
91
- def lockfile_dependencies
92
- dependencies = DependencySet.new
93
-
94
- return dependencies unless lockfile
95
-
96
- # Create a DependencySet where each element has no requirement. Any
97
- # requirements will be added when combining the DependencySet with
98
- # other DependencySets.
99
- parsed_lockfile.specs.each do |dependency|
100
- next if dependency.source.is_a?(::Bundler::Source::Path)
101
-
102
- dependencies <<
103
- Dependency.new(
104
- name: dependency.name,
105
- version: dependency_version(dependency.name)&.to_s,
106
- requirements: [],
107
- package_manager: "bundler"
108
- )
109
- end
110
-
111
- dependencies
112
- end
113
-
114
- def parsed_gemfile
115
- base_directory = dependency_files.first.directory
116
- @parsed_gemfile ||=
117
- SharedHelpers.in_a_temporary_directory(base_directory) do
118
- write_temporary_dependency_files
119
-
120
- SharedHelpers.in_a_forked_process do
121
- ::Bundler.instance_variable_set(:@root, Pathname.new(Dir.pwd))
122
-
123
- ::Bundler::Definition.build(gemfile.name, nil, {}).
124
- dependencies.
125
- select(&:current_platform?).
126
- # We can't dump gemspec sources, and we wouldn't bump them
127
- # anyway, so we filter them out.
128
- reject { |dep| dep.source.is_a?(::Bundler::Source::Gemspec) }
129
- end
130
- end
131
- rescue SharedHelpers::ChildProcessFailed => error
132
- msg = error.error_class + " with message: " +
133
- error.error_message.force_encoding("UTF-8").encode
134
- raise Dependabot::DependencyFileNotEvaluatable, msg
135
- end
136
-
137
- def parsed_gemspec(file)
138
- @parsed_gemspecs ||= {}
139
- @parsed_gemspecs[file.name] ||=
140
- SharedHelpers.in_a_temporary_directory do
141
- [file, *imported_ruby_files].each do |f|
142
- path = f.name
143
- FileUtils.mkdir_p(Pathname.new(path).dirname)
144
- File.write(path, f.content)
145
- end
146
-
147
- SharedHelpers.in_a_forked_process do
148
- ::Bundler.instance_variable_set(:@root, Pathname.new(Dir.pwd))
149
- ::Bundler.load_gemspec_uncached(file.name)
150
- end
151
- end
152
- rescue SharedHelpers::ChildProcessFailed => error
153
- msg = error.error_class + " with message: " + error.error_message
154
- raise Dependabot::DependencyFileNotEvaluatable, msg
155
- end
156
-
157
- def prepared_dependency_files
158
- @prepared_dependency_files ||=
159
- FilePreparer.new(dependency_files: dependency_files).
160
- prepared_dependency_files
161
- end
162
-
163
- def write_temporary_dependency_files
164
- prepared_dependency_files.each do |file|
165
- path = file.name
166
- FileUtils.mkdir_p(Pathname.new(path).dirname)
167
- File.write(path, file.content)
168
- end
169
- end
170
-
171
- def check_required_files
172
- file_names = dependency_files.map(&:name)
173
-
174
- return if file_names.any? do |name|
175
- name.end_with?(".gemspec") && !name.include?("/")
176
- end
177
-
178
- return if gemfile
179
-
180
- raise "A gemspec or Gemfile must be provided!"
181
- end
182
-
183
- def source_for(dependency)
184
- source = dependency.source
185
- if lockfile && default_rubygems?(source)
186
- # If there's a lockfile and the Gemfile doesn't have anything
187
- # interesting to say about the source, check that.
188
- source = source_from_lockfile(dependency.name)
189
- end
190
- raise "Bad source: #{source}" unless sources.include?(source.class)
191
-
192
- return nil if default_rubygems?(source)
193
-
194
- details = { type: source.class.name.split("::").last.downcase }
195
- if source.is_a?(::Bundler::Source::Git)
196
- details.merge!(git_source_details(source))
197
- end
198
- if source.is_a?(::Bundler::Source::Rubygems)
199
- details[:url] = source.remotes.first.to_s
200
- end
201
- details
202
- end
203
-
204
- def git_source_details(source)
205
- {
206
- url: source.uri,
207
- branch: source.branch || "master",
208
- ref: source.ref
209
- }
210
- end
211
-
212
- def default_rubygems?(source)
213
- return true if source.nil?
214
- return false unless source.is_a?(::Bundler::Source::Rubygems)
215
-
216
- source.remotes.any? { |r| r.to_s.include?("rubygems.org") }
217
- end
218
-
219
- def dependency_version(dependency_name)
220
- return unless lockfile
221
-
222
- spec = parsed_lockfile.specs.find { |s| s.name == dependency_name }
223
-
224
- # Not all files in the Gemfile will appear in the Gemfile.lock. For
225
- # instance, if a gem specifies `platform: [:windows]`, and the
226
- # Gemfile.lock is generated on a Linux machine, the gem will be not
227
- # appear in the lockfile.
228
- return unless spec
229
-
230
- # If the source is Git we're better off knowing the SHA-1 than the
231
- # version.
232
- if spec.source.instance_of?(::Bundler::Source::Git)
233
- return spec.source.revision
234
- end
235
-
236
- spec.version
237
- end
238
-
239
- def source_from_lockfile(dependency_name)
240
- parsed_lockfile.specs.find { |s| s.name == dependency_name }&.source
241
- end
242
-
243
- def dependency_in_gemfile?(gemfile:, dependency:)
244
- GemfileChecker.new(
245
- dependency: dependency,
246
- gemfile: gemfile
247
- ).includes_dependency?
248
- end
249
-
250
- def gemfile
251
- @gemfile ||= get_original_file("Gemfile") ||
252
- get_original_file("gems.rb")
253
- end
254
-
255
- def evaled_gemfiles
256
- dependency_files.
257
- reject { |f| f.name.end_with?(".gemspec") }.
258
- reject { |f| f.name.end_with?(".lock") }.
259
- reject { |f| f.name.end_with?(".ruby-version") }.
260
- reject { |f| f.name == "Gemfile" }.
261
- reject { |f| f.name == "gems.rb" }.
262
- reject { |f| f.name == "gems.locked" }
263
- end
264
-
265
- def lockfile
266
- @lockfile ||= get_original_file("Gemfile.lock") ||
267
- get_original_file("gems.locked")
268
- end
269
-
270
- def parsed_lockfile
271
- @parsed_lockfile ||=
272
- ::Bundler::LockfileParser.new(sanitized_lockfile_content)
273
- end
274
-
275
- def sanitized_lockfile_content
276
- regex = FileUpdater::LockfileUpdater::LOCKFILE_ENDING
277
- lockfile.content.gsub(regex, "")
278
- end
279
-
280
- def gemspecs
281
- # Path gemspecs are excluded (they're supporting files)
282
- @gemspecs ||= prepared_dependency_files.
283
- select { |file| file.name.end_with?(".gemspec") }.
284
- reject(&:support_file?)
285
- end
286
-
287
- def imported_ruby_files
288
- dependency_files.
289
- select { |f| f.name.end_with?(".rb") }.
290
- reject { |f| f.name == "gems.rb" }
291
- end
292
- end
293
- end
294
- end
295
-
296
- Dependabot::FileParsers.
297
- register("bundler", Dependabot::Bundler::FileParser)