allenwei-railroad 0.7.8

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.
@@ -0,0 +1,19 @@
1
+ COPYING
2
+ ChangeLog
3
+ History.txt
4
+ Manifest.txt
5
+ README.txt
6
+ Rakefile
7
+ bin/railroad
8
+ init.rb
9
+ lib/railroad.rb
10
+ lib/railroad/aasm_diagram.rb
11
+ lib/railroad/app_diagram.rb
12
+ lib/railroad/controllers_diagram.rb
13
+ lib/railroad/diagram_graph.rb
14
+ lib/railroad/lifecycle_diagram.rb
15
+ lib/railroad/models_diagram.rb
16
+ lib/railroad/options_struct.rb
17
+ lib/railroad/tasks/diagrams.rake
18
+ lib/railroad/tasks/diagrams.rb
19
+ railroad.gemspec
@@ -0,0 +1,175 @@
1
+ = RailRoad
2
+
3
+ RailRoad generates models and controllers diagrams in DOT language for a
4
+ Rails application.
5
+
6
+
7
+ = Usage
8
+
9
+ Run RailRoad on the Rails application's root directory. You can redirect its
10
+ output to a .dot file or pipe it to the dot or neato utilities to produce a
11
+ graphic. Model diagrams are intended to be processed using dot and
12
+ controller diagrams are best processed using neato.
13
+
14
+ railroad [options] command
15
+
16
+ == Options
17
+
18
+ Common options:
19
+ -b, --brief Generate compact diagram
20
+ (no attributes nor methods)
21
+ -e, --exclude file1[,fileN] Exclude given files
22
+ -c, --class-map file1,MyClass1[,fileN,MyClassN]
23
+ Map files to classes they contain
24
+ -i, --inheritance Include inheritance relations
25
+ -l, --label Add a label with diagram information
26
+ (type, date, migration, version)
27
+ -o, --output FILE Write diagram to file FILE
28
+ -v, --verbose Enable verbose output
29
+ (produce messages to STDOUT)
30
+ -u, --yuml Produce yuml instead of DOT
31
+ (for http://yuml.me)
32
+
33
+
34
+ Models diagram options:
35
+ -a, --all Include all models
36
+ (not only ActiveRecord::Base derived)
37
+ --hide-magic Hide magic field names
38
+ --hide-types Hide attributes type
39
+ -j, --join Concentrate edges
40
+ -m, --modules Include modules
41
+ -p, --plugins-models Include plugins models
42
+ -y, --libraries Include application library
43
+ -t, --transitive Include transitive associations
44
+ (through inheritance)
45
+
46
+ Controllers diagram options:
47
+ --hide-public Hide public methods
48
+ --hide-protected Hide protected methods
49
+ --hide-private Hide private methods
50
+
51
+ Other options:
52
+ -h, --help Show this message
53
+ --version Show version and copyright
54
+
55
+ == Commands
56
+
57
+ -M, --models Generate models diagram
58
+ -C, --controllers Generate controllers diagram
59
+ -A, --aasm Generate "acts as state machine" diagram
60
+ -L, --lifecycle Generate Hobo::Lifecycle state machine diagram
61
+
62
+
63
+ == Examples
64
+
65
+ railroad -o models.dot -M
66
+ Produces a models diagram to the file 'models.dot'
67
+ railroad -a -i -o full_models.dot -M
68
+ Models diagram with all classes showing inheritance relations
69
+ railroad -M | dot -Tsvg > models.svg
70
+ Model diagram in SVG format
71
+ railroad -M -u
72
+ Print yuml format diagram, used by http://yuml.me
73
+ railroad -C | neato -Tpng > controllers.png
74
+ Controller diagram in PNG format
75
+ railroad -h
76
+ Shows usage help
77
+
78
+
79
+ = Processing DOT files
80
+
81
+ To produce a PNG image from model diagram generated by RailRoad you can
82
+ issue the following command:
83
+
84
+ dot -Tpng models.dot > models.png
85
+
86
+ If you want to do the same with a controller diagram, use neato instead of
87
+ dot:
88
+
89
+ neato -Tpng controllers.dot > controllers.png
90
+
91
+ If you want to produce SVG (vectorial, scalable, editable) files, you can do
92
+ the following:
93
+
94
+ dot -Tsvg models.dot > models.svg
95
+ neato -Tsvg controllers.dot > controllers.svg
96
+
97
+ Important: There is a bug in Graphviz tools when generating SVG files that
98
+ cause a text overflow. You can solve this problem editing (with a text
99
+ editor, not a graphical SVG editor) the file and replacing around line 12
100
+ "font-size:14.00;" by "font-size:11.00;", or by issuing the following command
101
+ (see "man sed"):
102
+
103
+ sed -i 's/font-size:14.00/font-size:11.00/g' file.svg
104
+ sed -i 's/font-size:14.00/font-size:11px/g' file.svg # alternative
105
+
106
+ Note: For viewing and editing SVG there is an excellent opensource tool
107
+ called Inkscape (similar to Adobe Illustrator. For DOT processing you can
108
+ also use Omnigraffle (on Mac OS X).
109
+
110
+ = validation_reflection
111
+
112
+ If you have the
113
+ [validation_reflection](http://github.com/redinger/validation_reflection/tree/master)
114
+ plugin installed, your model ERD diagrams will properly distinguish
115
+ between required and optional associations.
116
+
117
+ Required associations are those that contain a
118
+ *validates_presence_of*, *validates_existence_of*,
119
+ *validates_associated*, or *validates_length_of* validation.
120
+
121
+ = RailRoad as a rake task
122
+
123
+ This version of railroad also works as a plugin.
124
+
125
+ script/plugin install git://github.com/bryanlarsen/railroad.git
126
+
127
+ `rake doc:diagrams` produces 'doc/diagrams/models.svg',
128
+ 'doc/diagrams/controllers.svg', and 'doc/diagrams/states.svg' and
129
+ 'doc/diagrams/lifecycle.svg'
130
+
131
+ Update 'lib/railroad/tasks/diagrams.rake' to change the options for
132
+ your diagrams.
133
+
134
+ Running RailRoad as a rake task ensures that all of your plugins are
135
+ loaded correctly, and may work when railroad from the command line
136
+ fails.
137
+
138
+ These rake tasks are also available if you install railroad as a gem.
139
+ In that case, add to your top-level Rakefile:
140
+
141
+ require 'railroad/tasks/diagrams'
142
+
143
+ = Requirements
144
+
145
+ RailRoad has been tested with Ruby 1.8.5 and Rails 1.1.6 to 1.2.3
146
+ applications. There is no additional requirements (nevertheless, all your
147
+ Rails application requirements must be installed).
148
+
149
+ In order to view/export the DOT diagrams, you'll need the processing tools
150
+ from Graphviz.
151
+
152
+ = Website and Project Home
153
+
154
+ http://railroad.rubyforge.org
155
+
156
+ = License
157
+
158
+ RailRoad is distributed under the terms of the GNU General Public License
159
+ as published by the Free Software Foundation; either version 2 of the
160
+ License, or (at your option) any later version.
161
+
162
+ = Author
163
+
164
+ Javier Smaldone
165
+ (javier -at- smaldone -dot- com -dot- ar, http://blog.smaldone.com.ar )
166
+
167
+ == Contributors
168
+
169
+ Thomas Ritz http://www.galaxy-ritz.de
170
+ Tien Dung http://github.com/tiendung
171
+ Factory Design Labs http://github.com/factorylabs
172
+ Mike Mondragon http://github.com/monde
173
+ Tero Tilus http://github.com/terotil
174
+ Bruno Michel http://github.com/nono
175
+
@@ -0,0 +1,16 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
6
+ require './lib/railroad.rb'
7
+
8
+ Hoe.new('railroad', APP_VERSION.join('.')) do |p|
9
+ p.rubyforge_name = 'railroad'
10
+ p.author = "Javier Smaldone"
11
+ p.email = "javier@smaldone.com.ar"
12
+ p.url = "http://railroad.rubyforge.org"
13
+ p.summary = "A DOT diagram generator for Ruby on Rail applications"
14
+ end
15
+
16
+ # vim: syntax=Ruby
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # RailRoad - RoR diagrams generator
4
+ # http://railroad.rubyforge.org
5
+ #
6
+ # RailRoad generates models and controllers diagrams in DOT language
7
+ # for a Rails application.
8
+ #
9
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
10
+ #
11
+ # This program is free software; you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation; either version 2 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+
17
+ $: << File.join(File.dirname(__FILE__), '../lib/')
18
+ require 'railroad'
19
+
20
+ options = OptionsStruct.new
21
+
22
+ options.parse ARGV
23
+
24
+ old_dir = Dir.pwd
25
+
26
+ Dir.chdir(options.root) if options.root != ''
27
+
28
+ if options.command == 'models'
29
+ diagram = ModelsDiagram.new options
30
+ elsif options.command == 'controllers'
31
+ diagram = ControllersDiagram.new options
32
+ elsif options.command == 'aasm'
33
+ diagram = AasmDiagram.new options
34
+ elsif options.command == 'lifecycle'
35
+ diagram = LifecycleDiagram.new options
36
+ else
37
+ STDERR.print "Error: You must supply a command\n" +
38
+ " (try #{APP_NAME} -h)\n\n"
39
+ exit 1
40
+ end
41
+
42
+ diagram.generate
43
+
44
+ Dir.chdir(old_dir)
45
+
46
+ diagram.print
47
+
data/init.rb ADDED
File without changes
@@ -0,0 +1,12 @@
1
+ APP_NAME = "railroad"
2
+ APP_HUMAN_NAME = "RailRoad"
3
+ APP_VERSION = [0,7,7]
4
+ COPYRIGHT = "Copyright (C) 2007-2008 Javier Smaldone"
5
+
6
+ require 'railroad/options_struct'
7
+ require 'railroad/diagram_graph'
8
+ require 'railroad/app_diagram'
9
+ require 'railroad/models_diagram'
10
+ require 'railroad/controllers_diagram'
11
+ require 'railroad/aasm_diagram'
12
+ require 'railroad/lifecycle_diagram'
@@ -0,0 +1,110 @@
1
+ # RailRoad - RoR diagrams generator
2
+ # http://railroad.rubyforge.org
3
+ #
4
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
5
+ # See COPYING for more details
6
+
7
+ # AASM code provided by Ana Nelson (http://ananelson.com/)
8
+
9
+ # Diagram for Acts As State Machine
10
+ class AasmDiagram < AppDiagram
11
+
12
+ def initialize(options)
13
+ #options.exclude.map! {|e| e = "app/models/" + e}
14
+ super options
15
+ @graph.diagram_type = 'Models'
16
+ # Processed habtm associations
17
+ @habtm = []
18
+ end
19
+
20
+ # Process model files
21
+ def generate
22
+ STDERR.print "Generating AASM diagram\n" if @options.verbose
23
+ files = Dir.glob("app/models/*.rb")
24
+ files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
25
+ files -= @options.exclude
26
+ files.each do |f|
27
+ process_class extract_class_name('app/models/', f).constantize
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # Load model classes
34
+ def load_classes
35
+ begin
36
+ disable_stdout
37
+ files = Dir.glob("app/models/**/*.rb")
38
+ files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
39
+ files -= @options.exclude
40
+ files.each {|file| get_model_class(file) }
41
+ enable_stdout
42
+ rescue LoadError
43
+ enable_stdout
44
+ print_error "model classes"
45
+ raise
46
+ end
47
+ end # load_classes
48
+
49
+ # This method is taken from the annotate models gem
50
+ # http://github.com/ctran/annotate_models/tree/master
51
+ #
52
+ # Retrieve the classes belonging to the model names we're asked to process
53
+ # Check for namespaced models in subdirectories as well as models
54
+ # in subdirectories without namespacing.
55
+ def get_model_class(file)
56
+ model = file.sub(/^.*app\/models\//, '').sub(/\.rb$/, '').camelize
57
+ parts = model.split('::')
58
+ begin
59
+ parts.inject(Object) {|klass, part| klass.const_get(part) }
60
+ rescue LoadError
61
+ Object.const_get(parts.last)
62
+ end
63
+ end
64
+
65
+ # Process a model class
66
+ def process_class(current_class)
67
+
68
+ STDERR.print "\tProcessing #{current_class}\n" if @options.verbose
69
+
70
+ states = nil
71
+ if current_class.respond_to? 'states'
72
+ states = current_class.states
73
+ initial = current_class.initial_state
74
+ events = current_class.read_inheritable_attribute(:transition_table)
75
+ elsif current_class.respond_to? 'aasm_states'
76
+ states = current_class.aasm_states.map { |s| s.name }
77
+ initial = current_class.aasm_initial_state
78
+ events = current_class.aasm_events
79
+ end
80
+
81
+ # Only interested in acts_as_state_machine models.
82
+ return if states.nil? || states.empty?
83
+
84
+ node_attribs = []
85
+ node_type = 'aasm'
86
+
87
+ states.each do |state_name|
88
+ node_shape = (initial === state_name) ? ", peripheries = 2" : ""
89
+ node_attribs << "#{current_class.name.downcase}_#{state_name} [label=#{state_name} #{node_shape}];"
90
+ end
91
+ @graph.add_node [node_type, current_class.name, node_attribs]
92
+
93
+ events.each do |event_name, event|
94
+ if !event.respond_to?('each')
95
+ def event.each(&blk)
96
+ @transitions.each { |t| blk.call(t) }
97
+ end
98
+ end
99
+ event.each do |transition|
100
+ @graph.add_edge [
101
+ 'event',
102
+ current_class.name.downcase + "_" + transition.from.to_s,
103
+ current_class.name.downcase + "_" + transition.to.to_s,
104
+ event_name.to_s
105
+ ]
106
+ end
107
+ end
108
+ end # process_class
109
+
110
+ end # class AasmDiagram
@@ -0,0 +1,94 @@
1
+ # RailRoad - RoR diagrams generator
2
+ # http://railroad.rubyforge.org
3
+ #
4
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
5
+ # See COPYING for more details
6
+
7
+ # Root class for RailRoad diagrams
8
+ class AppDiagram
9
+
10
+ def initialize(options)
11
+ @options = options
12
+ @graph = DiagramGraph.new
13
+ @graph.show_label = @options.label
14
+
15
+ STDERR.print "Loading application environment\n" if @options.verbose
16
+ load_environment
17
+
18
+ STDERR.print "Loading application classes\n" if @options.verbose
19
+ load_classes
20
+ end
21
+
22
+ # Print diagram
23
+ def print
24
+ if @options.output
25
+ old_stdout = STDOUT.dup
26
+ begin
27
+ STDOUT.reopen(@options.output)
28
+ rescue
29
+ STDERR.print "Error: Cannot write diagram to #{@options.output}\n\n"
30
+ exit 2
31
+ end
32
+ end
33
+
34
+ STDOUT.print to_s
35
+
36
+ if @options.output
37
+ STDOUT.reopen(old_stdout)
38
+ end
39
+ end # print
40
+
41
+ def to_s
42
+ if @options.xmi
43
+ STDERR.print "Generating XMI diagram\n" if @options.verbose
44
+ @graph.to_xmi
45
+ elsif @options.yuml
46
+ STDERR.print "Generating yuml diagram\n" if @options.verbose
47
+ @graph.to_yuml
48
+ else
49
+ STDERR.print "Generating DOT graph\n" if @options.verbose
50
+ @graph.to_dot
51
+ end
52
+ end
53
+
54
+
55
+ private
56
+
57
+ # Prevents Rails application from writing to STDOUT
58
+ def disable_stdout
59
+ @old_stdout = STDOUT.dup
60
+ STDOUT.reopen(PLATFORM =~ /mswin/ ? "NUL" : "/dev/null")
61
+ end
62
+
63
+ # Restore STDOUT
64
+ def enable_stdout
65
+ STDOUT.reopen(@old_stdout)
66
+ end
67
+
68
+
69
+ # Print error when loading Rails application
70
+ def print_error(type)
71
+ STDERR.print "Error loading #{type}.\n (Are you running " +
72
+ "#{APP_NAME} on the aplication's root directory?)\n\n"
73
+ end
74
+
75
+ # Load Rails application's environment
76
+ def load_environment
77
+ begin
78
+ disable_stdout
79
+ require "config/environment"
80
+ enable_stdout
81
+ rescue LoadError
82
+ enable_stdout
83
+ print_error "application environment"
84
+ raise
85
+ end
86
+ end
87
+
88
+ # Extract class name from filename
89
+ def extract_class_name(base, filename)
90
+ # this is will handle directory names as namespace names
91
+ filename.reverse.chomp(base.reverse).reverse.chomp(".rb").camelize
92
+ end
93
+
94
+ end # class AppDiagram