bryanlarsen-railroad 0.7.7

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/Manifest.txt ADDED
@@ -0,0 +1,18 @@
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/models_diagram.rb
15
+ lib/railroad/options_struct.rb
16
+ lib/railroad/tasks/diagrams.rake
17
+ lib/railroad/tasks/diagrams.rb
18
+ railroad.gemspec
data/README.txt ADDED
@@ -0,0 +1,152 @@
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
+
31
+ Models diagram options:
32
+ -a, --all Include all models
33
+ (not only ActiveRecord::Base derived)
34
+ --hide-magic Hide magic field names
35
+ --hide-types Hide attributes type
36
+ -j, --join Concentrate edges
37
+ -m, --modules Include modules
38
+ -p, --plugins-models Include plugins models
39
+ -y, --libraries Include application library
40
+ -t, --transitive Include transitive associations
41
+ (through inheritance)
42
+
43
+ Controllers diagram options:
44
+ --hide-public Hide public methods
45
+ --hide-protected Hide protected methods
46
+ --hide-private Hide private methods
47
+
48
+ Other options:
49
+ -h, --help Show this message
50
+ --version Show version and copyright
51
+
52
+ == Commands
53
+
54
+ -M, --models Generate models diagram
55
+ -C, --controllers Generate controllers diagram
56
+ -A, --aasm Generate "acts as state machine" diagram
57
+
58
+
59
+ == Examples
60
+
61
+ railroad -o models.dot -M
62
+ Produces a models diagram to the file 'models.dot'
63
+ railroad -a -i -o full_models.dot -M
64
+ Models diagram with all classes showing inheritance relations
65
+ railroad -M | dot -Tsvg > models.svg
66
+ Model diagram in SVG format
67
+ railroad -C | neato -Tpng > controllers.png
68
+ Controller diagram in PNG format
69
+ railroad -h
70
+ Shows usage help
71
+
72
+
73
+ = Processing DOT files
74
+
75
+ To produce a PNG image from model diagram generated by RailRoad you can
76
+ issue the following command:
77
+
78
+ dot -Tpng models.dot > models.png
79
+
80
+ If you want to do the same with a controller diagram, use neato instead of
81
+ dot:
82
+
83
+ neato -Tpng controllers.dot > controllers.png
84
+
85
+ If you want to produce SVG (vectorial, scalable, editable) files, you can do
86
+ the following:
87
+
88
+ dot -Tsvg models.dot > models.svg
89
+ neato -Tsvg controllers.dot > controllers.svg
90
+
91
+ Important: There is a bug in Graphviz tools when generating SVG files that
92
+ cause a text overflow. You can solve this problem editing (with a text
93
+ editor, not a graphical SVG editor) the file and replacing around line 12
94
+ "font-size:14.00;" by "font-size:11.00;", or by issuing the following command
95
+ (see "man sed"):
96
+
97
+ sed -i 's/font-size:14.00/font-size:11.00/g' file.svg
98
+ sed -i 's/font-size:14.00/font-size:11px/g' file.svg # alternative
99
+
100
+ Note: For viewing and editing SVG there is an excellent opensource tool
101
+ called Inkscape (similar to Adobe Illustrator. For DOT processing you can
102
+ also use Omnigraffle (on Mac OS X).
103
+
104
+ = RailRoad as a rake task
105
+
106
+ This version of railroad also works as a plugin.
107
+
108
+ script/plugin install git://github.com/bryanlarsen/railroad.git
109
+
110
+ `rake doc:diagrams` produces 'doc/diagrams/models.svg',
111
+ 'doc/diagrams/controllers.svg' and , 'doc/diagrams/states.svg'.
112
+
113
+ Update 'lib/railroad/tasks/diagrams.rake' to change the options for
114
+ your diagrams.
115
+
116
+ Running RailRoad as a rake task ensures that all of your plugins are
117
+ loaded correctly, and may work when railroad from the command line
118
+ fails.
119
+
120
+ = Requirements
121
+
122
+ RailRoad has been tested with Ruby 1.8.5 and Rails 1.1.6 to 1.2.3
123
+ applications. There is no additional requirements (nevertheless, all your
124
+ Rails application requirements must be installed).
125
+
126
+ In order to view/export the DOT diagrams, you'll need the processing tools
127
+ from Graphviz.
128
+
129
+ = Website and Project Home
130
+
131
+ http://railroad.rubyforge.org
132
+
133
+ = License
134
+
135
+ RailRoad is distributed under the terms of the GNU General Public License
136
+ as published by the Free Software Foundation; either version 2 of the
137
+ License, or (at your option) any later version.
138
+
139
+ = Author
140
+
141
+ Javier Smaldone
142
+ (javier -at- smaldone -dot- com -dot- ar, http://blog.smaldone.com.ar )
143
+
144
+ == Contributors
145
+
146
+ Thomas Ritz http://www.galaxy-ritz.de
147
+ Tien Dung http://github.com/tiendung
148
+ Factory Design Labs http://github.com/factorylabs
149
+ Mike Mondragon http://github.com/monde
150
+ Tero Tilus http://github.com/terotil
151
+ Bruno Michel http://github.com/nono
152
+
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/railroad.rb'
6
+
7
+ Hoe.new('railroad', APP_VERSION.join('.')) do |p|
8
+ p.rubyforge_name = 'railroad'
9
+ p.author = "Javier Smaldone"
10
+ p.email = "javier@smaldone.com.ar"
11
+ p.url = "http://railroad.rubyforge.org"
12
+ p.summary = "A DOT diagram generator for Ruby on Rail applications"
13
+ end
14
+
15
+ # vim: syntax=Ruby
data/bin/railroad ADDED
@@ -0,0 +1,45 @@
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
+ else
35
+ STDERR.print "Error: You must supply a command\n" +
36
+ " (try #{APP_NAME} -h)\n\n"
37
+ exit 1
38
+ end
39
+
40
+ diagram.generate
41
+
42
+ Dir.chdir(old_dir)
43
+
44
+ diagram.print
45
+
data/init.rb ADDED
File without changes
data/lib/railroad.rb ADDED
@@ -0,0 +1,11 @@
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'
@@ -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,91 @@
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
+ else
46
+ STDERR.print "Generating DOT graph\n" if @options.verbose
47
+ @graph.to_dot
48
+ end
49
+ end
50
+
51
+
52
+ private
53
+
54
+ # Prevents Rails application from writing to STDOUT
55
+ def disable_stdout
56
+ @old_stdout = STDOUT.dup
57
+ STDOUT.reopen(PLATFORM =~ /mswin/ ? "NUL" : "/dev/null")
58
+ end
59
+
60
+ # Restore STDOUT
61
+ def enable_stdout
62
+ STDOUT.reopen(@old_stdout)
63
+ end
64
+
65
+
66
+ # Print error when loading Rails application
67
+ def print_error(type)
68
+ STDERR.print "Error loading #{type}.\n (Are you running " +
69
+ "#{APP_NAME} on the aplication's root directory?)\n\n"
70
+ end
71
+
72
+ # Load Rails application's environment
73
+ def load_environment
74
+ begin
75
+ disable_stdout
76
+ require "config/environment"
77
+ enable_stdout
78
+ rescue LoadError
79
+ enable_stdout
80
+ print_error "application environment"
81
+ raise
82
+ end
83
+ end
84
+
85
+ # Extract class name from filename
86
+ def extract_class_name(base, filename)
87
+ # this is will handle directory names as namespace names
88
+ filename.reverse.chomp(base.reverse).reverse.chomp(".rb").camelize
89
+ end
90
+
91
+ end # class AppDiagram