graph 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest CHANGED
@@ -3,22 +3,6 @@
3
3
  require 'autotest/restart'
4
4
  require 'autotest/rcov'
5
5
 
6
- # Autotest.add_hook :initialize do |at|
7
- # at.extra_files << "../some/external/dependency.rb"
8
- #
9
- # at.libs << ":../some/external"
10
- #
11
- # at.add_exception 'vendor'
12
- #
13
- # at.add_mapping(/dependency.rb/) do |f, _|
14
- # at.files_matching(/test_.*rb$/)
15
- # end
16
- #
17
- # %w(TestA TestB).each do |klass|
18
- # at.extra_class_map[klass] = "test/test_misc.rb"
19
- # end
20
- # end
21
-
22
- # Autotest.add_hook :run_command do |at|
23
- # system "rake build"
24
- # end
6
+ Autotest.add_hook :initialize do |at|
7
+ at.testlib = "minitest/autorun"
8
+ end
data/History.txt CHANGED
@@ -1,3 +1,23 @@
1
+ === 1.2.0 / 2010-03-30
2
+
3
+ * 10 minor enhancements:
4
+
5
+ * Added rake_analyzer.rb to help visualize rake dependencies. YAY!
6
+ * Added #boxes to convert all nodes to boxes.
7
+ * Added #global_attrib to set attribs on all nodes.
8
+ * Added #nodes to return all nodes (even if not part of from-edge).
9
+ * Added #normalize to remove duplicate edges.
10
+ * Added #orient to set graph orientation.
11
+ * Added #rotate as LR alias to #orient.
12
+ * Added full rdoc for Graph.
13
+ * Switched to minitest.
14
+ * Updated Hoe setup.
15
+
16
+ * 2 bug fixes:
17
+
18
+ * Fixed inherited #clear to ensure ivars cleared as well.
19
+ * Fixed scanner to work with new macports deps output
20
+
1
21
  === 1.1.0 / 2009-04-16
2
22
 
3
23
  * 3 minor enhancements:
data/Manifest.txt CHANGED
@@ -8,6 +8,7 @@ lib/dep_analyzer.rb
8
8
  lib/freebsd_analyzer.rb
9
9
  lib/graph.rb
10
10
  lib/macports_analyzer.rb
11
+ lib/rake_analyzer.rb
11
12
  lib/rubygems/commands/graph_command.rb
12
13
  lib/rubygems_analyzer.rb
13
14
  lib/rubygems_plugin.rb
data/Rakefile CHANGED
@@ -4,9 +4,12 @@ require 'rubygems'
4
4
  require 'hoe'
5
5
  require './lib/graph.rb'
6
6
 
7
- Hoe.new('graph', Graph::VERSION) do |p|
8
- p.rubyforge_name = 'seattlerb'
9
- p.developer('Ryan Davis', 'ryand-ruby@zenspider.com')
7
+ Hoe.plugin :seattlerb
8
+
9
+ Hoe.spec 'graph' do
10
+ developer 'Ryan Davis', 'ryand-ruby@zenspider.com'
11
+
12
+ self.rubyforge_name = 'seattlerb'
10
13
  end
11
14
 
12
15
  # vim: syntax=Ruby
data/lib/dep_analyzer.rb CHANGED
@@ -116,7 +116,7 @@ class DepAnalyzer < Cache
116
116
  end
117
117
  end
118
118
 
119
- puts "Looks like you can nuke:\n\t#{indies.join("\n\t")}"
119
+ puts "Looks like you can nuke:\n\t#{indies.sort.join("\n\t")}"
120
120
 
121
121
  unless argv.empty? then
122
122
  argv.each do |pkg|
data/lib/graph.rb CHANGED
@@ -1,38 +1,106 @@
1
1
  #!/usr/local/bin/ruby -w
2
2
 
3
+ ##
4
+ # Graph is a type of hash that outputs in graphviz's dot format.
5
+
3
6
  class Graph < Hash
4
- VERSION = '1.1.0'
7
+ VERSION = '1.2.0' # :nodoc:
8
+
9
+ ##
10
+ # A Hash of arrays of attributes for each node. Eg:
11
+ #
12
+ # graph.attribs["a"] << "color = red"
13
+ #
14
+ # Will color node "a" red.
5
15
 
