kefka 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
data/app.rb CHANGED
@@ -12,21 +12,36 @@ end
12
12
  get '/callgraph' do
13
13
  content_type :json
14
14
 
15
- path = "examples/sample_a.rb"
15
+ path = "#{File.expand_path(File.dirname(__FILE__))}/examples/sample_a.rb"
16
16
  file = File.open(path)
17
17
 
18
18
  @tracer = Kefka::Tracer.new
19
19
  @tracer.trace(file, :callgraph_handler)
20
20
 
21
+ # input code
22
+ code = CodeRay.scan(@tracer.code, :ruby).div(:line_numbers => :table)
23
+
21
24
  graph = @tracer.method_graph
25
+
26
+ # output call graph using dot if graphviz is installed
27
+ if graphviz_installed = system("which dot")
28
+ graph.write_to_graphic_file("png", "#{File.expand_path(File.dirname(__FILE__))}/public/graph")
29
+ end
30
+
31
+ # html code graph
22
32
  graph.vertices.each { |method| method.format = :html }
23
- graph.to_json
33
+
34
+ {
35
+ :code => code,
36
+ :graphviz_installed => graphviz_installed,
37
+ :graph => graph
38
+ }.to_json
24
39
  end
25
40
 
26
41
  get '/locals' do
27
42
  content_type :json
28
43
 
29
- path = "examples/sample_a.rb"
44
+ path = "#{File.expand_path(File.dirname(__FILE__))}/examples/sample_a.rb"
30
45
  file = File.open(path)
31
46
 
32
47
  tracer = Kefka::Tracer.new
data/kefka.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "kefka"
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Reginald Tan"]
12
- s.date = "2012-07-30"
12
+ s.date = "2012-08-12"
13
13
  s.description = " It traces the execution path of a program and displays the source code of each method call in the callgraph "
14
14
  s.email = "redge.tan@gmail.com"
15
15
  s.executables = ["kefka"]
data/lib/kefka.rb CHANGED
@@ -22,12 +22,10 @@ class Kefka
22
22
  end
23
23
 
24
24
  def source_location
25
- return nil unless @file && @line
26
25
  [@file,@line]
27
26
  end
28
27
 
29
28
  def end_line
30
- return nil unless @line && source
31
29
  @line + source.lines.count - 1
32
30
  end
33
31
 
@@ -61,6 +59,14 @@ class Kefka
61
59
  "#{classname} #{id}"
62
60
  end
63
61
 
62
+ def eql?(other)
63
+ self.key == other.key
64
+ end
65
+
66
+ def hash
67
+ [@file,@line].hash
68
+ end
69
+
64
70
  def to_json(*a)
