This file is indexed.

/usr/lib/ruby/vendor_ruby/rspec/core/formatters/deprecation_formatter.rb is in ruby-rspec-core 3.5.0c3e0m0s0-1.

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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
RSpec::Support.require_rspec_core "formatters/helpers"

module RSpec
  module Core
    module Formatters
      # @private
      class DeprecationFormatter
        Formatters.register self, :deprecation, :deprecation_summary

        attr_reader :count, :deprecation_stream, :summary_stream

        def initialize(deprecation_stream, summary_stream)
          @deprecation_stream = deprecation_stream
          @summary_stream = summary_stream
          @seen_deprecations = Set.new
          @count = 0
        end
        alias :output :deprecation_stream

        def printer
          @printer ||= case deprecation_stream
                       when File
                         ImmediatePrinter.new(FileStream.new(deprecation_stream),
                                              summary_stream, self)
                       when RaiseErrorStream
                         ImmediatePrinter.new(deprecation_stream, summary_stream, self)
                       else
                         DelayedPrinter.new(deprecation_stream, summary_stream, self)
                       end
        end

        def deprecation(notification)
          return if @seen_deprecations.include? notification

          @count += 1
          printer.print_deprecation_message notification
          @seen_deprecations << notification
        end

        def deprecation_summary(_notification)
          printer.deprecation_summary
        end

        def deprecation_message_for(data)
          if data.message
            SpecifiedDeprecationMessage.new(data)
          else
            GeneratedDeprecationMessage.new(data)
          end
        end

        RAISE_ERROR_CONFIG_NOTICE = <<-EOS.gsub(/^\s+\|/, '')
          |
          |If you need more of the backtrace for any of these deprecations to
          |identify where to make the necessary changes, you can configure
          |`config.raise_errors_for_deprecations!`, and it will turn the
          |deprecation warnings into errors, giving you the full backtrace.
        EOS

        DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set " \
          "`config.deprecation_stream` to a file for full output."

        SpecifiedDeprecationMessage = Struct.new(:type) do
          def initialize(data)
            @message = data.message
            super deprecation_type_for(data)
          end

          def to_s
            output_formatted @message
          end

          def too_many_warnings_message
            msg = "Too many similar deprecation messages reported, disregarding further reports. "
            msg << DEPRECATION_STREAM_NOTICE
            msg
          end

          private

          def output_formatted(str)
            return str unless str.lines.count > 1
            separator = "#{'-' * 80}"
            "#{separator}\n#{str.chomp}\n#{separator}"
          end

          def deprecation_type_for(data)
            data.message.gsub(/(\w+\/)+\w+\.rb:\d+/, '')
          end
        end

        GeneratedDeprecationMessage = Struct.new(:type) do
          def initialize(data)
            @data = data
            super data.deprecated
          end

          def to_s
            msg =  "#{@data.deprecated} is deprecated."
            msg << " Use #{@data.replacement} instead." if @data.replacement
            msg << " Called from #{@data.call_site}." if @data.call_site
            msg
          end

          def too_many_warnings_message
            msg = "Too many uses of deprecated '#{type}'. "
            msg << DEPRECATION_STREAM_NOTICE
            msg
          end
        end

        # @private
        class ImmediatePrinter
          attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter

          def initialize(deprecation_stream, summary_stream, deprecation_formatter)
            @deprecation_stream = deprecation_stream

            @summary_stream = summary_stream
            @deprecation_formatter = deprecation_formatter
          end

          def print_deprecation_message(data)
            deprecation_message = deprecation_formatter.deprecation_message_for(data)
            deprecation_stream.puts deprecation_message.to_s
          end

          def deprecation_summary
            return if deprecation_formatter.count.zero?
            deprecation_stream.summarize(summary_stream, deprecation_formatter.count)
          end
        end

        # @private
        class DelayedPrinter
          TOO_MANY_USES_LIMIT = 4

          attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter

          def initialize(deprecation_stream, summary_stream, deprecation_formatter)
            @deprecation_stream = deprecation_stream
            @summary_stream = summary_stream
            @deprecation_formatter = deprecation_formatter
            @seen_deprecations = Hash.new { 0 }
            @deprecation_messages = Hash.new { |h, k| h[k] = [] }
          end

          def print_deprecation_message(data)
            deprecation_message = deprecation_formatter.deprecation_message_for(data)
            @seen_deprecations[deprecation_message] += 1

            stash_deprecation_message(deprecation_message)
          end

          def stash_deprecation_message(deprecation_message)
            if @seen_deprecations[deprecation_message] < TOO_MANY_USES_LIMIT
              @deprecation_messages[deprecation_message] << deprecation_message.to_s
            elsif @seen_deprecations[deprecation_message] == TOO_MANY_USES_LIMIT
              @deprecation_messages[deprecation_message] << deprecation_message.too_many_warnings_message
            end
          end

          def deprecation_summary
            return unless @deprecation_messages.any?

            print_deferred_deprecation_warnings
            deprecation_stream.puts RAISE_ERROR_CONFIG_NOTICE

            summary_stream.puts "\n#{Helpers.pluralize(deprecation_formatter.count, 'deprecation warning')} total"
          end

          def print_deferred_deprecation_warnings
            deprecation_stream.puts "\nDeprecation Warnings:\n\n"
            @deprecation_messages.keys.sort_by(&:type).each do |deprecation|
              messages = @deprecation_messages[deprecation]
              messages.each { |msg| deprecation_stream.puts msg }
              deprecation_stream.puts
            end
          end
        end

        # @private
        # Not really a stream, but is usable in place of one.
        class RaiseErrorStream
          def puts(message)
            raise DeprecationError, message
          end

          def summarize(summary_stream, deprecation_count)
            summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} found."
          end
        end

        # @private
        # Wraps a File object and provides file-specific operations.
        class FileStream
          def initialize(file)
            @file = file

            # In one of my test suites, I got lots of duplicate output in the
            # deprecation file (e.g. 200 of the same deprecation, even though
            # the `puts` below was only called 6 times). Setting `sync = true`
            # fixes this (but we really have no idea why!).
            @file.sync = true
          end

          def puts(*args)
            @file.puts(*args)
          end

          def summarize(summary_stream, deprecation_count)
            path = @file.respond_to?(:path) ? @file.path : @file.inspect
            summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} logged to #{path}"
            puts RAISE_ERROR_CONFIG_NOTICE
          end
        end
      end
    end

    # Deprecation Error.
    DeprecationError = Class.new(StandardError)
  end
end