6
16
  attr_reader :attribs
7
- attr_reader :prefix
17
+
18
+ ##
19
+ # An array of the order of traversal / definition of the nodes.
20
+ #
21
+ # You (generally) should leave this alone.
22
+
8
23
  attr_reader :order
9
- attr_reader :edge
10
24
 
11
- def initialize
12
- super { |h,k| h[k] = [] }
13
- @prefix = []
14
- @order = []
15
- @attribs = Hash.new { |h,k| h[k] = [] }
16
- @edge = Hash.new { |h,k| h[k] = Hash.new { |h2,k2| h2[k2] = [] } }
17
- end
25
+ ##
26
+ # An array of attributes to add to the front of the graph source. Eg:
27
+ #
28
+ # graph.prefix << "ratio = 1.5"
18
29
 
19
- def []= key, val
30
+ attr_reader :prefix
31
+
32
+ ##
33
+ # A Hash of a Hashes of Arrays of attributes for an edge. Eg:
34
+ #
35
+ # graph.edge["a"]["b"] << "color = blue"
36
+ #
37
+ # Will color the edge between a and b blue.
38
+
39
+ attr_reader :edge
40
+
41
+ def []= key, val # :nodoc:
20
42
  @order << key unless self.has_key? key
21
43
  super
22
44
  end
23
45
 
24
- def delete key
25
- @order.delete key
46
+ def clear # :nodoc:
26
47
  super
48
+ @prefix.clear
49
+ @order.clear
50
+ @attribs.clear
51
+ @edge.clear
27
52
  end
28
53
 
29
- def filter_size minimum
30
- counts.each do |node, count|
31
- next unless count < minimum
32
- delete node
54
+ ##
55
+ # Return all nodes (aka the set of all keys and values).
56
+
57
+ def nodes
58
+ (keys + values).flatten.uniq
59
+ end
60
+
61
+ ##
62
+ # A convenience method to set every node to be a box. Especially
63
+ # good for longer text nodes.
64
+
65
+ def boxes
66
+ prefix << "node [ shape = box ]"
67
+ end
68
+
69
+ ##
70
+ # A convenience method to set an attribute on all nodes.
71
+
72
+ def global_attrib attrib
73
+ nodes.each do |key|
74
+ attribs[key] << attrib
33
75
  end
34
76
  end
35
77
 
78
+ ##
79
+ # Returns a Hash with a count of the outgoing edges for each node.
80
+
81
+ def counts
82
+ result = Hash.new 0
83
+ each_pair do |from, to|
84
+ result[from] += 1
85
+ end
86
+ result
87
+ end
88
+
89
+ def delete key # :nodoc:
90
+ @order.delete key
91
+ # TODO: prolly needs to go clean up attribs
92
+ super
93
+ end
94
+
95
+ ##
96
+ # Overrides Hash#each_pair to go over each _edge_. Eg:
97
+ #
98
+ # g["a"] << "b"
99
+ # g["a"] << "b"
100
+ # g.each_pair { |from, to| ... }
101
+ #
102
+ # goes over a -> b *twice*.
103
+
36
104
  def each_pair
37
105
  @order.each do |from|
38
106
  self[from].each do |to|
@@ -41,6 +109,27 @@ class Graph < Hash
41
109
  end
42
110
  end
43
111
 
112
+ ##
113
+ # Deletes nodes that have less than minimum number of outgoing edges.
114
+
115
+ def filter_size minimum
116
+ counts.each do |node, count|
117
+ next unless count < minimum
118
+ delete node
119
+ end
120
+ end
121
+
122
+ def initialize # :nodoc:
123
+ super { |h,k| h[k] = [] }
124
+ @prefix = []
125
+ @order = []
126
+ @attribs = Hash.new { |h,k| h[k] = [] }
127
+ @edge = Hash.new { |h,k| h[k] = Hash.new { |h2,k2| h2[k2] = [] } }
128
+ end
129
+
130
+ ##
131
+ # Creates a new Graph whose edges point the other direction.
132
+
44
133
  def invert
45
134
  result = self.class.new
46
135
  each_pair do |from, to|
@@ -49,18 +138,50 @@ class Graph < Hash
49
138
  result
50
139
  end
51
140
 
52
- def counts
53
- result = Hash.new 0
54
- each_pair do |from, to|
55
- result[from] += 1
56
- end
57
- result
58
- end
141
+ ##
142
+ # Returns a list of keys sorted by number of outgoing edges.
59
143
 
60
144
  def keys_by_count
61
145
  counts.sort_by { |key, count| -count }.map {|key, count| key }
62
146
  end
63
147
 
148
+ ##
149
+ # Specify the orientation of the graph. Defaults to the graphviz default "TB".
150
+
151
+ def orient dir = "TB"
152
+ prefix << "rankdir = #{dir}"
153
+ end
154
+
155
+ ##
156
+ # Really just an alias for #orient but with "LR" as the default value.
157
+
158
+ def rotate dir = "LR"
159
+ orient dir
160
+ end
161
+
162
+ ##
163
+ # Remove all duplicate edges.
164
+
165
+ def normalize
166
+ each do |k,v|
167
+ v.uniq!
168
+ end
169
+ end
170
+
171
+ ##
172
+ # Saves out both a dot file to path and an image for the specified type.
173
+ # Specify type as nil to skip exporting an image.
174
+
175
+ def save path, type="png"
176
+ File.open "#{path}.dot", "w" do |f|
177
+ f.write self.to_s
178
+ end
179
+ system "dot -T#{type} #{path}.dot > #{path}.#{type}" if type
180
+ end
181
+
182
+ ##
183
+ # Outputs a graphviz graph.
184
+
64
185
  def to_s
65
186
  result = []
66
187
  result << "digraph absent"
@@ -83,11 +204,4 @@ class Graph < Hash
83
204
  result << " }"
84
205
  result.join "\n"
85
206
  end
86
-
87
- def save path, type="png"
88
- File.open "#{path}.dot", "w" do |f|
89
- f.write self.to_s
90
- end
91
- system "dot -T#{type} #{path}.dot > #{path}.#{type}" if type
92
- end
93
207
  end
@@ -16,6 +16,6 @@ class MacportsAnalyzer < DepAnalyzer
16
16
  def deps port
17
17
  cache("#{port}.deps") {
18
18
  `port deps #{port}`
19
- }.scan(/^\t(\S+)$/).flatten
19
+ }.scan(/Dependencies:\s*(.+)$/).join(', ').split(/, /)
20
20
  end
21
21
  end
@@ -0,0 +1,31 @@
1
+ require 'dep_analyzer'
2
+
3
+ class RakeAnalyzer < DepAnalyzer
4
+ def run
5
+ require 'graph'
6
+ g = Graph.new
7
+ g.rotate
8
+
9
+ current = nil
10
+ `rake -P -s`.each_line do |line|
11
+ case line
12
+ when /^rake (.+)/
13
+ name = $1
14
+ # current = (name =~ /pkg/) ? nil : name
15
+ current = name
16
+ g[current] if current # force the node to exist, in case of a leaf
17
+ when /^\s+(.+)/
18
+ dep = $1
19
+ next if current =~ /pkg/ and File.file? dep
20
+ g[current] << dep if current
21
+ else
22
+ warn "unparsed: #{line.chomp}"
23
+ end
24
+ end
25
+
26
+
27
+ g.boxes
28
+ g.save "#{self.class}"
29
+ system "open #{self.class}.png"
30
+ end
31
+ end
data/test/test_graph.rb CHANGED
@@ -1,15 +1,43 @@
1
- require "test/unit"
1
+ require "minitest/autorun"
2
2
  require "tmpdir"
3
3
  require "graph"
4
4
 
5
- class TestGraph < Test::Unit::TestCase
5
+ class TestGraph < MiniTest::Unit::TestCase
6
6
  def setup
7
7
  @graph = Graph.new
8
8
  @graph["a"] << "b"
9
9
  end
10
10
 
