class Dependabot::Bundler::FileUpdater::GemspecSanitizer::Rewriter
Attributes
replacement_version[R]
Public Class Methods
new(replacement_version:)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 49 def initialize(replacement_version:) @replacement_version = replacement_version end
Public Instance Methods
on_send(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 53 def on_send(node) # Wrap any `require` or `require_relative` calls in a rescue # block, as we might not have the required files wrap_require(node) if requires_file?(node) # Remove any assignments to a VERSION constant (or similar), as # that constant probably comes from a required file replace_version_assignments(node) # Replace the `s.files= ...` assignment with a blank array, as # occasionally a File.open(..).readlines pattern is used replace_file_assignments(node) # Replace the `s.require_path= ...` assignment, as # occasionally a Dir['lib'] pattern is used replace_require_paths_assignments(node) # Replace any `File.read(...)` calls with a dummy string replace_file_reads(node) # Replace any `JSON.parse(...)` calls with a dummy hash replace_json_parses(node) # Remove the arguments from any `Find.find(...)` calls remove_find_dot_find_args(node) remove_unnecessary_assignments(node) end
Private Instance Methods
find_heredoc_end_range(node)
click to toggle source
Performs a depth-first search for the first heredoc in the given Parser::AST::Node.
Returns a Parser::Source::Range identifying the location of the end
of the heredoc, or nil if no heredoc was found.
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 258 def find_heredoc_end_range(node) return unless node.is_a?(Parser::AST::Node) node.children.each do |child| next unless child.is_a?(Parser::AST::Node) return child.location.heredoc_end if child.location.respond_to?(:heredoc_end) range = find_heredoc_end_range(child) return range if range end nil end
node_assigns_files_to_var?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 148 def node_assigns_files_to_var?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return false unless node.children.first&.type == :lvar return false unless node.children[1] == :files= node_dynamically_lists_files?(node.children[2]) end
node_assigns_require_paths?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 165 def node_assigns_require_paths?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return false unless node.children.first&.type == :lvar node.children[1] == :require_paths= end
node_assigns_to_version_constant?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 136 def node_assigns_to_version_constant?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return false unless node.children.first&.type == :lvar return true if node.children[1] == :version= return true if node_is_version_constant?(node.children.last) return true if node_calls_version_constant?(node.children.last) node_interpolates_version_constant?(node.children.last) end
node_calls_find_dot_find?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 225 def node_calls_find_dot_find?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return false unless node.children.first&.type == :const return false unless node.children.first.children.last == :Find node.children[1] == :find end
node_calls_version_constant?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 290 def node_calls_version_constant?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.type == :send node.children.any? { |n| node_is_version_constant?(n) } end
node_dynamically_lists_files?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 157 def node_dynamically_lists_files?(node) return false unless node.is_a?(Parser::AST::Node) return true if node.type == :send node.type == :block && node.children.first&.type == :send end
node_includes_heredoc?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 249 def node_includes_heredoc?(node) find_heredoc_end_range(node) end
node_interpolates_version_constant?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 297 def node_interpolates_version_constant?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.type == :dstr node.children. select { |n| n.type == :begin }. flat_map(&:children). any? { |n| node_is_version_constant?(n) } end
node_is_version_constant?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 283 def node_is_version_constant?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.type == :const node.children.last.to_s.match?(/version/i) end
node_parses_json?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 208 def node_parses_json?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return false unless node.children.first&.type == :const return false unless node.children.first.children.last == :JSON node.children[1] == :parse end
node_reads_a_file?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 182 def node_reads_a_file?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return false unless node.children.first&.type == :const return false unless node.children.first.children.last == :File node.children[1] == :read end
node_uses_readlines?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 191 def node_uses_readlines?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return false unless node.children.first&.type == :const return false unless node.children.first.children.last == :File node.children[1] == :readlines end
remove_find_args(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 343 def remove_find_args(node) last_arg = node.children.last range_to_remove = last_arg.loc.expression.join(node.children[2].loc.begin.begin) remove(range_to_remove) end
remove_find_dot_find_args(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 217 def remove_find_dot_find_args(node) return unless node.is_a?(Parser::AST::Node) return if node.children[1] == :version= return remove_find_args(node) if node_calls_find_dot_find?(node) node.children.each { |child| remove_find_dot_find_args(child) } end
remove_unnecessary_assignments(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 234 def remove_unnecessary_assignments(node) return unless node.is_a?(Parser::AST::Node) if unnecessary_assignment?(node) && node_includes_heredoc?(node) range_to_remove = node.loc.expression.join(find_heredoc_end_range(node)) return replace(range_to_remove, '"sanitized"') elsif unnecessary_assignment?(node) return replace(node.loc.expression, '"sanitized"') end node.children.each do |child| remove_unnecessary_assignments(child) end end
replace_constant(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 307 def replace_constant(node) case node.children.last&.type when :str, :int then nil # no-op when :float, :const, :send, :lvar, :if, :dstr replace( node.children.last.loc.expression, %("#{replacement_version}") ) else raise "Unexpected node type #{node.children.last&.type}" end end
replace_file_assignment(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 320 def replace_file_assignment(node) replace(node.children.last.loc.expression, "[]") end
replace_file_assignments(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 118 def replace_file_assignments(node) return unless node.is_a?(Parser::AST::Node) return replace_file_assignment(node) if node_assigns_files_to_var?(node) node.children.each { |child| replace_file_assignments(child) } end
replace_file_read(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 328 def replace_file_read(node) replace(node.loc.expression, %("#{replacement_version}")) end
replace_file_readlines(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 339 def replace_file_readlines(node) replace(node.loc.expression, %(["#{replacement_version}"])) end
replace_file_reads(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 173 def replace_file_reads(node) return unless node.is_a?(Parser::AST::Node) return if node.children[1] == :version= return replace_file_read(node) if node_reads_a_file?(node) return replace_file_readlines(node) if node_uses_readlines?(node) node.children.each { |child| replace_file_reads(child) } end
replace_json_parse(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 332 def replace_json_parse(node) replace( node.loc.expression, %({ "version" => "#{replacement_version}" }) ) end
replace_json_parses(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 200 def replace_json_parses(node) return unless node.is_a?(Parser::AST::Node) return if node.children[1] == :version= return replace_json_parse(node) if node_parses_json?(node) node.children.each { |child| replace_json_parses(child) } end
replace_require_paths_assignment(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 324 def replace_require_paths_assignment(node) replace(node.children.last.loc.expression, "['lib']") end
replace_require_paths_assignments(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 126 def replace_require_paths_assignments(node) return unless node.is_a?(Parser::AST::Node) return replace_require_paths_assignment(node) if node_assigns_require_paths?(node) node.children.each do |child| replace_require_paths_assignments(child) end end
replace_version_assignments(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 100 def replace_version_assignments(node) return unless node.is_a?(Parser::AST::Node) return replace_constant(node) if node_assigns_to_version_constant?(node) node.children.each { |child| replace_version_assignments(child) } end
replace_version_constant_references(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 108 def replace_version_constant_references(node) return unless node.is_a?(Parser::AST::Node) return replace(node.loc.expression, %("#{replacement_version}")) if node_is_version_constant?(node) node.children.each do |child| replace_version_constant_references(child) end end
requires_file?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 86 def requires_file?(node) %i(require require_relative).include?(node.children[1]) end
unnecessary_assignment?(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 273 def unnecessary_assignment?(node) return false unless node.is_a?(Parser::AST::Node) return false unless node.children.first.is_a?(Parser::AST::Node) return true if node.children.first.type == :lvar && UNNECESSARY_ASSIGNMENTS.include?(node.children[1]) node.children[1] == :[]= && node.children.first.children.last end
wrap_require(node)
click to toggle source
# File lib/dependabot/bundler/file_updater/gemspec_sanitizer.rb, line 90 def wrap_require(node) replace( node.loc.expression, "begin\n"\ "#{node.loc.expression.source_line}\n"\ "rescue LoadError\n"\ "end" ) end