gratr 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/Grater.xcf +0 -0
  2. data/README +328 -0
  3. data/Rakefile +220 -0
  4. data/examples/graph_self.rb +54 -0
  5. data/examples/module_graph.jpg +0 -0
  6. data/examples/module_graph.rb +12 -0
  7. data/examples/self_graph.jpg +0 -0
  8. data/examples/visualize.jpg +0 -0
  9. data/examples/visualize.rb +8 -0
  10. data/install.rb +49 -0
  11. data/lib/gratr.rb +33 -0
  12. data/lib/gratr/adjacency_graph.rb +230 -0
  13. data/lib/gratr/base.rb +34 -0
  14. data/lib/gratr/biconnected.rb +116 -0
  15. data/lib/gratr/chinese_postman.rb +123 -0
  16. data/lib/gratr/common.rb +73 -0
  17. data/lib/gratr/comparability.rb +92 -0
  18. data/lib/gratr/digraph.rb +113 -0
  19. data/lib/gratr/digraph_distance.rb +185 -0
  20. data/lib/gratr/dot.rb +90 -0
  21. data/lib/gratr/edge.rb +145 -0
  22. data/lib/gratr/graph.rb +315 -0
  23. data/lib/gratr/graph_api.rb +82 -0
  24. data/lib/gratr/import.rb +44 -0
  25. data/lib/gratr/labels.rb +103 -0
  26. data/lib/gratr/maximum_flow.rb +107 -0
  27. data/lib/gratr/rdot.rb +326 -0
  28. data/lib/gratr/search.rb +409 -0
  29. data/lib/gratr/strong_components.rb +127 -0
  30. data/lib/gratr/undirected_graph.rb +153 -0
  31. data/tests/TestBiconnected.rb +53 -0
  32. data/tests/TestChinesePostman.rb +53 -0
  33. data/tests/TestComplement.rb +54 -0
  34. data/tests/TestDigraph.rb +333 -0
  35. data/tests/TestDigraphDistance.rb +138 -0
  36. data/tests/TestEdge.rb +171 -0
  37. data/tests/TestInspection.rb +57 -0
  38. data/tests/TestMultiEdge.rb +57 -0
  39. data/tests/TestNeighborhood.rb +64 -0
  40. data/tests/TestProperties.rb +160 -0
  41. data/tests/TestSearch.rb +257 -0
  42. data/tests/TestStrongComponents.rb +85 -0
  43. data/tests/TestTriagulated.rb +137 -0
  44. data/tests/TestUndirectedGraph.rb +219 -0
  45. metadata +92 -0
