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 ADDED
@@ -0,0 +1,6 @@
1
+ Mkgraph
2
+ =======
3
+
4
+ A class dependency visualiser
5
+
6
+
@@ -0,0 +1,9 @@
1
+ Log Options:
2
+ format: brief # brief or full
3
+ output: stderr # stderr, stdout or file name
4
+ level: WARN # INFO, WARN or FATAL
5
+ Labels:
6
+ root: Entry Point
7
+ root comment: The Root Comment
8
+ Output:
9
+ image name: view.png
@@ -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
+
@@ -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: []