Skip to content

Instantly share code, notes, and snippets.

@icorson3
Last active February 12, 2020 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save icorson3/4c6205808ba4ffc7c795af7c3cfe4a62 to your computer and use it in GitHub Desktop.
Save icorson3/4c6205808ba4ffc7c795af7c3cfe4a62 to your computer and use it in GitHub Desktop.
# requires pry, parser, and ast gems
#
# Running:
#
#  # running on an individual file (or pass multiple file names in)
#  ruby-rewrite --load 'insert_ruby_params_keyword.rb' -m spec/controllers/api/songs_controller.rb
#
#  # running on all the file individually. note: if a pry gets triggered you'll see it, but it won't give you
#. # control of the terminal, you'll need to use the previous command on the filed that fails.
#  find spec/controllers -name "*_spec.rb" | xargs ruby-rewrite --load 'insert_ruby_params_keyword.rb' -m

require 'pry'

class InsertRubyParamsKeyword < ::Parser::TreeRewriter
  # Method calls are tagged as :send
  # We're only interested in method calls so hook into on_send.
  def on_send(node)
    method = node.children[1]

    # we only care about method calls that are the HTTP methods
    if [:get, :put, :post, :delete, :patch, :head].include?(method)
      #binding.pry if node.location.line == 78 || node.location.line == 79
      if node.children[0] != nil
        #no op
      elsif node.children.count >= 3 && node.children[3].respond_to?(:to_sexp_array) && node.children[3].to_sexp_array.first == :send
        original_call = node.children[3].location.expression.source
        replace(node.children[3].location.expression, "params: #{original_call}")
      else
        hash_node = node.children.find { |child_node| child_node.is_a?(Parser::AST::Node) && child_node.type == :hash }

        if hash_node
          multiline = hash_node.children.first.loc.line != hash_node.children.last.loc.line
          if multiline
            leading_spaces = hash_node.location.expression.source.scan(/^\s+/).first
            source = hash_node.location.expression.source.gsub(/^/m, "  ")
            replace(hash_node.location.expression, "params: {\n#{leading_spaces}#{source}\n#{leading_spaces}}")
          else
            insert_before(hash_node.location.expression, "params: { ")
            insert_after(hash_node.location.expression, " }")
          end
        end
      end
      # find the first parameter that is a hash. Based on the method signature of get/post/put/delete
      # we know this is the params hash.

    end
    super
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment