graph 1.1.0 → 1.2.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/.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