mkgraph 1.1.0
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/README +6 -0
- data/lib/mgopts.yml +9 -0
- data/lib/mkgraph.rb +307 -0
- data/test/test_mkgraph.rb +36 -0
- data/test/tt.rb +61 -0
- metadata +99 -0
data/README
ADDED
data/lib/mgopts.yml
ADDED
data/lib/mkgraph.rb
ADDED
@@ -0,0 +1,307 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
## $Author :: Cliff
|
4
|
+
## $Version:: 1v0
|
5
|
+
##
|
6
|
+
##
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'graphviz'
|
11
|
+
require 'tree'
|
12
|
+
require 'logger'
|
13
|
+
require 'yaml'
|
14
|
+
|
15
|
+
#
|
16
|
+
# Example : Mkgraph#new <ruby.rb> - initialise
|
17
|
+
# Mkgraph#run - process file
|
18
|
+
# Mkgraph#make_image - create the image file
|
19
|
+
# Mkgraph#show_image - display the image file
|
20
|
+
#
|
21
|
+
# Arguments: The file to be visualised when creating a new instance
|
22
|
+
#
|
23
|
+
# Note : A valid mgopts.yml must be in the working directory.
|
24
|
+
# == You could copy a template file from the gem installation directory.
|
25
|
+
#
|
26
|
+
|
27
|
+
class Mkgraph
|
28
|
+
|
29
|
+
#
|
30
|
+
# Initialise
|
31
|
+
#
|
32
|
+
# Params: The name of the file to be processed
|
33
|
+
#
|
34
|
+
def initialize pattern
|
35
|
+
|
36
|
+
begin
|
37
|
+
$yml = YAML.load_file 'mgopts.yml'
|
38
|
+
rescue Exception => e
|
39
|
+
print e.message + "\n"
|
40
|
+
print "You could use the default \'mgopts.yml\' file in the installation\n"
|
41
|
+
print "directory as a template.\n"
|
42
|
+
print "Example:\n"
|
43
|
+
|
44
|
+
tip = <<-EOS
|
45
|
+
Log Options:
|
46
|
+
format: brief # brief or full
|
47
|
+
output: stderr # stderr, stdout or file name
|
48
|
+
level: WARN # INFO, WARN or FATAL
|
49
|
+
Labels:
|
50
|
+
root: Entry Point
|
51
|
+
root comment: The Root Comment
|
52
|
+
Output:
|
53
|
+
image name: view.png
|
54
|
+
EOS
|
55
|
+
|
56
|
+
puts "#{tip}"
|
57
|
+
exit 1
|
58
|
+
end
|
59
|
+
|
60
|
+
# puts $yml['sectionA']['user'] + "**************\n"
|
61
|
+
# puts $yml['sectionB']['file'] + "**************\n"
|
62
|
+
log_fmt = $yml['Log Options']['format']
|
63
|
+
|
64
|
+
log_opt = $yml['Log Options']['output']
|
65
|
+
case log_opt
|
66
|
+
when 'stderr'
|
67
|
+
log_op = $stderr
|
68
|
+
when 'stdout'
|
69
|
+
log_op = $stdout
|
70
|
+
else
|
71
|
+
log_op = log_opt
|
72
|
+
end
|
73
|
+
|
74
|
+
loglev = $yml['Log Options']['level']
|
75
|
+
case loglev
|
76
|
+
when 'INFO'
|
77
|
+
ll = Logger::INFO
|
78
|
+
when 'WARN'
|
79
|
+
ll = Logger::WARN
|
80
|
+
else
|
81
|
+
ll = Logger::FATAL
|
82
|
+
end
|
83
|
+
|
84
|
+
@file_pattern = pattern
|
85
|
+
|
86
|
+
$LOG = Logger.new(log_op).tap do |log|
|
87
|
+
log.progname = 'mkgraph'
|
88
|
+
log.level = ll # Logger::INFO # $yml['Log Options']['level']
|
89
|
+
if log_fmt == 'brief'
|
90
|
+
log.formatter = proc do |severity, datetime, progname, msg|
|
91
|
+
"#{progname}: #{msg}\n"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
$LOG.info "Pattern: " + @file_pattern
|
97
|
+
# Rough test for OS TODO
|
98
|
+
if RUBY_PLATFORM.include?("linux") == false
|
99
|
+
$windows = true
|
100
|
+
else
|
101
|
+
$windows = false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Does the work.
|
107
|
+
# Params: None
|
108
|
+
#
|
109
|
+
def run
|
110
|
+
end_count = 0
|
111
|
+
end_expected = 0 # how many ends before class end
|
112
|
+
class_end_expected = 0 # how many class ends we expect (internal definitions)
|
113
|
+
cname = ""
|
114
|
+
in_class = false
|
115
|
+
parent_class_name = nil
|
116
|
+
print_parent = true
|
117
|
+
|
118
|
+
$iname = $yml['Output']['image name']
|
119
|
+
|
120
|
+
$root_node = Tree::TreeNode.new($yml['Labels']['root'], $yml['Labels']['root comment'])
|
121
|
+
tnode = $root_node
|
122
|
+
|
123
|
+
# Process all file matching @file_pattern
|
124
|
+
Dir.glob(@file_pattern) do |file|
|
125
|
+
|
126
|
+
$LOG.info "Looking at file - " + file
|
127
|
+
ignore = false
|
128
|
+
|
129
|
+
next if file == '.' or file == '..'
|
130
|
+
|
131
|
+
# Process each line in the file
|
132
|
+
File.open(file) do |f|
|
133
|
+
f.each_line do |line|
|
134
|
+
|
135
|
+
# Ignore =begin/=end blocks
|
136
|
+
if line.match(/^=end/) != nil
|
137
|
+
ignore = false
|
138
|
+
elsif line.match(/^=begin/) != nil
|
139
|
+
ignore = true
|
140
|
+
else
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
|
144
|
+
next if ignore == true
|
145
|
+
|
146
|
+
# Process the line read from file
|
147
|
+
case line
|
148
|
+
when /^\s*#/
|
149
|
+
nil
|
150
|
+
when /\s*when.*new/ # only to avoid this situation HERE
|
151
|
+
nil
|
152
|
+
when /\'\.new/ # only to avoid the situation in line.split('.new')
|
153
|
+
nil
|
154
|
+
when /\.new/
|
155
|
+
name = line.split('.new')
|
156
|
+
cname = name[0].split.last
|
157
|
+
if in_class == true
|
158
|
+
$LOG.debug "NEW INSTANCE OF CLASS = [" + cname + "] created in class " + parent_class_name
|
159
|
+
tnode = proc_node tnode, parent_class_name, cname, false, false
|
160
|
+
else
|
161
|
+
if true == print_parent
|
162
|
+
$LOG.debug "NEW INSTANCE OF CLASS = [" + cname + "] created outside any parent class"
|
163
|
+
tnode = proc_node tnode, parent_class_name, cname, true, true
|
164
|
+
end
|
165
|
+
end
|
166
|
+
when /^\s*elsif/
|
167
|
+
nil
|
168
|
+
when /^\s*class[\s]+/
|
169
|
+
parent_class_name = line.split(' ')[1]
|
170
|
+
class_end_expected += 1
|
171
|
+
in_class = true
|
172
|
+
if print_parent == true
|
173
|
+
$LOG.info "Start of class " + parent_class_name
|
174
|
+
end
|
175
|
+
tnode = proc_node tnode, $root_node.name, parent_class_name, true, false
|
176
|
+
when /^\s*begin/
|
177
|
+
end_expected += 1
|
178
|
+
when /^.*if /
|
179
|
+
end_expected += 1
|
180
|
+
when /^\s*def /
|
181
|
+
end_expected += 1
|
182
|
+
when /^.* do/
|
183
|
+
end_expected += 1
|
184
|
+
when /^\s*case/
|
185
|
+
end_expected += 1
|
186
|
+
when /^\s*end[\s.]/
|
187
|
+
if end_expected == 0
|
188
|
+
if class_end_expected > 0
|
189
|
+
class_end_expected -= 1
|
190
|
+
in_class = false
|
191
|
+
if print_parent == true && parent_class_name != nil
|
192
|
+
$LOG.info "End of class " + parent_class_name
|
193
|
+
end
|
194
|
+
parent_class_name = nil
|
195
|
+
end
|
196
|
+
else
|
197
|
+
end_expected -= 1
|
198
|
+
end
|
199
|
+
end # case
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
# Recursive method used to find a name (ID) in the Tree object
|
207
|
+
def find_leaf root, sname
|
208
|
+
|
209
|
+
$LOG.debug "find_leaf searching for: [" + sname + "] This Root is " + root.name
|
210
|
+
r = root
|
211
|
+
|
212
|
+
if root != nil && root.name != sname
|
213
|
+
root.children { |child|
|
214
|
+
r = find_leaf child, sname
|
215
|
+
break if r.name == sname
|
216
|
+
}
|
217
|
+
else
|
218
|
+
$LOG.info "NIL OR FOUND [" + root.name + "]"
|
219
|
+
r = root
|
220
|
+
end
|
221
|
+
$LOG.info "find_leaf returning: [" + r.name + "]"
|
222
|
+
r
|
223
|
+
end
|
224
|
+
|
225
|
+
# Process a line of interest i.e. when a class is being
|
226
|
+
# defined or instanciated etc. Called from the 'run' method
|
227
|
+
def proc_node root, par, child, join_to_root, used
|
228
|
+
begin
|
229
|
+
if join_to_root == true
|
230
|
+
if true == used
|
231
|
+
$root_node << Tree::TreeNode.new(child, "child")
|
232
|
+
else
|
233
|
+
$root_node << Tree::TreeNode.new(child, "orphan")
|
234
|
+
end
|
235
|
+
else
|
236
|
+
$LOG.info "NEED TO ATTACH " + child + " TO: " + par
|
237
|
+
r = find_leaf root, par
|
238
|
+
$LOG.info "AFTER FIND_LEAF: " + r.name
|
239
|
+
r << Tree::TreeNode.new(child, "used")
|
240
|
+
end
|
241
|
+
rescue Exception => e
|
242
|
+
$LOG.info e.message
|
243
|
+
$LOG.info "***** Processing node " + "None" + " --> " + child.to_s
|
244
|
+
end
|
245
|
+
# $root_node.printTree
|
246
|
+
|
247
|
+
root
|
248
|
+
end
|
249
|
+
|
250
|
+
# Recursive method to add elements from the Tree to the GraphViz Tree
|
251
|
+
def add_element g, root
|
252
|
+
if root.hasChildren? == true
|
253
|
+
root.children { |child|
|
254
|
+
add_element g, child
|
255
|
+
}
|
256
|
+
end
|
257
|
+
|
258
|
+
if root.isRoot?
|
259
|
+
g.add_node root.name, {:label => "{{" + root.name + "|" + root.content + "}|" + "Root}", :style => "filled", :fillcolor => "lightblue", :shape => "record", :color =>"black"}
|
260
|
+
else
|
261
|
+
g.add_node root.name , {:shape => "egg", :color =>"violet"}
|
262
|
+
end
|
263
|
+
|
264
|
+
if ! root.isRoot?
|
265
|
+
# Add an edge to the parent
|
266
|
+
if root.content == "orphan"
|
267
|
+
g.add_edge(root.parent.name, root.name, :label => root.parent.name + " contains " + root.name, :color => "red", :fontcolor => "red")
|
268
|
+
else
|
269
|
+
g.add_edge(root.parent.name, root.name, :label => root.parent.name + " uses " + root.name, :color => "blue", :fontcolor => "blue")
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
g
|
274
|
+
end
|
275
|
+
|
276
|
+
public
|
277
|
+
# Use Graphviz to create the image file
|
278
|
+
def make_image
|
279
|
+
g = GraphViz.new( :G, :rankdir => "TB", :type => :digraph, :bgcolor => "lightgrey", :nodesep => 0.85, :normalize => true, :concentrate => true)
|
280
|
+
root = $root_node
|
281
|
+
g = add_element g, root
|
282
|
+
if $windows != true
|
283
|
+
res = system("rm " + $iname + " > /dev/null")
|
284
|
+
end
|
285
|
+
begin
|
286
|
+
g.output( :png => $iname)
|
287
|
+
rescue Exception => e
|
288
|
+
$LOG.warn e.message + "\n"
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
# Display the image file
|
293
|
+
def show_image
|
294
|
+
begin
|
295
|
+
if $windows != true
|
296
|
+
res = system("pkill eog; " + $yml['Osdep']['viewer'] + " " + $iname + " > /dev/null 2>&1")
|
297
|
+
else
|
298
|
+
res = system("call " + $yml['Osdep']['viewer'] + " " + $iname)
|
299
|
+
end
|
300
|
+
if res == false
|
301
|
+
raise "Bad Command"
|
302
|
+
end
|
303
|
+
rescue Exception => e
|
304
|
+
$LOG.info e.message
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/ruby -W0
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'mkgraph'
|
6
|
+
|
7
|
+
$LOAD_PATH <<'.'<<'lib'
|
8
|
+
|
9
|
+
|
10
|
+
me = File::basename($0)
|
11
|
+
|
12
|
+
if ARGV.size > 0
|
13
|
+
file_pattern = ARGV[0]
|
14
|
+
if file_pattern == "me"
|
15
|
+
file_pattern = me
|
16
|
+
me = "XXXXX"
|
17
|
+
print "me = " + me
|
18
|
+
else
|
19
|
+
if ! File.exist?(ARGV[0])
|
20
|
+
print "Cannot find file " + ARGV[0] + "\n"
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
file_pattern = "**/*.rb"
|
26
|
+
end
|
27
|
+
|
28
|
+
# print "File pattern is " + file_pattern + "\n"
|
29
|
+
a = Mkgraph.new file_pattern
|
30
|
+
|
31
|
+
a.run
|
32
|
+
|
33
|
+
a.make_image
|
34
|
+
|
35
|
+
exit 0
|
36
|
+
|
data/test/tt.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
a = A.new
|
3
|
+
E.new
|
4
|
+
|
5
|
+
class E
|
6
|
+
def initialize
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class A
|
11
|
+
def initialize
|
12
|
+
end
|
13
|
+
|
14
|
+
def m1
|
15
|
+
d = D.new
|
16
|
+
E.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def m2
|
20
|
+
b = B.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class B
|
25
|
+
def initialize
|
26
|
+
end
|
27
|
+
|
28
|
+
def m1
|
29
|
+
A.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def m2
|
33
|
+
C.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class C
|
38
|
+
def initialize
|
39
|
+
A.new
|
40
|
+
B.new
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
class D
|
46
|
+
def initialize
|
47
|
+
# E.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class l
|
52
|
+
def initialize
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
=begin
|
57
|
+
class p
|
58
|
+
def initialize
|
59
|
+
end
|
60
|
+
end
|
61
|
+
=end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mkgraph
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Cliff
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-06-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ruby-graphviz
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.0'
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.0.9
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.0'
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 1.0.9
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: tree
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0.2'
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.2.1
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.2'
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.2.1
|
58
|
+
description: Create class dependancy graph. This is only partially complete.
|
59
|
+
email: cliff@dev.win.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- lib/mkgraph.rb
|
65
|
+
- test/test_mkgraph.rb
|
66
|
+
- test/tt.rb
|
67
|
+
- lib/mgopts.yml
|
68
|
+
- README
|
69
|
+
homepage: http://dev.win.com
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options:
|
74
|
+
- --title
|
75
|
+
- Mkgraph
|
76
|
+
- --main
|
77
|
+
- README
|
78
|
+
- --line-numbers
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.28
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: Dependancy Graph
|
99
|
+
test_files: []
|