65
71
  {
66
72
  :classname => @classname,
@@ -97,7 +103,8 @@ class Kefka
97
103
 
98
104
  class Tracer
99
105
 
100
- attr_reader :method_table, :local_values, :logger, :callstack, :method_graph
106
+ attr_reader :local_values, :logger, :callstack, :method_graph,
107
+ :code
101
108
 
102
109
  def initialize(log_level = Logger::INFO)
103
110
  @method_graph = MethodGraph.new
@@ -108,17 +115,21 @@ class Kefka
108
115
  @logger.level = log_level
109
116
  end
110
117
 
118
+ def get_locals(target)
119
+ target.eval("local_variables")
120
+ end
121
+
122
+ def deep_copy(val)
123
+ Marshal.load(Marshal.dump(val))
124
+ rescue TypeError
125
+ "_unknown_"
126
+ end
127
+
111
128
  def get_values_of_locals_from_binding(target)
112
- locals = target.eval("local_variables")
129
+ locals = get_locals(target)
113
130
  locals.inject({}) do |result,l|
114
131
  val = target.eval(l.to_s)
115
- val = begin
116
- # deep copy
117
- Marshal.load(Marshal.dump(val)) if val
118
- rescue TypeError
119
- "_unknown_"
120
- end
121
-
132
+ val = deep_copy(val)
122
133
  result.merge!({ l => val })
123
134
  result
124
135
  end
@@ -193,12 +204,17 @@ class Kefka
193
204
  end
194
205
  end
195
206
 
207
+ def print_callgraph
208
+ public_dir = "#{File.expand_path(File.dirname(__FILE__))}/../public"
209
+ @method_graph.write_to_graphic_file("png", "#{public_dir}/graph")
210
+ end
211
+
196
212
  def trace(file_path, handler = :callgraph_handler)
197
213
  file = File.open(file_path)
198
214
 
199
215
  thread = Thread.new {
200
- code = file.read
201
- eval(code, TOPLEVEL_BINDING, file.path, 1)
216
+ @code = file.read
217
+ eval(@code, TOPLEVEL_BINDING, file.path, 1)
202
218
  }
203
219
 
204
220
  thread.set_trace_func method(handler).to_proc
@@ -5,22 +5,31 @@ var jqSelectorEscape = function(text) {
5
5
  var createCodeBubbles = function(data) {
6
6
  console.log(data);
7
7
 
8
- var methodGraph = data;
8
+ var input = data.code;
9
+
10
+ $("div#input").last().append(input);
11
+
12
+ if (data.graphviz_installed == true) {
13
+ $("div#callGraph").last().append("<img src='graph.png'/>");
14
+ } else {
15
+ $("div#callGraph").last().append("Graphviz visualization not Available. Install Graphviz to enable it.");
16
+ }
17
+
18
+ var codeGraph = data.graph;
9
19
 
10
20
  var xPos = 0;
11
- var yPos = 0;
12
21
  var bubbleDiv, $bubble, $code,
13
22
  key, header,
14
23
  lineCount, column;
15
24
 
16
- var methods = methodGraph.vertices;
25
+ var methods = codeGraph.vertices;
17
26
 
18
27
  for (var i = 0; i < methods.length; i++ )
19
28
  {
20
29
  bubbleDiv = "<div class='bubble'></div>";
21
- $(bubbleDiv).appendTo("#methodGraph");
30
+ $(bubbleDiv).appendTo("#codeGraph");
22
31
 
23
- $bubble = $("#methodGraph .bubble").last();
32
+ $bubble = $("#codeGraph .bubble").last();
24
33
  $bubble.append(methods[i].source);
25
34
 
26
35
  // set id for bubble table
@@ -36,11 +45,8 @@ var createCodeBubbles = function(data) {
36
45
  //xPos = $callerBubble.position().left + 200;
37
46
 
38
47
  // position bubble table
39
- $bubble.css("position", "absolute")
40
- .css("left", xPos)
41
- .css("top", yPos);
42
-
43
- yPos += $bubble.height();
48
+ $bubble.css("position", "relative")
49
+ .css("left", xPos);
44
50
 
45
51
  // add column for displaying local values
46
52
  lineCount = $bubble.find("td.line-numbers a").length;
data/views/index.erb CHANGED
@@ -11,7 +11,18 @@ Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
11
11
  </head>
12
12
 
13
13
  <body>
14
- <div id="methodGraph">
14
+ <h1 id="input_header">Input</h1>
15
+ <div id="input">
16
+
17
+ </div>
18
+
19
+ <h1 id="codegraph_header">Graphviz CallGraph</h1>
20
+ <div id="callGraph">
21
+
22
+ </div>
23
+
24
+ <h1 id="codegraph_header">CodeGraph</h1>
25
+ <div id="codeGraph">
15
26
 
16
27
  </div>
17
28
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kefka
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-30 00:00:00.000000000 Z
12
+ date: 2012-08-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yajl-ruby
16
- requirement: &70228522339920 !ruby/object:Gem::Requirement
16
+ requirement: &70273937010140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70228522339920
24
+ version_requirements: *70273937010140
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: coderay
27
- requirement: &70228522338980 !ruby/object:Gem::Requirement
27
+ requirement: &70273937009600 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70228522338980
35
+ version_requirements: *70273937009600
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sinatra
38
- requirement: &70228522338180 !ruby/object:Gem::Requirement
38
+ requirement: &70273937008940 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70228522338180
46
+ version_requirements: *70273937008940
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: method_source
49
- requirement: &70228522337200 !ruby/object:Gem::Requirement
49
+ requirement: &70273936990620 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70228522337200
57
+ version_requirements: *70273936990620
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rgl
60
- requirement: &70228522336240 !ruby/object:Gem::Requirement
60
+ requirement: &70273936989280 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70228522336240
68
+ version_requirements: *70273936989280
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry
71
- requirement: &70228522335260 !ruby/object:Gem::Requirement
71
+ requirement: &70273936987380 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70228522335260
79
+ version_requirements: *70273936987380
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: pry-doc
82
- requirement: &70228522334380 !ruby/object:Gem::Requirement
82
+ requirement: &70273936986160 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70228522334380
90
+ version_requirements: *70273936986160
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rspec
93
- requirement: &70228522333560 !ruby/object:Gem::Requirement
93
+ requirement: &70273936984420 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70228522333560
101
+ version_requirements: *70273936984420
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: jeweler
104
- requirement: &70228522332680 !ruby/object:Gem::Requirement
104
+ requirement: &70273936983420 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70228522332680
112
+ version_requirements: *70273936983420
113
113
  description: ! ' It traces the execution path of a program and displays the source
114
114
  code of each method call in the callgraph '
115
115
  email: redge.tan@gmail.com
@@ -155,7 +155,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
155
  version: '0'
156
156
  segments:
157
157
  - 0
158
- hash: 2834341029582018531
158
+ hash: -1427345181685482934
159
159
  required_rubygems_version: !ruby/object:Gem::Requirement
160
160
  none: false
161
161
  requirements: