source_route 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -0
- data/examples/callback_in_activesupport.rb +1 -2
- data/examples/show_init_files_when_rails_server_start.rb +1 -1
- data/lib/source_route/formats/html.rb +1 -1
- data/lib/source_route/formats/html_template.slim +23 -23
- data/lib/source_route/generate_result.rb +17 -20
- data/lib/source_route/tp_result_chain.rb +8 -3
- data/lib/source_route/version.rb +1 -1
- data/lib/source_route/wrapper.rb +10 -1
- data/lib/source_route.rb +1 -0
- data/test/source_route_test.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e359db40f93fb8aa3973ed198e521e29c21aa2ab
|
4
|
+
data.tar.gz: b0f07e1dce0010f430d54b81b993c0bd7dcb73e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b418b380f34fe5ed9aa794eab4950b6c9936f9f019408047de068412c1986f49d17c0d84cb05e80d302d30af3f27b3d404797d8d2d7077feb7f143bc728437ec
|
7
|
+
data.tar.gz: 02fd9a36fbb122ebadfd660baf1fe19328f272ba0260a5620becdd310bb69b34d68af85655f1355353b9ac375b38f4819f9feb61690c17d4f4358924e8f16ff1
|
data/README.md
CHANGED
@@ -62,6 +62,19 @@ It will output the trace when you run the application.
|
|
62
62
|
see more usage in examples.
|
63
63
|
see full usage in examples/callback_in_activesupport.rb
|
64
64
|
|
65
|
+
## Why
|
66
|
+
|
67
|
+
I always wanna upgrade my ruby(rails) skills. But everytime when I look for workaround from stack overflow I feel frustration.
|
68
|
+
|
69
|
+
To get solution or workaround from google or stack overflow is suitable when I'm a ruby starter or deadline is urgent. But it's not really helpful for my skills.
|
70
|
+
|
71
|
+
The way how I solve problem define my skills border and depth. So if I slove problems by search google and stack overflow with workarounds, I mostly just increase my experiences on ruby(rails). But if I solve problems directly, in most case, I can say my skill border extends.
|
72
|
+
|
73
|
+
That's why I create this gem. To solve problems directly, I need to know what happened in call or return traces.
|
74
|
+
Fortunately ruby 2.0 introduce a new feature TracePoint to easily trace inner event. But it's not easily to be used as daily tool. This gem tries to make tracing more readable and easily in our daily work.
|
75
|
+
|
76
|
+
Finally, I expect my working style can change from searching workaround from internet to reading code trace(then more easily check source) directly. I hope it can help you too.
|
77
|
+
|
65
78
|
## Test
|
66
79
|
|
67
80
|
$ bundle install
|
@@ -78,6 +91,10 @@ see full usage in examples/callback_in_activesupport.rb
|
|
78
91
|
|
79
92
|
### TODO
|
80
93
|
|
94
|
+
Open Method directly from browser
|
95
|
+
|
96
|
+
Apply https://github.com/a5hik/ng-sortable
|
97
|
+
|
81
98
|
Hide defined class filter. Add vertical timeline.
|
82
99
|
(see http://tympanus.net/codrops/2013/05/02/vertical-timeline/
|
83
100
|
http://stackoverflow.com/questions/20896240/responsive-timeline-ui-with-bootstrap3)
|
@@ -3,10 +3,9 @@ require 'active_support/callbacks'
|
|
3
3
|
require 'source_route'
|
4
4
|
|
5
5
|
SourceRoute.enable do
|
6
|
-
event :call, :return
|
7
6
|
defined_class 'ActiveSupport::Callbacks', 'PersonRecord'
|
8
7
|
method_id :base_save, :saving_message, :callback
|
9
|
-
|
8
|
+
full_feature
|
10
9
|
end
|
11
10
|
|
12
11
|
class Record
|
@@ -16,7 +16,7 @@ SourceRoute.enable do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
# The above source route block defines
|
19
|
+
# The above source route block defines trace point feature as following
|
20
20
|
# files = []
|
21
21
|
# tp = TracePoint.new(:line) do |tp|
|
22
22
|
# if tp.path =~ /your_rails_application_root_dir_name/
|
@@ -8,7 +8,7 @@ module SourceRoute
|
|
8
8
|
def self.slim_render(wrapper)
|
9
9
|
result_config = wrapper.condition.result_config
|
10
10
|
template_path = File.expand_path "../html_template.slim", __FILE__
|
11
|
-
slim_template = Slim::Template.new(template_path)
|
11
|
+
slim_template = Slim::Template.new(template_path, pretty: true)
|
12
12
|
|
13
13
|
filename = result_config[:filename] || "#{Time.now.strftime('%H%M')}-source-route.html"
|
14
14
|
|
@@ -13,20 +13,6 @@ html
|
|
13
13
|
.call-level-4 { margin-left: 150px }
|
14
14
|
body(ng-app="SourceRoute" ng-controller="MainCtrl")
|
15
15
|
|
16
|
-
ruby:
|
17
|
-
local_trace_data = @tp_result_chain.map do |tp_result|
|
18
|
-
if tp_result.key?(:defined_class)
|
19
|
-
tp_result[:defined_class] = tp_result[:defined_class].to_s
|
20
|
-
tp_result[:return_value] = tp_result[:return_value].inspect if tp_result.key?(:return_value)
|
21
|
-
end
|
22
|
-
tp_result
|
23
|
-
end
|
24
|
-
|
25
|
-
.data-collect
|
26
|
-
/ dont use local_trace_data.to_json, because ActiveSupport override it and can introduce unexpected crash for some data
|
27
|
-
#trace-data(data-trace="#{JSON.dump(local_trace_data)}" data-tp-events="#{JSON.dump(@condition.events)}")
|
28
|
-
|
29
|
-
|
30
16
|
nav.navbar.navbar-default.navbar-static-top
|
31
17
|
.container
|
32
18
|
.container-fluid
|
@@ -46,12 +32,12 @@ html
|
|
46
32
|
.container
|
47
33
|
.trace-flow
|
48
34
|
.row
|
49
|
-
.left-info.col-sm-4
|
35
|
+
.left-info.col-sm-4(ng-if="false")
|
50
36
|
.btn-group-vertical
|
51
37
|
button.btn.btn-default(ng-repeat="klass in ::definedClasses"
|
52
38
|
ng-click="traceFilter.defined_class = klass" style="height: 60px")
|
53
|
-
span(ng-bind="klass")
|
54
|
-
.traces.center-info.col-sm-
|
39
|
+
span(ng-bind="klass.substring(0, 40)" popover="{{klass}}" popover-trigger="mouseenter" popover-placement="bottom")
|
40
|
+
.traces.center-info.col-sm-12(ng-class="{{traceFilter.event}}")
|
55
41
|
.trace.well.well-lg.call-level.call-level(ng-repeat="trace in traces | filter:traceFilter:true"
|
56
42
|
ng-class="callLevelClass(trace)")
|
57
43
|
.header(ng-click="showMoreDetail = !showMoreDetail")
|
@@ -63,24 +49,24 @@ html
|
|
63
49
|
div(ng-if="trace.hasOwnProperty('return_value')")
|
64
50
|
span
|
65
51
|
| =>
|
66
|
-
span<(ng-bind="trace.return_value")
|
52
|
+
span<(ng-bind="trace.return_value.substring(0, 150)")
|
67
53
|
|
68
54
|
.details(ng-if="showMoreDetail")
|
69
|
-
.local-vars.well.well-sm(ng-if="trace.local_var" style="color: green")
|
55
|
+
.local-vars.well.well-sm(ng-if="trace.local_var" style="color: green; margin-bottom: 0")
|
70
56
|
span Local Var
|
71
57
|
.local-values(ng-repeat="(key, value) in trace.local_var")
|
72
58
|
span<>(ng-bind="key")
|
73
59
|
span<>
|
74
60
|
| =>
|
75
61
|
/ ? could inspect repaire it ?
|
76
|
-
span<>(ng-bind="value
|
77
|
-
.ins-vars.well.well-sm(ng-if="trace.instance_var" style="color: blue")
|
62
|
+
span<>(ng-bind="value | json")
|
63
|
+
.ins-vars.well.well-sm(ng-if="trace.instance_var" style="color: blue; margin-bottom: 0")
|
78
64
|
span Instance Var
|
79
65
|
.ins-values(ng-repeat="(key, value) in trace.instance_var")
|
80
66
|
span<>(ng-bind="key")
|
81
67
|
span<>
|
82
68
|
| =>
|
83
|
-
span<>(ng-bind="value
|
69
|
+
span<>(ng-bind="value | json")
|
84
70
|
.path-value.well.well-sm(ng-if="trace.path")
|
85
71
|
span Path
|
86
72
|
div
|
@@ -90,9 +76,10 @@ html
|
|
90
76
|
.right-info.col-sm-2
|
91
77
|
|
92
78
|
script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"
|
79
|
+
script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.2/ui-bootstrap-tpls.min.js"
|
93
80
|
|
94
81
|
javascript:
|
95
|
-
sourceRoute = angular.module('SourceRoute', [])
|
82
|
+
sourceRoute = angular.module('SourceRoute', ['ui.bootstrap'])
|
96
83
|
sourceRoute.controller('MainCtrl', function($scope, $filter) {
|
97
84
|
$scope.traces = angular.element("#trace-data").data('trace')
|
98
85
|
$scope.tpEvents = angular.element("#trace-data").data('tp-events')
|
@@ -122,3 +109,16 @@ html
|
|
122
109
|
}
|
123
110
|
|
124
111
|
})
|
112
|
+
|
113
|
+
ruby:
|
114
|
+
local_trace_data = @tp_result_chain.map do |tp_result|
|
115
|
+
if tp_result.key?(:defined_class)
|
116
|
+
tp_result[:defined_class] = tp_result[:defined_class].to_s
|
117
|
+
tp_result[:return_value] = tp_result[:return_value].inspect if tp_result.key?(:return_value)
|
118
|
+
end
|
119
|
+
tp_result
|
120
|
+
end
|
121
|
+
|
122
|
+
.data-collect
|
123
|
+
/ dont use local_trace_data.to_json, because ActiveSupport override it and can introduce unexpected crash for some data
|
124
|
+
#trace-data(data-trace="#{JSON.dump(local_trace_data)}" data-tp-events="#{JSON.dump(@condition.events)}")
|
@@ -3,7 +3,7 @@ module SourceRoute
|
|
3
3
|
class GenerateResult
|
4
4
|
|
5
5
|
Config = Struct.new(:format, :show_additional_attrs,
|
6
|
-
:include_local_var, :include_instance_var,
|
6
|
+
:include_local_var, :include_instance_var, :include_tp_self,
|
7
7
|
:filename, :import_return_to_call) do
|
8
8
|
def initialize(f="silence", s=[], ilr=false, iiv=false)
|
9
9
|
super(f, s, ilr, iiv)
|
@@ -44,8 +44,9 @@ module SourceRoute
|
|
44
44
|
def build(trace_point_instance)
|
45
45
|
@tp = trace_point_instance
|
46
46
|
collect_tp_data
|
47
|
-
|
48
|
-
|
47
|
+
@collect_data[:tp_self] = @tp.self if @config[:include_tp_self]
|
48
|
+
collect_local_var_data if @config[:include_local_var]
|
49
|
+
collect_instance_var_data if @config[:include_instance_var]
|
49
50
|
@collect_data
|
50
51
|
end
|
51
52
|
|
@@ -84,27 +85,23 @@ module SourceRoute
|
|
84
85
|
end
|
85
86
|
|
86
87
|
def collect_local_var_data
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
@tp.binding.
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
@collect_data.merge!(local_var: local_var_hash)
|
95
|
-
end
|
88
|
+
local_var_hash = {}
|
89
|
+
|
90
|
+
@tp.binding.eval('local_variables').each do |v|
|
91
|
+
local_var_hash[v] = @tp.binding.local_variable_get v
|
92
|
+
end
|
93
|
+
if local_var_hash != {}
|
94
|
+
@collect_data.merge!(local_var: local_var_hash)
|
96
95
|
end
|
97
96
|
end
|
98
97
|
|
99
98
|
def collect_instance_var_data
|
100
|
-
|
101
|
-
|
102
|
-
@tp.self.
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
@collect_data.merge!(instance_var: instance_var_hash)
|
107
|
-
end
|
99
|
+
instance_var_hash = {}
|
100
|
+
@tp.self.instance_variables.each do |key|
|
101
|
+
instance_var_hash[key] = @tp.self.instance_variable_get(key)
|
102
|
+
end
|
103
|
+
if instance_var_hash != {}
|
104
|
+
@collect_data.merge!(instance_var: instance_var_hash)
|
108
105
|
end
|
109
106
|
end
|
110
107
|
|
@@ -20,9 +20,14 @@ module SourceRoute
|
|
20
20
|
|
21
21
|
def import_return_value_to_call_chain
|
22
22
|
call_chain.each do |ctp|
|
23
|
-
|
24
|
-
rtp[:defined_class] == ctp[:defined_class] and rtp[:method_id] == ctp[:method_id]
|
25
|
-
|
23
|
+
matched_return_tp = return_chain.detect do |rtp|
|
24
|
+
rtp[:defined_class] == ctp[:defined_class] and rtp[:method_id] == ctp[:method_id] and
|
25
|
+
rtp[:tp_self] == ctp[:tp_self]
|
26
|
+
|
27
|
+
end
|
28
|
+
ctp[:return_value] = matched_return_tp[:return_value]
|
29
|
+
ctp[:local_var] = matched_return_tp[:local_var]
|
30
|
+
ctp[:instance_var] = matched_return_tp[:instance_var]
|
26
31
|
end
|
27
32
|
end
|
28
33
|
|
data/lib/source_route/version.rb
CHANGED
data/lib/source_route/wrapper.rb
CHANGED
@@ -30,7 +30,6 @@ module SourceRoute
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def event(*v)
|
33
|
-
# why need self? without self, the events will not really changed, why?. seems a bug in Struct
|
34
33
|
self.events = v.map(&:to_sym) unless v == []
|
35
34
|
end
|
36
35
|
|
@@ -41,6 +40,16 @@ module SourceRoute
|
|
41
40
|
def has_call_and_return_event
|
42
41
|
events.include? :return and events.include? :call
|
43
42
|
end
|
43
|
+
|
44
|
+
def full_feature(value=true)
|
45
|
+
return unless value
|
46
|
+
|
47
|
+
self.events = [:call, :return]
|
48
|
+
result_config.import_return_to_call = true
|
49
|
+
result_config.include_instance_var = true
|
50
|
+
result_config.include_local_var = true
|
51
|
+
result_config.include_tp_self = true
|
52
|
+
end
|
44
53
|
end
|
45
54
|
|
46
55
|
def initialize
|
data/lib/source_route.rb
CHANGED
data/test/source_route_test.rb
CHANGED
@@ -104,6 +104,15 @@ class SourceRouteTest < Minitest::Test
|
|
104
104
|
assert_equal 2, @wrapper.tp_result_chain.size
|
105
105
|
end
|
106
106
|
|
107
|
+
def test_trace_with_full_feature
|
108
|
+
SourceRoute.trace method_id: 'nonsense', full_feature: true do
|
109
|
+
SampleApp.new.nonsense
|
110
|
+
end
|
111
|
+
assert @wrapper.condition.result_config.include_tp_self
|
112
|
+
first_result = @wrapper.tp_result_chain.first
|
113
|
+
assert first_result[:tp_self]
|
114
|
+
end
|
115
|
+
|
107
116
|
def test_trace_without_first_hash_option
|
108
117
|
SourceRoute.trace output_format: :test do
|
109
118
|
SampleApp.new.nonsense
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: source_route
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- raykin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|