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,221 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "parser/current"
4
- require "dependabot/bundler/file_updater"
5
-
6
- module Dependabot
7
- module Bundler
8
- class FileUpdater
9
- class RequirementReplacer
10
- attr_reader :dependency, :file_type, :updated_requirement,
11
- :previous_requirement
12
-
13
- def initialize(dependency:, file_type:, updated_requirement:,
14
- previous_requirement: nil, insert_if_bare: false)
15
- @dependency = dependency
16
- @file_type = file_type
17
- @updated_requirement = updated_requirement
18
- @previous_requirement = previous_requirement
19
- @insert_if_bare = insert_if_bare
20
- end
21
-
22
- def rewrite(content)
23
- buffer = Parser::Source::Buffer.new("(gemfile_content)")
24
- buffer.source = content
25
- ast = Parser::CurrentRuby.new.parse(buffer)
26
-
27
- updated_content = Rewriter.new(
28
- dependency: dependency,
29
- file_type: file_type,
30
- updated_requirement: updated_requirement,
31
- insert_if_bare: insert_if_bare?
32
- ).rewrite(buffer, ast)
33
-
34
- update_comment_spacing_if_required(content, updated_content)
35
- end
36
-
37
- private
38
-
39
- def insert_if_bare?
40
- @insert_if_bare
41
- end
42
-
43
- def update_comment_spacing_if_required(content, updated_content)
44
- return updated_content unless previous_requirement
45
-
46
- return updated_content if updated_content == content
47
- return updated_content if length_change.zero?
48
-
49
- updated_lines = updated_content.lines
50
- updated_line_index =
51
- updated_lines.length.
52
- times.find { |i| content.lines[i] != updated_content.lines[i] }
53
- updated_line = updated_lines[updated_line_index]
54
-
55
- updated_line =
56
- if length_change.positive?
57
- updated_line.sub(/(?<=\s)\s{#{length_change}}#/, "#")
58
- elsif length_change.negative?
59
- updated_line.sub(/(?<=\s{2})#/, " " * length_change.abs + "#")
60
- end
61
-
62
- updated_lines[updated_line_index] = updated_line
63
- updated_lines.join
64
- end
65
-
66
- def length_change
67
- unless previous_requirement.start_with?("=")
68
- return updated_requirement.length - previous_requirement.length
69
- end
70
-
71
- updated_requirement.length -
72
- previous_requirement.gsub(/^=/, "").strip.length
73
- end
74
-
75
- class Rewriter < Parser::TreeRewriter
76
- # TODO: Ideally we wouldn't have to ignore all of these, but
77
- # implementing each one will be tricky.
78
- SKIPPED_TYPES = %i(send lvar dstr begin if splat const).freeze
79
-
80
- def initialize(dependency:, file_type:, updated_requirement:,
81
- insert_if_bare:)
82
- @dependency = dependency
83
- @file_type = file_type
84
- @updated_requirement = updated_requirement
85
- @insert_if_bare = insert_if_bare
86
-
87
- return if %i(gemfile gemspec).include?(file_type)
88
-
89
- raise "File type must be :gemfile or :gemspec. Got #{file_type}."
90
- end
91
-
92
- def on_send(node)
93
- return unless declares_targeted_gem?(node)
94
-
95
- req_nodes = node.children[3..-1]
96
- req_nodes = req_nodes.reject { |child| child.type == :hash }
97
-
98
- return if req_nodes.none? && !insert_if_bare?
99
- return if req_nodes.any? { |n| SKIPPED_TYPES.include?(n.type) }
100
-
101
- quote_characters = extract_quote_characters_from(req_nodes)
102
- space_after_specifier = space_after_specifier?(req_nodes)
103
- use_equality_operator = use_equality_operator?(req_nodes)
104
-
105
- new_req = new_requirement_string(
106
- quote_characters: quote_characters,
107
- space_after_specifier: space_after_specifier,
108
- use_equality_operator: use_equality_operator
109
- )
110
- if req_nodes.any?
111
- replace(range_for(req_nodes), new_req)
112
- else
113
- insert_after(range_for(node.children[2..2]), ", #{new_req}")
114
- end
115
- end
116
-
117
- private
118
-
119
- attr_reader :dependency, :file_type, :updated_requirement
120
-
121
- def insert_if_bare?
122
- @insert_if_bare
123
- end
124
-
125
- def declaration_methods
126
- return %i(gem) if file_type == :gemfile
127
-
128
- %i(add_dependency add_runtime_dependency
129
- add_development_dependency)
130
- end
131
-
132
- def declares_targeted_gem?(node)
133
- return false unless declaration_methods.include?(node.children[1])
134
-
135
- node.children[2].children.first == dependency.name
136
- end
137
-
138
- def extract_quote_characters_from(requirement_nodes)
139
- return ['"', '"'] if requirement_nodes.none?
140
-
141
- case requirement_nodes.first.type
142
- when :str, :dstr
143
- [
144
- requirement_nodes.first.loc.begin.source,
145
- requirement_nodes.first.loc.end.source
146
- ]
147
- else
148
- [
149
- requirement_nodes.first.children.first.loc.begin.source,
150
- requirement_nodes.first.children.first.loc.end.source
151
- ]
152
- end
153
- end
154
-
155
- def space_after_specifier?(requirement_nodes)
156
- return true if requirement_nodes.none?
157
-
158
- req_string =
159
- case requirement_nodes.first.type
160
- when :str, :dstr
161
- requirement_nodes.first.loc.expression.source
162
- else
163
- requirement_nodes.first.children.first.loc.expression.source
164
- end
165
-
166
- ops = Gem::Requirement::OPS.keys
167
- return true if ops.none? { |op| req_string.include?(op) }
168
-
169
- req_string.include?(" ")
170
- end
171
-
172
- def use_equality_operator?(requirement_nodes)
173
- return true if requirement_nodes.none?
174
-
175
- req_string =
176
- case requirement_nodes.first.type
177
- when :str, :dstr
178
- requirement_nodes.first.loc.expression.source
179
- else
180
- requirement_nodes.first.children.first.loc.expression.source
181
- end
182
-
183
- req_string.match?(/(?<![<>])=/)
184
- end
185
-
186
- def new_requirement_string(quote_characters:,
187
- space_after_specifier:,
188
- use_equality_operator:)
189
- open_quote, close_quote = quote_characters
190
- new_requirement_string =
191
- updated_requirement.split(",").
192
- map do |r|
193
- req_string = serialized_req(r, use_equality_operator)
194
- %(#{open_quote}#{req_string}#{close_quote})
195
- end.join(", ")
196
-
197
- new_requirement_string.delete!(" ") unless space_after_specifier
198
- new_requirement_string
199
- end
200
-
201
- def serialized_req(req, use_equality_operator)
202
- tmp_req = req
203
-
204
- # Gem::Requirement serializes exact matches as a string starting
205
- # with `=`. We may need to remove that equality operator if it
206
- # wasn't used originally.
207
- unless use_equality_operator
208
- tmp_req = tmp_req.gsub(/(?<![<>])=/, "")
209
- end
210
-
211
- tmp_req.strip
212
- end
213
-
214
- def range_for(nodes)
215
- nodes.first.loc.begin.begin.join(nodes.last.loc.expression)
216
- end
217
- end
218
- end
219
- end
220
- end
221
- end
@@ -1,204 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "excon"
4
- require "dependabot/metadata_finders"
5
- require "dependabot/metadata_finders/base"
6
-
7
- module Dependabot
8
- module Bundler
9
- class MetadataFinder < Dependabot::MetadataFinders::Base
10
- SOURCE_KEYS = %w(
11
- source_code_uri
12
- homepage_uri
13
- wiki_uri
14
- bug_tracker_uri
15
- documentation_uri
16
- changelog_uri
17
- mailing_list_uri
18
- download_uri
19
- ).freeze
20
-
21
- def homepage_url
22
- return super unless %w(default rubygems).include?(new_source_type)
23
- return super unless rubygems_api_response["homepage_uri"]
24
-
25
- rubygems_api_response["homepage_uri"]
26
- end
27
-
28
- private
29
-
30
- def look_up_source
31
- case new_source_type
32
- when "git" then find_source_from_git_url
33
- when "default", "rubygems" then find_source_from_rubygems
34
- else raise "Unexpected source type: #{new_source_type}"
35
- end
36
- end
37
-
38
- def new_source_type
39
- sources =
40
- dependency.requirements.map { |r| r.fetch(:source) }.uniq.compact
41
-
42
- return "default" if sources.empty?
43
- raise "Multiple sources! #{sources.join(', ')}" if sources.count > 1
44
-
45
- sources.first[:type] || sources.first.fetch("type")
46
- end
47
-
48
- def find_source_from_rubygems
49
- api_source = find_source_from_rubygems_api_response
50
- return api_source if api_source || new_source_type == "default"
51
-
52
- find_source_from_gemspec_download
53
- end
54
-
55
- def find_source_from_rubygems_api_response
56
- source_url = rubygems_api_response.
57
- values_at(*SOURCE_KEYS).
58
- compact.
59
- find { |url| Source.from_url(url) }
60
-
61
- Source.from_url(source_url)
62
- end
63
-
64
- def find_source_from_git_url
65
- info = dependency.requirements.map { |r| r[:source] }.compact.first
66
-
67
- url = info[:url] || info.fetch("url")
68
- Source.from_url(url)
69
- end
70
-
71
- def find_source_from_gemspec_download
72
- github_urls = []
73
- return unless rubygems_marshalled_gemspec_response
74
-
75
- rubygems_marshalled_gemspec_response.scan(Source::SOURCE_REGEX) do
76
- github_urls << Regexp.last_match.to_s
77
- end
78
-
79
- source_url = github_urls.find do |url|
80
- repo = Source.from_url(url).repo
81
- repo.downcase.end_with?(dependency.name)
82
- end
83
- return unless source_url
84
-
85
- Source.from_url(source_url)
86
- end
87
-
88
- # Note: This response MUST NOT be unmarshalled
89
- # (as calling Marshal.load is unsafe)
90
- def rubygems_marshalled_gemspec_response
91
- if defined?(@rubygems_marshalled_gemspec_response)
92
- return @rubygems_marshalled_gemspec_response
93
- end
94
-
95
- gemspec_uri =
96
- "#{registry_url}quick/Marshal.4.8/"\
97
- "#{dependency.name}-#{dependency.version}.gemspec.rz"
98
-
99
- response =
100
- Excon.get(
101
- gemspec_uri,
102
- headers: registry_auth_headers,
103
- idempotent: true,
104
- **SharedHelpers.excon_defaults
105
- )
106
-
107
- if response.status >= 400
108
- return @rubygems_marshalled_gemspec_response = nil
109
- end
110
-
111
- @rubygems_marshalled_gemspec_response =
112
- Zlib::Inflate.inflate(response.body)
113
- rescue Zlib::DataError
114
- @rubygems_marshalled_gemspec_response = nil
115
- end
116
-
117
- def rubygems_api_response
118
- return @rubygems_api_response if defined?(@rubygems_api_response)
119
-
120
- response =
121
- Excon.get(
122
- "#{registry_url}api/v1/gems/#{dependency.name}.json",
123
- headers: registry_auth_headers,
124
- idempotent: true,
125
- **SharedHelpers.excon_defaults
126
- )
127
- return @rubygems_api_response = {} if response.status >= 400
128
-
129
- response_body = response.body
130
- response_body = augment_private_response_if_appropriate(response_body)
131
-
132
- @rubygems_api_response = JSON.parse(response_body)
133
- append_slash_to_source_code_uri(@rubygems_api_response)
134
- rescue JSON::ParserError, Excon::Error::Timeout
135
- @rubygems_api_response = {}
136
- end
137
-
138
- def append_slash_to_source_code_uri(listing)
139
- # We have to do this so that `Source.from_url(...)` doesn't prune the
140
- # last line off of the directory.
141
- return listing unless listing&.fetch("source_code_uri", nil)
142
- return listing if listing.fetch("source_code_uri").end_with?("/")
143
-
144
- listing["source_code_uri"] = listing["source_code_uri"] + "/"
145
- listing
146
- end
147
-
148
- def augment_private_response_if_appropriate(response_body)
149
- return response_body if new_source_type == "default"
150
-
151
- parsed_body = JSON.parse(response_body)
152
- return response_body if (SOURCE_KEYS - parsed_body.keys).none?
153
-
154
- digest = parsed_body.values_at("version", "authors", "info").hash
155
-
156
- source_url = parsed_body.
157
- values_at(*SOURCE_KEYS).
158
- compact.
159
- find { |url| Source.from_url(url) }
160
- return response_body if source_url
161
-
162
- rubygems_response =
163
- Excon.get(
164
- "https://rubygems.org/api/v1/gems/#{dependency.name}.json",
165
- idempotent: true,
166
- **SharedHelpers.excon_defaults
167
- )
168
- parsed_rubygems_body = JSON.parse(rubygems_response.body)
169
- rubygems_digest =
170
- parsed_rubygems_body.values_at("version", "authors", "info").hash
171
-
172
- digest == rubygems_digest ? rubygems_response.body : response_body
173
- rescue JSON::ParserError, Excon::Error::Socket, Excon::Error::Timeout
174
- response_body
175
- end
176
-
177
- def registry_url
178
- return "https://rubygems.org/" if new_source_type == "default"
179
-
180
- info = dependency.requirements.map { |r| r[:source] }.compact.first
181
- info[:url] || info.fetch("url")
182
- end
183
-
184
- def registry_auth_headers
185
- return {} unless new_source_type == "rubygems"
186
-
187
- token =
188
- credentials.
189
- select { |cred| cred["type"] == "rubygems_server" }.
190
- find { |cred| registry_url.include?(cred["host"]) }&.
191
- fetch("token")
192
-
193
- return {} unless token
194
-
195
- token += ":" unless token.include?(":")
196
- encoded_token = Base64.encode64(token).delete("\n")
197
- { "Authorization" => "Basic #{encoded_token}" }
198
- end
199
- end
200
- end
201
- end
202
-
203
- Dependabot::MetadataFinders.
204
- register("bundler", Dependabot::Bundler::MetadataFinder)
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dependabot/utils"
4
-
5
- module Dependabot
6
- module Bundler
7
- class Requirement < Gem::Requirement
8
- # For consistency with other langauges, we define a requirements array.
9
- # Ruby doesn't have an `OR` separator for requirements, so it always
10
- # contains a single element.
11
- def self.requirements_array(requirement_string)
12
- [new(requirement_string)]
13
- end
14
-
15
- # Patches Gem::Requirement to make it accept requirement strings like
16
- # "~> 4.2.5, >= 4.2.5.1" without first needing to split them.
17
- def initialize(*requirements)
18
- requirements = requirements.flatten.flat_map do |req_string|
19
- req_string.split(",")
20
- end
21
-
22
- super(requirements)
23
- end
24
- end
25
- end
26
- end
27
-
28
- Dependabot::Utils.
29
- register_requirement_class("bundler", Dependabot::Bundler::Requirement)