Class: LoadTracer

Inherits:
Object
  • Object
show all
Defined in:
lib/load_tracer.rb,
lib/load_tracer/version.rb

Defined Under Namespace

Classes: FileSpec

Constant Summary collapse

LOAD_METHODS =
%i(require require_relative load autoload)
VERSION =
'0.1.0'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeLoadTracer

Returns a new instance of LoadTracer.



53
54
55
56
# File 'lib/load_tracer.rb', line 53

def initialize
  @dependencies = Hash.new { |hash, key| hash[key] = [] }
  @reverse_dependencies = Hash.new { |hash, key| hash[key] = [] }
end

Class Method Details

.traceObject



47
48
49
50
51
# File 'lib/load_tracer.rb', line 47

def self.trace
  instance = new
  instance.tracer.enable { yield }
  instance.report
end

Instance Method Details

#reportObject



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
# File 'lib/load_tracer.rb', line 79

def report
  file_specs = @dependencies.map do |path, deps|
    FileSpec.new(
      name: File.basename(path),
      path: path,
      dependencies: deps,
    )
  end

  @reverse_dependencies.each do |path, rdeps|
    fs = file_specs.find { |fs| fs.path == path }

    if fs.nil?
      file_specs << FileSpec.new(
        name: File.basename(path),
        path: path,
        dependencies: [],
        reverse_dependencies: rdeps
      )
    else
      fs.reverse_dependencies = rdeps
    end
  end

  file_specs
end

#tracerObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/load_tracer.rb', line 58

def tracer
  TracePoint.new(:call) do |tp|
    next unless LOAD_METHODS.include?(tp.method_id)
    next if tp.defined_class != ::Kernel
    next if tp.path != __FILE__

    case tp.event
    when :call
      bl = caller_locations[1]

      feature = get_feature(tp)
      path = find_path(feature) || find_path(File.expand_path(feature, File.dirname(bl.path)))

      raise LoadError.new("cannot load such file -- #{feature}") if path.nil?

      @dependencies[bl.path] << path
      @reverse_dependencies[path] << bl.path
    end
  end
end