File: deprecation.rb

package info (click to toggle)
ruby-sprockets 3.7.0-1%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 544 kB
  • sloc: ruby: 4,163; makefile: 2
file content (90 lines) | stat: -rw-r--r-- 2,521 bytes parent folder | download | duplicates (3)
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
module Sprockets
  class Deprecation
    THREAD_LOCAL__SILENCE_KEY = "_sprockets_deprecation_silence".freeze
    DEFAULT_BEHAVIORS = {
      raise: ->(message, callstack) {
        e = DeprecationException.new(message)
        e.set_backtrace(callstack.map(&:to_s))
        raise e
      },

      stderr: ->(message, callstack) {
        $stderr.puts(message)
      },
    }

    attr_reader :callstack

    def self.silence(&block)
      Thread.current[THREAD_LOCAL__SILENCE_KEY] = true
      block.call
    ensure
      Thread.current[THREAD_LOCAL__SILENCE_KEY] = false
    end

    def initialize(callstack = nil)
      @callstack = callstack || caller(2)
    end

    def warn(message)
      return if Thread.current[THREAD_LOCAL__SILENCE_KEY]
      deprecation_message(message).tap do |m|
        behavior.each { |b| b.call(m, callstack) }
      end
    end

    private
      def behavior
        @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
      end

      def behavior=(behavior)
        @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
      end

      def deprecation_message(message = nil)
        message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
        "DEPRECATION WARNING: #{message} #{ deprecation_caller_message }"
      end

      def deprecation_caller_message
        file, line, method = extract_callstack
        if file
          if line && method
            "(called from #{method} at #{file}:#{line})"
          else
            "(called from #{file}:#{line})"
          end
        end
      end

      SPROCKETS_GEM_ROOT = File.expand_path("../../../../..", __FILE__) + "/"

      def ignored_callstack(path)
        path.start_with?(SPROCKETS_GEM_ROOT) || path.start_with?(RbConfig::CONFIG['rubylibdir'])
      end

      def extract_callstack
        return _extract_callstack if callstack.first.is_a? String

        offending_line = callstack.find { |frame|
          frame.absolute_path && !ignored_callstack(frame.absolute_path)
        } || callstack.first

        [offending_line.path, offending_line.lineno, offending_line.label]
      end

      def _extract_callstack
        offending_line = callstack.find { |line| !ignored_callstack(line) } || callstack.first

        if offending_line
          if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
            md.captures
          else
            offending_line
          end
        end
      end
  end
  private_constant :Deprecation
end