11
- def test_to_s_empty
12
- assert_equal util_dot, Graph.new.to_s
11
+ def test_boxes
12
+ expected = util_dot('"a" -> "b"')
13
+ assert_equal expected, @graph.to_s
14
+
15
+ @graph.boxes
16
+
17
+ expected = util_dot('node [ shape = box ]',
18
+ '"a" -> "b"')
19
+ assert_equal expected, @graph.to_s
20
+ end
21
+
22
+ def test_clear
23
+ @graph.clear
24
+
25
+ assert_empty @graph.prefix, "prefix"
26
+ assert_empty @graph.order, "order"
27
+ assert_empty @graph.attribs, "attribs"
28
+ assert_empty @graph.edge, "edge"
29
+ end
30
+
31
+ def test_counts
32
+ expect = { "a" => 1, }
33
+ assert_equal expect, @graph.counts
34
+
35
+ @graph["a"] << "b"
36
+ @graph["a"] << "c"
37
+ @graph["b"] << "c"
38
+
39
+ expect = { "a" => 3, "b" => 1, }
40
+ assert_equal expect, @graph.counts
13
41
  end
14
42
 
15
43
  def test_delete
@@ -22,6 +50,18 @@ class TestGraph < Test::Unit::TestCase
22
50
  assert @graph.empty?
23
51
  end
24
52
 
53
+ def test_global_attrib
54
+ expected = util_dot('"a" -> "b"')
55
+ assert_equal expected, @graph.to_s
56
+
57
+ @graph.global_attrib "color = blue"
58
+
59
+ expected = util_dot('"a" [ color = blue ]',
60
+ '"b" [ color = blue ]',
61
+ '"a" -> "b"')
62
+ assert_equal expected, @graph.to_s
63
+ end
64
+
25
65
  def test_invert
26
66
  @graph["a"] << "c"
27
67
  invert = @graph.invert
@@ -35,10 +75,52 @@ class TestGraph < Test::Unit::TestCase
35
75
  assert_equal %w(d a), @graph.keys_by_count
36
76
  end
37
77
 
78
+ def test_nodes
79
+ assert_equal %w(a), @graph.keys.sort
80
+ assert_equal %w(a b), @graph.nodes.sort
81
+ end
82
+
83
+ def test_normalize
84
+ @graph.clear
85
+ @graph["a"] << "b" << "b" << "b" # 3 edges from a to b
86
+
87
+ expect = { "a" => %w(b b b) }
88
+ assert_equal expect, @graph
89
+
90
+ @graph.normalize # clear all but one edge
91
+
92
+ expect = { "a" => %w(b) }
93
+ assert_equal expect, @graph
94
+ end
95
+
96
+ def test_orient
97
+ @graph.orient "blah"
98
+
99
+ assert_equal ["rankdir = blah"], @graph.prefix
100
+ end
101
+
102
+ def test_orient_default
103
+ @graph.orient
104
+
105
+ assert_equal ["rankdir = TB"], @graph.prefix
106
+ end
107
+
38
108
  def test_order
39
109
  assert_equal %w(a), @graph.order
40
110
  end
41
111
 
112
+ def test_rotate
113
+ @graph.rotate "blah"
114
+
115
+ assert_equal ["rankdir = blah"], @graph.prefix
116
+ end
117
+
118
+ def test_rotate_default
119
+ @graph.rotate
120
+
121
+ assert_equal ["rankdir = LR"], @graph.prefix
122
+ end
123
+
42
124
  def test_save
43
125
  util_save "png"
44
126
  end
@@ -57,19 +139,23 @@ class TestGraph < Test::Unit::TestCase
57
139
  assert_equal expected, @graph.to_s
58
140
  end
59
141
 
60
- def test_to_s_prefix
61
- @graph.prefix << "blah"
142
+ def test_to_s_attrib
143
+ @graph.attribs["a"] << "color = blue"
62
144
  @graph["a"] << "c"
63
145
 
64
- expected = util_dot('blah', '"a" -> "b"', '"a" -> "c"')
146
+ expected = util_dot('"a" [ color = blue ]', '"a" -> "b"', '"a" -> "c"')
65
147
  assert_equal expected, @graph.to_s
66
148
  end
67
149
 
68
- def test_to_s_attrib
69
- @graph.attribs["a"] << "color = blue"
150
+ def test_to_s_empty
151
+ assert_equal util_dot, Graph.new.to_s
152
+ end
153
+
154
+ def test_to_s_prefix
155
+ @graph.prefix << "blah"
70
156
  @graph["a"] << "c"
71
157
 
72
- expected = util_dot('"a" [ color = blue ]', '"a" -> "b"', '"a" -> "c"')
158
+ expected = util_dot('blah', '"a" -> "b"', '"a" -> "c"')
73
159
  assert_equal expected, @graph.to_s