Binary file
data/README ADDED
@@ -0,0 +1,328 @@
1
+ = GRAph Theory in Ruby (GRATR)
2
+
3
+ link:../gratr.jpg GRATR is a framework for graph data structures and algorithms.
4
+
5
+ This project is a fork of Horst Duchene's RGL library.
6
+
7
+ The design of the library is much influenced by the Boost Graph Library (BGL)
8
+ which is written in C++ heavily using its template mechanism. Refer to
9
+ http://www.boost.org/libs/graph/doc for further links and documentation on graph
10
+ data structures and algorithms and the design rationales of BGL.
11
+
12
+ A comprehensive summary of graph terminology can be found in the the graph
13
+ section of the <em>Dictionary of Algorithms and Data Structures</em> at
14
+ http://www.nist.gov/dads/HTML/graph.html.
15
+
16
+ There are two Arc classes, GRATR::Arc and GRATR::Edge.
17
+
18
+ GRATR::Digraph and it's pseudonym GRATR::DirectedGraph are classes that have single directed edges
19
+ between vertices and loops are forbidden. GRATR::DirectedPseudoGraph allows for
20
+ multiple directed edges between vertices and loops are forbidden.
21
+ GRATR::DirectedMultiGraph allows for multiple directed edges between vertices and
22
+ loops on vertices.
23
+
24
+ GRATR::UndirectedGraph, GRATR::UndirectedPseudoGraph and GRATR::UndirectedMultiGraph are similar
25
+ but all edges are undirected.
26
+
27
+ These classes are all available with a <tt>require 'gratr'</tt> statement in your Ruby code. If one wishes
28
+ to pull the classes into the current namespace, i.e. drop the <tt>GRATR::</tt> from all
29
+ class statements and use <tt>require 'gratr/import'</tt> instead.
30
+
31
+ == Design principles
32
+
33
+ This document concentrates on the special issues of the implementation in
34
+ Ruby. The main design goals directly taken from the BGL design are:
35
+
36
+ * An interface for how the structure of a graph can be accessed using a generic
37
+ interface that hides the details of the graph data structure
38
+ implementation. This interface is defined by the module Graph, which should be
39
+ included in concrete classes.
40
+
41
+ * A standardized generic interface for traversing graphs using standard
42
+ Ruby block iterators.
43
+
44
+ * Implementation is separated from interface, and hidden from the average user.
45
+ An advanced user could also easily override the internals with a different
46
+ implementation if need be.
47
+
48
+ GRATR provides some general purpose graph classes that conform to this interface,
49
+ but they are not meant to be the *only* graph classes. As in BGL I believe that
50
+ the main contribution of the GRATR is the formulation of this interface.
51
+
52
+ The BGL graph interface and graph components are generic in the sense of the C++
53
+ Standard Template Library (STL). In Ruby other techniques are available to
54
+ express the generic character of the algorithms and data structures mainly using
55
+ mixins and iterators. The BGL documentation mentions three means to achieve
56
+ genericity:
57
+
58
+ * Algorithm/Data-Structure Interoperability
59
+ * Extension through Function Objects and Visitors
60
+ * Element Type Parameterization
61
+ * Vertex and Arc Property Multi-Parameterization
62
+
63
+ The first is easily achieved in GRATR using mixins, which of course is not as
64
+ efficient than C++ templates (but much more readable :-). The second one is
65
+ even more easily implemented using standard iterators with blocks.
66
+ The third one is no issue since Ruby is dynamically typed: Each object can
67
+ be a graph vertex (even nil!). There is no need for a vertex (or even edge type). A
68
+ label interface is provided for end users as well. One could simply use
69
+ a hash externally, but the future development of network graphs will require
70
+ a weight or capacity property to be accessible.
71
+
72
+ === Algorithms
73
+
74
+ This version of GRATR contains a core set of algorithm patterns:
75
+
76
+ * Breadth First Search Graph[1,2,1,3,1,4,2,5].bfs => [1, 2, 3, 4, 5]
77
+ * Depth First Search Graph[1,2,1,3,1,4,2,5].dfs => [1, 2, 5, 3, 4]
78
+ * A* Search
79
+ * Lexicographic Search
80
+ * Dijkstra's Algorithm
81
+ * Floyd-Warshall
82
+ * Triangulation and Comparability detection
83
+
84
+ The algorithm patterns by themselves do not compute any meaningful quantities
85
+ over graphs, they are merely building blocks for constructing graph
86
+ algorithms. The graph algorithms in GRATR currently include:
87
+
88
+ * Topological Sort (topsort)
89
+ * Strongly Connected Components (strong_connect)
90
+ * Transitive Closure (transitive_closure)
91
+
92
+ === Data Structures
93
+
94
+ GRATR currently provides one graph module that implement a generalized adjacency
95
+ list and an edge list adaptor.
96
+
97
+ * GRATR::AdjacencyGraph
98
+
99
+ The GRATR::Digraph class is the general purpose *swiss army knife* of graph
100
+ classes, most of the other classes are just modifications to this class.
101
+ It is optimized for efficient access to just the out-edges, fast vertex
102
+ insertion and removal at the cost of extra space overhead, etc.
103
+
104
+ === GEM Installation
105
+
106
+ Download the GEM file and install it with ..
107
+
108
+ % gem install gratr-VERSION.gem
109
+
110
+ or directly with
111
+
112
+ % gem install gratr
113
+
114
+ Use the correct version number for VERSION (e.g. 0.2.x). You may need root
115
+ privileges to install.
116
+
117
+ === Running tests
118
+
119
+ GRATR comes with a Rakefile which automatically runs the tests. Goto the
120
+ installation directory and start rake:
121
+
122
+ % gem env
123
+ Rubygems Environment:
124
+ - VERSION: 0.8.3 (0.8.3)
125
+ - INSTALLATION DIRECTORY: /usr/lib/ruby/gems/1.8
126
+ - GEM PATH:
127
+ - /usr/lib/ruby/gems/1.8
128
+ - REMOTE SOURCES:
129
+ - http://gems.rubyforge.org
130
+
131
+ % cd /usr/lib/ruby/gems/1.8/gems/gratr-0.2.2/
132
+ % r40> rake
133
+ (in /usr/lib/ruby/gems/1.8/gems/gratr-0.2.2)
134
+ ruby1.8 -Ilib:tests -e0 -rtests/TestGraphXML -rtests/TestComponents -rtests/TestDirectedGraph -rtests/TestArc -rtests/TestImplicit -rtests/TestTransitiveClosure -rtests/TestTraversal -rtests/TestUnDirectedGraph
135
+ Loaded suite -e
136
+ Started
137
+ ........................................................................................................
138
+ Finished in 0.736444 seconds.
139
+
140
+ 40 tests, 421 assertions, 0 failures, 0 errors
141
+
142
+ === Normal Installation
143
+
144
+ You have to install stream library before. You can than install GRATR with the
145
+ following command:
146
+
147
+ % ruby install.rb
148
+
149
+ from its distribution directory. To uninstall it use
150
+
151
+ % ruby install.rb -u
152
+
153
+ The rdoc is useful as well:
154
+
155
+ % rake rdoc
156
+
157
+ == Example irb session with GRATR
158
+
159
+ irb> require 'gratr/import'
160
+ => true
161
+ irb> dg = Digraph[1,2, 2,3, 2,4, 4,5, 6,4, 1,6]
162
+ => GRATR::Digraph[[2, 3], [1, 6], [2, 4], [4, 5], [1, 2], [6, 4]]
163
+
164
+ A few properties of the graph
165
+
166
+ irb> dg.directed?
167
+ => true
168
+ irb> dg.vertex?(4)
169
+ => true
170
+ irb> dg.edge?(2,4)
171
+ => true
172
+ irb> dg.edge?(4,2)
173
+ => false
174
+ irb> dg.vertices
175
+ => [5, 6, 1, 2, 3, 4]
176
+
177
+ Every object could be a vertex (there is no class Vertex), even the class
178
+ object _Object_:
179
+
180
+ irb> dg.vertex? Object
181
+ => false
182
+ irb> UndirectedGraph.new(dg).edges.sort.to_s
183
+ => "(1=2)(2=3)(2=4)(4=5)(1=6)(4=6)"
184
+
185
+ Add inverse edge (4-2) to directed graph:
186
+
187
+ irb> dg.add_edge! 4,2
188
+ => GRATR::Digraph[[2, 3], [1, 6], [4, 2], [2, 4], [4, 5], [1, 2], [6, 4]]
189
+
190
+ (4-2) == (2-4) in the undirected graph:
191
+
192
+ irb> UndirectedGraph.new(dg).edges.sort.to_s
193
+ => "(1=2)(2=3)(2=4)(4=5)(1=6)(4=6)"
194
+
195
+ (4-2) != (2-4) in directed graphs:
196
+
197
+ irb> dg.edges.sort.to_s
198
+ => "(1-2)(1-6)(2-3)(2-4)(4-2)(4-5)(6-4)"
199
+ irb> dg.remove_edge! 4,2
200
+ => GRATR::Digraph[[2, 3], [1, 6], [2, 4], [4, 5], [1, 2], [6, 4]]
201
+
202
+ <em>Topological sort</em> is realized with as iterator:
203
+
204
+ irb> dg.topsort
205
+ => [1, 2, 3, 6, 4, 5]
206
+ irb> y=0; dg.topsort {|v| y+=v}; y
207
+ => 21
208
+
209
+ # Use DOT to visualize this graph:
210
+ irb> require 'gratr/dot'
211
+ irb> dg.write_to_graphic_file('jpg','visualize')
212
+ "graph.jpg"
213
+
214
+ The result: link:../examples/visualize.jpg
215
+
216
+ Here's an example showing the module inheritance hierarchy:
217
+
218
+ module_graph=Digraph.new
219
+ ObjectSpace.each_object(Module) do |m|
220
+ m.ancestors.each {|a| module_graph.add_edge!(m,a) if m != a}
221
+ end
222
+
223
+ gv = module_graph.vertices.select {|v| v.to_s.match(/GRATR/)}
224
+ module_graph.induced_subgraph(gv).write_to_graphic_file('jpg','module_graph')
225
+
226
+ The result: link:../examples/module_graph.jpg
227
+
228
+ Look for more in the examples directory.
229
+
230
+ == Credits
231
+
232
+ Many thanks to Robert Feldt which also worked on a graph library
233
+ (http://rockit.sf.net/subprojects/graphr) who pointed me to BGL and many other
234
+ graph resources. Manuel Simoni found a subtle bug in a preliminary version
235
+ announced at http://rubygarden.com/ruby?RubyAlgorithmPackage/Graph.
236
+
237
+ Robert kindly allowed to integrate his work on graphr, which I did not yet
238
+ succeed. Especially his work to output graphs for
239
+ GraphViz[http://www.research.att.com/sw/tools/graphviz/download.html] is much
240
+ more elaborated than the minimal support in dot.rb.
241
+
242
+ Jeremy Siek one of the authors of the nice book "The Boost Graph Library (BGL)"
243
+ (http://www.boost.org/libs/graph/doc) kindly allowed to use the
244
+ BGL documentation as a _cheap_ reference for GRATR. He and Robert also gave
245
+ feedback and many ideas for GRATR.
246
+
247
+ Dave Thomas for RDoc[http://rdoc.sourceforge.net] which generated what you read
248
+ and Matz for Ruby. Dave included in the latest version of RDoc (alpha9) the
249
+ module dot/dot.rb which I use instead of Roberts module to visualize graphs
250
+ (see gratr/dot.rb).
251
+
252
+ Horst Duchene for RGL which provided the basis for this library and his vision.
253
+
254
+ Rick Bradley who reworked the library and added many graph theoretic constructs.
255
+
256
+ == Known Bugs
257
+
258
+ * Some of the digraph distance algorithms need reworked to work for pseudo and multi graphs.
259
+
260
+ == To Do
261
+
262
+ * Primal Dual for combinatorial optimization problems
263
+ * Min-Max Flow
264
+ * Near optimal traveling salesman problem
265
+ * Orientation of undirected graphs
266
+
267
+ == Release Notes
268
+
269
+ The core interface is about to be updated to allow for cleaner dependency injects. Luke Kanies has also contributed
270
+ several optimizations for speed and logged some bugs. This will result in a 0.5 release coming soon.
271
+
272
+ === 0.4.2
273
+
274
+ * Fixed bug in parallel edge adjacency detection.
275
+ * Fix to allow symbols to be passed through to dot for labels.
276
+ * Changed naming to use Arcs for Digraphs and Edges for Undirected Graphs.
277
+ * Added a gem release.
278
+
279
+ === 0.4.1
280
+
281
+ * Got reflection working for graphs
282
+ * Fixed major bugs in multi and pseudo graph handling
283
+
284
+ === 0.4.0
285
+
286
+ Initial release of fork from RGL library.
287
+
288
+ == Copying
289
+
290
+ Copyright (c) 2006 Shawn Patrick Garbett
291
+
292
+ Copyright (c) 2002,2004,2005 by Horst Duchene
293
+
294
+ Copyright (c) 2000,2001 Jeremy Siek, Indiana University (jsiek@osl.iu.edu)
295
+
296
+ All rights reserved.
297
+
298
+ Jeremy Siek was one of the principal developers of the Boost Graph library.
299
+ Since this work is derivative, his name is included in the copyright list.
300
+
301
+ Redistribution and use in source and binary forms, with or without modification,
302
+ are permitted provided that the following conditions are met:
303
+
304
+ * Redistributions of source code must retain the above copyright notice(s),
305
+ this list of conditions and the following disclaimer.
306
+ * Redistributions in binary form must reproduce the above copyright notice,
307
+ this list of conditions and the following disclaimer in the documentation
308
+ and/or other materials provided with the distribution.
309
+ * Neither the name of the Shawn Garbett nor the names of its contributors
310
+ may be used to endorse or promote products derived from this software
311
+ without specific prior written permission.
312
+
313
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
314
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
315
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
316
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
317
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
318
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
319
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
320
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
321
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
322
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
323
+
324
+ == Support
325
+
326
+ Please contact me at mailto:shawn@garbett.org with bug reports
327
+ suggestions, and other comments. If you send patches, it would help if
328
+ they were generated using "diff -u".
@@ -0,0 +1,220 @@
1
+ # Rakefile for GRATR -*- ruby -*-
2
+ begin
3
+ require 'rubygems'
4
+ require 'rake/gempackagetask'
5
+ rescue Exception
6
+ nil
7
+ end
8
+
9
+ require 'rake/clean'
10
+ require 'rake/testtask'
11
+ require 'rake/rdoctask'
12
+
13
+ # Determine the current version of the software
14
+
15
+ if `ruby -Ilib -rgratr/base -e'puts GRATR_VERSION'` =~ /\S+$/
16
+ PKG_VERSION = $&
17
+ else
18
+ PKG_VERSION = "0.0.0"
19
+ end
20
+
21
+ SUMMARY = "Graph Theory Ruby library"
22
+ SOURCES = FileList['lib/**/*.rb']
23
+ RDOC_DIR = './gratr'
24
+
25
+ # The default task is run if rake is given no explicit arguments.
26
+
27
+ desc "Default Task"
28
+ task :default => :test
29
+
30
+ # Define a test task.
31
+
32
+ Rake::TestTask.new { |t|
33
+ t.libs << "tests"
34
+ t.pattern = 'tests/Test*.rb'
35
+ t.verbose = true
36
+ }
37
+
38
+ task :test
39
+
40
+ # Define a test that will run all the test targets.
41
+ desc "Run all test targets"
42
+ task :testall => [:test ]
43
+
44
+ # Install gratr using the standard install.rb script.
45
+
46
+ desc "Install the application"
47
+ task :install do
48
+ ruby "install.rb"
49
+ end
50
+
51
+ # CVS Tasks ----------------------------------------------------------
52
+
53
+ desc "Tag all the CVS files with the latest release number (TAG=x)"
54
+ task :tag do
55
+ rel = "REL_" + PKG_VERSION.gsub(/\./, '_')
56
+ rel << ENV['TAG'] if ENV['TAG']
57
+ puts rel
58
+ sh %{cvs commit -m 'pre-tag commit'}
59
+ sh %{cvs tag #{rel}}
60
+ end
61
+
62
+ # Create a task to build the RDOC documentation tree.
63
+
64
+ rd = Rake::RDocTask.new("rdoc") { |rdoc|
65
+ rdoc.rdoc_dir = RDOC_DIR
66
+ rdoc.title = SUMMARY
67
+ rdoc.options << '--line-numbers' << '--inline-source' <<
68
+ '--main' << 'README'
69
+ rdoc.rdoc_files.include(SOURCES, 'README' ) #, 'examples/examples.rb')
70
+ }
71
+
72
+ # ====================================================================
73
+ # Create a task that will package the gratr software into distributable
74
+ # tar, zip and gem files.
75
+
76
+ PKG_FILES = FileList[
77
+ 'install.rb',
78
+ '[A-Z]*',
79
+ 'tests/**/*.rb',
80
+ 'examples/**/*'
81
+ ] + SOURCES
82
+
83
+ if ! defined?(Gem)
84
+ puts "Package Target requires RubyGEMs"
85
+ else
86
+ spec = Gem::Specification.new do |s|
87
+
88
+ #### Basic information.
89
+
90
+ s.name = 'gratr'
91
+ s.version = PKG_VERSION
92
+ s.summary = SUMMARY
93
+
94
+ s.description = <<-EOF
95
+ GRATR is a framework for graph data structures and algorithms.
96
+
97
+ This library is a fork of RGL. This version utilizes
98
+ Ruby blocks and duck typing to greatly simplfy the code. It also supports
99
+ export to DOT format for display as graphics.
100
+
101
+ GRATR currently contains a core set of algorithm patterns:
102
+
103
+ * Breadth First Search
104
+ * Depth First Search
105
+ * A* Search
106
+ * Floyd-Warshall
107
+ * Best First Search
108
+ * Djikstra's Algorithm
109
+ * Lexicographic Search
110
+
111
+ The algorithm patterns by themselves do not compute any meaningful quantities
112
+ over graphs, they are merely building blocks for constructing graph
113
+ algorithms. The graph algorithms in GRATR currently include:
114
+
115
+ * Topological Sort
116
+ * Strongly Connected Components
117
+ * Transitive Closure
118
+ * Rural Chinese Postman
119
+ * Biconnected
120
+ EOF
121
+
122
+ #### Which files are to be included in this gem? Everything! (Except CVS directories.)
123
+ s.files = PKG_FILES.to_a
124
+
125
+ #### Load-time details: library and application (you will need one or both).
126
+
127
+ s.require_path = 'lib' # Use these for libraries.
128
+ s.autorequire = 'gratr'
129
+
130
+ #### Documentation and testing.
131
+
132
+ s.has_rdoc = true
133
+ s.extra_rdoc_files = ['README']
134
+ s.rdoc_options <<
135
+ '--title' << 'GRATR - Ruby Graph Library' <<
136
+ '--main' << 'README' <<
137
+ '--line-numbers'
138
+
139
+ #### Author and project details.
140
+ s.author = "Shawn Garbett"
141
+ s.email = "shawn@garbett.org"
142
+ s.homepage = "http://gratr.rubyforge.org"
143
+ s.rubyforge_project = "gratr"
144
+
145
+ end
146
+
147
+ Rake::GemPackageTask.new(spec) do |pkg|
148
+ #pkg.need_zip = true
149
+ pkg.need_tar = true
150
+ end
151
+ end
152
+
153
+ # TAGS ---------------------------------------------------------------
154
+
155
+ file 'tags' => SOURCES do
156
+ print "Running ctags..."
157
+ sh %{ctags #{SOURCES.join(' ')}} # vi tags
158
+ puts "done."
159
+ end
160
+
161
+ file 'TAGS' => SOURCES do
162
+ sh %{ctags -e #{SOURCES.join(' ')}} # emacs TAGS
163
+ end
164
+
165
+ # Misc tasks =========================================================
166
+
167
+ def count_lines(filename)
168
+ lines = 0
169
+ codelines = 0
170
+ open(filename) { |f|
171
+ f.each do |line|
172
+ lines += 1
173
+ next if line =~ /^\s*$/
174
+ next if line =~ /^\s*#/
175
+ codelines += 1
176
+ end
177
+ }
178
+ [lines, codelines]
179
+ end
180
+
181
+ def show_line(msg, lines, loc)
182
+ printf "%6s %6s %s\n", lines.to_s, loc.to_s, msg
183
+ end
184
+
185
+ desc "Count lines in the main files"
186
+ task :lines do
187
+ total_lines = 0
188
+ total_code = 0
189
+ show_line("File Name", "LINES", "LOC")
190
+ SOURCES.each do |fn|
191
+ lines, codelines = count_lines(fn)
192
+ show_line(fn, lines, codelines)
193
+ total_lines += lines
194
+ total_code += codelines
195
+ end
196
+ show_line("TOTAL", total_lines, total_code)
197
+ end
198
+
199
+ ARCHIVEDIR = '/mnt/flash'
200
+
201
+ task :archive => [:package] do
202
+ cp FileList["pkg/*.tgz", "pkg/*.zip", "pkg/*.gem"], ARCHIVEDIR
203
+ end
204
+
205
+ desc "Copy rdoc html to rubyforge"
206
+ task :rdoc2rf => [:rdoc] do
207
+ sh "scp -r #{RDOC_DIR} monora@rubyforge.org:/var/www/gforge-projects/gratr"
208
+ sh "scp examples/*.jpg monora@rubyforge.org:/var/www/gforge-projects/gratr/examples"
209
+ end
210
+
211
+ STATS_DIRECTORIES = [
212
+ %w(Libraries lib/gratr),
213
+ %w(Unit\ tests tests),
214
+ ].collect { |name, dir| [ name, "./#{dir}" ] }.select { |name, dir| File.directory?(dir) }
215
+
216
+ desc "Report code statistics (KLOCs, etc) from the application"
217
+ task :stats do
218
+ require 'stats/code_statistics'
219
+ CodeStatistics.new(*STATS_DIRECTORIES).to_s
220
+ end