load_tracer 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/load_tracer.rb +31 -13
- data/lib/load_tracer/static_checker.rb +80 -0
- data/lib/load_tracer/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8506eef88908cad86610b5a6d6741ff697acc77172067fb41e162939eb6df5b7
|
4
|
+
data.tar.gz: 03dc7508cecc0b9fa08c1fbf3f4157b88196eb704fbb0664b14ae8e480b384ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 125417a2ee92c559509bcc15e7e0a3229fd1e5b99f96835d3e9aa6b9d32ebcf926825abe1b6316dafca424f1adf6af62e0992366f80b5b96c59b7f0e7ab592e0
|
7
|
+
data.tar.gz: a6c8d3b5900e8f990ed07e63a38c3f4bcfa0dc879bf169854b2a9f4914c66723264829d92c62a1325d90eee59290d4824a25e46872f0bef4959b634c10bf7784
|
data/Gemfile.lock
CHANGED
data/lib/load_tracer.rb
CHANGED
@@ -2,6 +2,7 @@ require 'binding_of_caller'
|
|
2
2
|
require 'load_tracer/formatter/default'
|
3
3
|
require 'load_tracer/formatter/dot'
|
4
4
|
require 'load_tracer/formatter/json'
|
5
|
+
require 'load_tracer/static_checker'
|
5
6
|
require 'load_tracer/version'
|
6
7
|
|
7
8
|
module Kernel
|
@@ -43,21 +44,27 @@ class LoadTracer
|
|
43
44
|
|
44
45
|
LOAD_METHODS = %i(require require_relative load autoload)
|
45
46
|
|
46
|
-
def self.trace(format: nil, exclude_files: [])
|
47
|
-
|
48
|
-
instance.tracer.enable { yield }
|
49
|
-
instance.report(format: format)
|
47
|
+
def self.trace(format: nil, exclude_files: [], &block)
|
48
|
+
new(exclude_files: exclude_files).trace(format: format, &block)
|
50
49
|
end
|
51
50
|
|
52
|
-
def initialize(exclude_files: [])
|
51
|
+
def initialize(format: nil, exclude_files: [])
|
52
|
+
@exclude_files = exclude_files
|
53
|
+
end
|
54
|
+
|
55
|
+
def trace(format: nil)
|
53
56
|
@dependencies = Hash.new { |hash, key| hash[key] = [] }
|
54
57
|
@reverse_dependencies = Hash.new { |hash, key| hash[key] = [] }
|
55
|
-
@
|
58
|
+
@load_checked_features = Hash.new
|
56
59
|
@not_found_features = []
|
60
|
+
|
61
|
+
tracer.enable { yield }
|
62
|
+
|
63
|
+
report(format: format, dependencies: @dependencies, reverse_dependencies: @reverse_dependencies)
|
57
64
|
end
|
58
65
|
|
59
66
|
def tracer
|
60
|
-
TracePoint.new(:
|
67
|
+
TracePoint.new(:return) do |tp|
|
61
68
|
next unless LOAD_METHODS.include?(tp.method_id)
|
62
69
|
next if tp.defined_class != ::Kernel
|
63
70
|
next if tp.path != __FILE__
|
@@ -78,26 +85,37 @@ class LoadTracer
|
|
78
85
|
next
|
79
86
|
end
|
80
87
|
|
88
|
+
@load_checked_features[bl.absolute_path] = true
|
89
|
+
|
81
90
|
@dependencies[bl.absolute_path] << path
|
82
91
|
@reverse_dependencies[path] << bl.absolute_path
|
92
|
+
|
93
|
+
if !tp.return_value && !@load_checked_features[path]
|
94
|
+
file_specs = StaticChecker.parse_file(path)
|
95
|
+
|
96
|
+
file_specs.each do |fs|
|
97
|
+
@dependencies[fs.path] |= fs.dependencies
|
98
|
+
@reverse_dependencies[fs.path] |= fs.reverse_dependencies
|
99
|
+
end
|
100
|
+
end
|
83
101
|
end
|
84
102
|
end
|
85
103
|
|
86
|
-
def report(format:)
|
104
|
+
def report(format:, dependencies:, reverse_dependencies:)
|
87
105
|
case format
|
88
106
|
when :dot
|
89
107
|
DotFormatter.export(
|
90
|
-
dependencies:
|
108
|
+
dependencies: dependencies
|
91
109
|
)
|
92
110
|
when :json
|
93
111
|
JsonFormatter.export(
|
94
|
-
dependencies:
|
95
|
-
reverse_dependencies:
|
112
|
+
dependencies: dependencies,
|
113
|
+
reverse_dependencies: reverse_dependencies
|
96
114
|
)
|
97
115
|
else
|
98
116
|
DefaultFormatter.export(
|
99
|
-
dependencies:
|
100
|
-
reverse_dependencies:
|
117
|
+
dependencies: dependencies,
|
118
|
+
reverse_dependencies: reverse_dependencies
|
101
119
|
)
|
102
120
|
end
|
103
121
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class LoadTracer
|
2
|
+
class StaticChecker < LoadTracer
|
3
|
+
def self.parse_file(path)
|
4
|
+
new(path).trace
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@path = path
|
9
|
+
end
|
10
|
+
|
11
|
+
def trace(format: nil)
|
12
|
+
@dependencies = Hash.new { |hash, key| hash[key] = [] }
|
13
|
+
@reverse_dependencies = Hash.new { |hash, key| hash[key] = [] }
|
14
|
+
@load_checked_features = Hash.new
|
15
|
+
@not_found_features = []
|
16
|
+
|
17
|
+
traverse(path: @path)
|
18
|
+
|
19
|
+
report(format: format, dependencies: @dependencies, reverse_dependencies: @reverse_dependencies)
|
20
|
+
end
|
21
|
+
|
22
|
+
def traverse(path:)
|
23
|
+
return if @load_checked_features[path]
|
24
|
+
return if File.extname(path) != '.rb'
|
25
|
+
|
26
|
+
@load_checked_features[path] = true
|
27
|
+
ast = RubyVM::AbstractSyntaxTree.parse_file(path)
|
28
|
+
features = search_load_features(ast: ast)
|
29
|
+
|
30
|
+
features.each do |feature|
|
31
|
+
feature_path = find_path(feature) || find_path(File.expand_path(feature, File.dirname(path)))
|
32
|
+
|
33
|
+
if feature_path.nil?
|
34
|
+
@not_found_features << feature
|
35
|
+
next
|
36
|
+
end
|
37
|
+
|
38
|
+
traverse(path: feature_path)
|
39
|
+
|
40
|
+
@dependencies[path] << feature_path
|
41
|
+
@reverse_dependencies[feature_path] << path
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def inspector(ast:, &block)
|
48
|
+
ast.children.each do |child|
|
49
|
+
next unless child.instance_of?(RubyVM::AbstractSyntaxTree::Node)
|
50
|
+
|
51
|
+
yield child
|
52
|
+
|
53
|
+
inspector(ast: child, &block)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def search_load_features(ast:)
|
58
|
+
features = []
|
59
|
+
|
60
|
+
inspector(ast: ast) do |node|
|
61
|
+
next if node.type != :FCALL
|
62
|
+
|
63
|
+
method_id = node.children[0]
|
64
|
+
|
65
|
+
next unless LOAD_METHODS.include?(method_id)
|
66
|
+
|
67
|
+
feature = case method_id
|
68
|
+
when :require, :require_relative, :load
|
69
|
+
node.children[1].children[0].children[0]
|
70
|
+
when :autoload
|
71
|
+
node.children[1].children[1].children[0]
|
72
|
+
end
|
73
|
+
|
74
|
+
features << feature if feature.instance_of?(String)
|
75
|
+
end
|
76
|
+
|
77
|
+
features
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/load_tracer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: load_tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shuichi Tamayose
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: binding_of_caller
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/load_tracer/formatter/dot.rb
|
93
93
|
- lib/load_tracer/formatter/json.rb
|
94
94
|
- lib/load_tracer/formatter/templates/default.dot.erb
|
95
|
+
- lib/load_tracer/static_checker.rb
|
95
96
|
- lib/load_tracer/version.rb
|
96
97
|
- load_tracer.gemspec
|
97
98
|
homepage: https://github.com/siman-man/load_tracer
|
@@ -113,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
114
|
- !ruby/object:Gem::Version
|
114
115
|
version: '0'
|
115
116
|
requirements: []
|
116
|
-
rubygems_version: 3.0.
|
117
|
+
rubygems_version: 3.0.3
|
117
118
|
signing_key:
|
118
119
|
specification_version: 4
|
119
120
|
summary: This gem can check the dependency files.
|