74
160
  end
75
161
 
metadata CHANGED
@@ -1,48 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graph
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 2
8
+ - 0
9
+ version: 1.2.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Ryan Davis
8
13
  autorequire:
9
14
  bindir: bin
10
- cert_chain:
11
- - |
12
- -----BEGIN CERTIFICATE-----
13
- MIIDPjCCAiagAwIBAgIBADANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
14
- ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
15
- GRYDY29tMB4XDTA5MDMwNjE4NTMxNVoXDTEwMDMwNjE4NTMxNVowRTETMBEGA1UE
16
- AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
17
- JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
18
- b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
19
- taCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT
20
- oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh
21
- GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt
22
- qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
23
- gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
24
- HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
25
- AQAY59gYvDxqSqgC92nAP9P8dnGgfZgLxP237xS6XxFGJSghdz/nI6pusfCWKM8m
26
- vzjjH2wUMSSf3tNudQ3rCGLf2epkcU13/rguI88wO6MrE0wi4ZqLQX+eZQFskJb/
27
- w6x9W1ur8eR01s397LSMexySDBrJOh34cm2AlfKr/jokKCTwcM0OvVZnAutaovC0
28
- l1SVZ0ecg88bsWHA0Yhh7NFxK1utWoIhtB6AFC/+trM0FQEB/jZkIS8SaNzn96Rl
29
- n0sZEf77FLf5peR8TP/PtmIg7Cyqz23sLM4mCOoTGIy5OcZ8TdyiyINUHtb5ej/T
30
- FBHgymkyj/AOSqKRIpXPhjC6
31
- -----END CERTIFICATE-----
15
+ cert_chain: []
32
16
 
33
- date: 2009-04-16 00:00:00 -07:00
17
+ date: 2010-03-30 00:00:00 -07:00
34
18
  default_executable:
35
19
  dependencies:
36
20
  - !ruby/object:Gem::Dependency
37
- name: hoe
21
+ name: rubyforge
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 0
30
+ - 4
31
+ version: 2.0.4
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: minitest
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 6
44
+ - 0
45
+ version: 1.6.0
38
46
  type: :development
39
- version_requirement:
40
- version_requirements: !ruby/object:Gem::Requirement
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: hoe
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
41
52
  requirements:
42
53
  - - ">="
43
54
  - !ruby/object:Gem::Version
44
- version: 1.12.2
45
- version:
55
+ segments:
56
+ - 2
57
+ - 6
58
+ - 0
59
+ version: 2.6.0
60
+ type: :development
61
+ version_requirements: *id003
46
62
  description: |-
47
63
  Graph is a type of hash that outputs in graphviz's dot format. It
48
64
  comes with a command-line interface that is easily pluggable.
@@ -71,6 +87,7 @@ files:
71
87
  - lib/freebsd_analyzer.rb
72
88
  - lib/graph.rb
73
89
  - lib/macports_analyzer.rb
90
+ - lib/rake_analyzer.rb
74
91
  - lib/rubygems/commands/graph_command.rb
75
92
  - lib/rubygems_analyzer.rb
76
93
  - lib/rubygems_plugin.rb
@@ -89,18 +106,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
106
  requirements:
90
107
  - - ">="
91
108
  - !ruby/object:Gem::Version
109
+ segments:
110
+ - 0
92
111
  version: "0"
93
- version:
94
112
  required_rubygems_version: !ruby/object:Gem::Requirement
95
113
  requirements:
96
114
  - - ">="
97
115
  - !ruby/object:Gem::Version
116
+ segments:
117
+ - 0
98
118
  version: "0"
99
- version:
100
119
  requirements: []
101
120
 
102
121
  rubyforge_project: seattlerb
103
- rubygems_version: 1.3.2
122
+ rubygems_version: 1.3.6
104
123
  signing_key:
105
124
  specification_version: 3
106
125
  summary: Graph is a type of hash that outputs in graphviz's dot format
data.tar.gz.sig DELETED
@@ -1 +0,0 @@
1
- I�[‹ �"O����V��+o�!Q�d�fc"7�sj��_�Piu�_,��w��y�m���pO��!L��ެ���T��"Akv�Ӛ�v�v
metadata.gz.sig DELETED
Binary file