This file is indexed.

/usr/lib/ruby/vendor_ruby/pry/commands/find_method.rb is in pry 0.10.3-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
class Pry
  class Command::FindMethod < Pry::ClassCommand
    extend Pry::Helpers::BaseHelpers

    match 'find-method'
    group 'Context'
    description 'Recursively search for a method within a Class/Module or the current namespace.'
    command_options :shellwords => false

    banner <<-'BANNER'
      Usage: find-method  [-n|-c] METHOD [NAMESPACE]

      Recursively search for a method within a Class/Module or the current namespace.
      Use the `-n` switch (the default) to search for methods whose name matches the
      given regex. Use the `-c` switch to search for methods that contain the given
      code.

      # Find all methods whose name match /re/ inside
      # the Pry namespace. Matches Pry#repl, etc.
      find-method re Pry

      # Find all methods that contain the code:
      # output.puts inside the Pry namepsace.
      find-method -c 'output.puts' Pry
    BANNER

    def options(opt)
      opt.on :n, :name,    "Search for a method by name"
      opt.on :c, :content, "Search for a method based on content in Regex form"
    end

    def process
      return if args.size < 1
      klass = search_class

      matches = if opts.content?
        content_search(klass)
      else
        name_search(klass)
      end

      show_search_results(matches)
    end

    private

    # @return [Regexp] The pattern to search for.
    def pattern
      @pattern ||= ::Regexp.new args[0]
    end

    # Output the result of the search.
    #
    # @param [Array] matches
    def show_search_results(matches)
      if matches.empty?
        output.puts text.bold("No Methods Matched")
      else
        print_matches(matches)
      end
    end

    # The class to search for methods.
    # We only search classes, so if the search object is an
    # instance, return its class. If no search object is given
    # search `target_self`.
    def search_class
      klass = if args[1]
                target.eval(args[1])
              else
                target_self
              end

      klass.is_a?(Module) ? klass : klass.class
    end

    # pretty-print a list of matching methods.
    #
    # @param [Array<Method>] matches
    def print_matches(matches)
      grouped = matches.group_by(&:owner)
      order = grouped.keys.sort_by{ |x| x.name || x.to_s }

      order.each do |klass|
        print_matches_for_class(klass, grouped)
      end
    end

    # Print matched methods for a class
    def print_matches_for_class(klass, grouped)
      output.puts text.bold(klass.name)
      grouped[klass].each do |method|
        header = method.name_with_owner
        output.puts header + additional_info(header, method)
      end
    end

    # Return the matched lines of method source if `-c` is given or ""
    # if `-c` was not given
    def additional_info(header, method)
      if opts.content?
        ": " << colorize_code(matched_method_lines(header, method))
      else
        ""
      end
    end

    def matched_method_lines(header, method)
      method.source.split(/\n/).select {|x| x =~ pattern }.join("\n#{' ' * header.length}")
    end

    # Run the given block against every constant in the provided namespace.
    #
    # @param [Module] klass The namespace in which to start the search.
    # @param [Hash<Module,Boolean>] done The namespaces we've already visited (private)
    # @yieldparam klass Each class/module in the namespace.
    #
    def recurse_namespace(klass, done={}, &block)
      return if !(Module === klass) || done[klass]

      done[klass] = true

      yield klass

      klass.constants.each do |name|
        next if klass.autoload?(name)
        begin
          const = klass.const_get(name)
        rescue RescuableException
          # constant loading is an inexact science at the best of times,
          # this often happens when a constant was .autoload? but someone
          # tried to load it. It's now not .autoload? but will still raise
          # a NameError when you access it.
        else
          recurse_namespace(const, done, &block)
        end
      end
    end

    # Gather all the methods in a namespace that pass the given block.
    #
    # @param [Module] namespace The namespace in which to search.
    # @yieldparam [Method] method The method to test
    # @yieldreturn [Boolean]
    # @return [Array<Method>]
    #
    def search_all_methods(namespace)
      done = Hash.new{ |h,k| h[k] = {} }
      matches = []

      recurse_namespace(namespace) do |klass|
        (Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).each do |method|
          next if done[method.owner][method.name]
          done[method.owner][method.name] = true

          matches << method if yield method
        end
      end

      matches
    end

    # Search for all methods with a name that matches the given regex
    # within a namespace.
    #
    # @param [Module] namespace The namespace to search
    # @return [Array<Method>]
    #
    def name_search(namespace)
      search_all_methods(namespace) do |meth|
        meth.name =~ pattern
      end
    end

    # Search for all methods who's implementation matches the given regex
    # within a namespace.
    #
    # @param [Module] namespace The namespace to search
    # @return [Array<Method>]
    #
    def content_search(namespace)
      search_all_methods(namespace) do |meth|
        begin
          meth.source =~ pattern
        rescue RescuableException
          false
        end
      end
    end
  end

  Pry::Commands.add_command(Pry::Command::FindMethod)
end