railroad 0.4.1 → 0.5.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/ChangeLog CHANGED
@@ -1,5 +1,20 @@
1
+ Version 0.5.0 (may 10 2008)
2
+ - Changed model relationships representation (feature request #10898)
3
+ - Added support for plugins models (-p) (feature request #12742 by
4
+ Chris Richards). Thanks to Elliot Smith.
5
+ - Added support for irregular inflexions (from patch #12384). Thanks
6
+ to Juan Ignacio Pumarino.
7
+ - Added hidding of magic fields (--hide-magic) (from patch #13351)
8
+ Thanks to Hajime Baba.
9
+ - Added -r option to set the application root path (request #12801).
10
+ - The -e flag now requires full path to excluded files.
11
+ - Added support for state machine diagram ("acts as state machine" plugin).
12
+ Thanks to Ana Nelson (she did all the work!).
13
+
14
+
1
15
  Version 0.4.1 (may 9 2008)
2
- - Fix a bug (class name treated as String).
16
+ - Fix bug #17852 (class name treated as String).
17
+
3
18
 
4
19
  Version 0.4.0 (apr 25 2007)
5
20
  - Draw inheritance edges in reverse way
data/README CHANGED
@@ -18,9 +18,7 @@ controller diagrams are best processed using neato.
18
18
  Common options:
19
19
  -b, --brief Generate compact diagram
20
20
  (no attributes nor methods)
21
- -e, --exclude file1[,fileN] Exclude files
22
- (relative path to 'app/models/' or
23
- 'app/controllers/')
21
+ -e, --exclude file1[,fileN] Exclude given files
24
22
  -i, --inheritance Include inheritance relations
25
23
  -l, --label Add a label with diagram information
26
24
  (type, date, migration, version)
@@ -31,9 +29,11 @@ Common options:
31
29
  Models diagram options:
32
30
  -a, --all Include all models
33
31
  (not only ActiveRecord::Base derived)
32
+ --hide-magic Hide magic field names
34
33
  --hide-types Hide attributes type
35
34
  -j, --join Concentrate edges
36
35
  -m, --modules Include modules
36
+ -p, --plugins-models Include plugins models
37
37
  -t, --transitive Include transitive associations
38
38
  (through inheritance)
39
39
 
@@ -50,6 +50,7 @@ Other options:
50
50
 
51
51
  -M, --models Generate models diagram
52
52
  -C, --controllers Generate controllers diagram
53
+ -A, --aasm Generate "acts as state machine" diagram
53
54
 
54
55
 
55
56
  == Examples
@@ -6,7 +6,7 @@
6
6
  # RailRoad generates models and controllers diagrams in DOT language
7
7
  # for a Rails application.
8
8
  #
9
- # Copyright 2007 - Javier Smaldone (http://www.smaldone.com.ar)
9
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
10
10
  #
11
11
  # This program is free software; you can redistribute it and/or modify
12
12
  # it under the terms of the GNU General Public License as published by
@@ -16,21 +16,28 @@
16
16
 
17
17
  APP_NAME = "railroad"
18
18
  APP_HUMAN_NAME = "RailRoad"
19
- APP_VERSION = [0,4,1]
20
- COPYRIGHT = "Copyright (C) 2007 Javier Smaldone"
19
+ APP_VERSION = [0,5,0]
20
+ COPYRIGHT = "Copyright (C) 2007-2008 Javier Smaldone"
21
21
 
22
22
  require 'railroad/options_struct'
23
23
  require 'railroad/models_diagram'
24
24
  require 'railroad/controllers_diagram'
25
+ require 'railroad/aasm_diagram'
25
26
 
26
27
  options = OptionsStruct.new
27
28
 
28
29
  options.parse ARGV
29
30
 
31
+ old_dir = Dir.pwd
32
+
33
+ Dir.chdir(options.root) if options.root != ''
34
+
30
35
  if options.command == 'models'
31
36
  diagram = ModelsDiagram.new options
32
37
  elsif options.command == 'controllers'
33
38
  diagram = ControllersDiagram.new options
39
+ elsif options.command == 'aasm'
40
+ diagram = AasmDiagram.new options
34
41
  else
35
42
  STDERR.print "Error: You must supply a command\n" +
36
43
  " (try #{APP_NAME} -h)\n\n"
@@ -38,4 +45,8 @@ else
38
45
  end
39
46
 
40
47
  diagram.generate
48
+
49
+ Dir.chdir(old_dir)
50
+
41
51
  diagram.print
52
+
@@ -0,0 +1,81 @@
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
+ require 'railroad/app_diagram'
10
+
11
+ # Diagram for Acts As State Machine
12
+ class AasmDiagram < AppDiagram
13
+
14
+ def initialize(options)
15
+ #options.exclude.map! {|e| e = "app/models/" + e}
16
+ super options
17
+ @graph.diagram_type = 'Models'
18
+ # Processed habtm associations
19
+ @habtm = []
20
+ end
21
+
22
+ # Process model files
23
+ def generate
24
+ STDERR.print "Generating AASM diagram\n" if @options.verbose
25
+ files = Dir.glob("app/models/**/*.rb")
26
+ files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
27
+ files -= @options.exclude
28
+ files.each do |f|
29
+ process_class extract_class_name(f).constantize
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ # Load model classes
36
+ def load_classes
37
+ begin
38
+ disable_stdout
39
+ files = Dir.glob("app/models/**/*.rb")
40
+ files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
41
+ files -= @options.exclude
42
+ files.each {|m| require m }
43
+ enable_stdout
44
+ rescue LoadError
45
+ enable_stdout
46
+ print_error "model classes"
47
+ raise
48
+ end
49
+ end # load_classes
50
+
51
+ # Process a model class
52
+ def process_class(current_class)
53
+
54
+ STDERR.print "\tProcessing #{current_class}\n" if @options.verbose
55
+
56
+ # Only interested in acts_as_state_machine models.
57
+ return unless current_class.respond_to?'states'
58
+
59
+ node_attribs = []
60
+ node_type = 'aasm'
61
+
62
+ current_class.states.each do |state_name|
63
+ state = current_class.read_inheritable_attribute(:states)[state_name]
64
+ node_shape = (current_class.initial_state === state_name) ? ", peripheries = 2" : ""
65
+ node_attribs << "#{current_class.name.downcase}_#{state_name} [label=#{state_name} #{node_shape}];"
66
+ end
67
+ @graph.add_node [node_type, current_class.name, node_attribs]
68
+
69
+ current_class.read_inheritable_attribute(:transition_table).each do |event_name, event|
70
+ event.each do |transition|
71
+ @graph.add_edge [
72
+ 'event',
73
+ current_class.name.downcase + "_" + transition.from.to_s,
74
+ current_class.name.downcase + "_" + transition.to.to_s,
75
+ event_name.to_s
76
+ ]
77
+ end
78
+ end
79
+ end # process_class
80
+
81
+ end # class AasmDiagram
@@ -1,7 +1,7 @@
1
1
  # RailRoad - RoR diagrams generator
2
2
  # http://railroad.rubyforge.org
3
3
  #
4
- # Copyright 2007 - Javier Smaldone (http://www.smaldone.com.ar)
4
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
5
5
  # See COPYING for more details
6
6
 
7
7
  require 'railroad/diagram_graph'
@@ -81,7 +81,9 @@ class AppDiagram
81
81
 
82
82
  # Extract class name from filename
83
83
  def extract_class_name(filename)
84
- filename.split('/')[2..-1].join('/').split('.').first.camelize
84
+ #filename.split('/')[2..-1].join('/').split('.').first.camelize
85
+ # Fixed by patch from ticket #12742
86
+ File.basename(filename).chomp(".rb").camelize
85
87
  end
86
88
 
87
89
  end # class AppDiagram
@@ -1,7 +1,7 @@
1
1
  # RailRoad - RoR diagrams generator
2
2
  # http://railroad.rubyforge.org
3
3
  #
4
- # Copyright 2007 - Javier Smaldone (http://www.smaldone.com.ar)
4
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
5
5
  # See COPYING for more details
6
6
 
7
7
  require 'railroad/app_diagram'
@@ -10,7 +10,7 @@ require 'railroad/app_diagram'
10
10
  class ControllersDiagram < AppDiagram
11
11
 
12
12
  def initialize(options)
13
- options.exclude.map! {|e| "app/controllers/" + e}
13
+ #options.exclude.map! {|e| "app/controllers/" + e}
14
14
  super options
15
15
  @graph.diagram_type = 'Controllers'
16
16
  end
@@ -1,7 +1,7 @@
1
1
  # RailRoad - RoR diagrams generator
2
2
  # http://railroad.rubyforge.org
3
3
  #
4
- # Copyright 2007 - Javier Smaldone (http://www.smaldone.com.ar)
4
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
5
5
  # See COPYING for more details
6
6
 
7
7
 
@@ -97,6 +97,9 @@ class DiagramGraph
97
97
  options = ''
98
98
  when 'module'
99
99
  options = 'shape=box, style=dotted, label="' + name + '"'
100
+ when 'aasm'
101
+ # Return subgraph format
102
+ return "subgraph cluster_#{name.downcase} {\n\tlabel = #{quote(name)}\n\t#{attributes.join("\n ")}}"
100
103
  end # case
101
104
  return "\t#{quote(name)} [#{options}]\n"
102
105
  end # dot_node
@@ -106,13 +109,18 @@ class DiagramGraph
106
109
  options = name != '' ? "label=\"#{name}\", " : ''
107
110
  case type
108
111
  when 'one-one'
109
- options += 'taillabel="1"'
112
+ #options += 'taillabel="1"'
113
+ options += 'arrowtail=odot, arrowhead=dot, dir=both'
110
114
  when 'one-many'
111
- options += 'taillabel="n"'
115
+ #options += 'taillabel="n"'
116
+ options += 'arrowtail=crow, arrowhead=dot, dir=both'
112
117
  when 'many-many'
113
- options += 'taillabel="n", headlabel="n", arrowtail="normal"'
118
+ #options += 'taillabel="n", headlabel="n", arrowtail="normal"'
119
+ options += 'arrowtail=crow, arrowhead=crow, dir=both'
114
120
  when 'is-a'
115
121
  options += 'arrowhead="none", arrowtail="onormal"'
122
+ when 'event'
123
+ options += "fontsize=10"
116
124
  end
117
125
  return "\t#{quote(from)} -> #{quote(to)} [#{options}]\n"
118
126
  end # dot_edge
@@ -1,7 +1,7 @@
1
1
  # RailRoad - RoR diagrams generator
2
2
  # http://railroad.rubyforge.org
3
3
  #
4
- # Copyright 2007 - Javier Smaldone (http://www.smaldone.com.ar)
4
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
5
5
  # See COPYING for more details
6
6
 
7
7
  require 'railroad/app_diagram'
@@ -10,7 +10,7 @@ require 'railroad/app_diagram'
10
10
  class ModelsDiagram < AppDiagram
11
11
 
12
12
  def initialize(options)
13
- options.exclude.map! {|e| "app/models/" + e}
13
+ #options.exclude.map! {|e| "app/models/" + e}
14
14
  super options
15
15
  @graph.diagram_type = 'Models'
16
16
  # Processed habtm associations
@@ -20,7 +20,9 @@ class ModelsDiagram < AppDiagram
20
20
  # Process model files
21
21
  def generate
22
22
  STDERR.print "Generating models diagram\n" if @options.verbose
23
- files = Dir.glob("app/models/**/*.rb") - @options.exclude
23
+ files = Dir.glob("app/models/**/*.rb")
24
+ files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
25
+ files -= @options.exclude
24
26
  files.each do |f|
25
27
  process_class extract_class_name(f).constantize
26
28
  end
@@ -32,7 +34,9 @@ class ModelsDiagram < AppDiagram
32
34
  def load_classes
33
35
  begin
34
36
  disable_stdout
35
- files = Dir.glob("app/models/**/*.rb") - @options.exclude
37
+ files = Dir.glob("app/models/**/*.rb")
38
+ files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
39
+ files -= @options.exclude
36
40
  files.each {|m| require m }
37
41
  enable_stdout
38
42
  rescue LoadError
@@ -48,16 +52,36 @@ class ModelsDiagram < AppDiagram
48
52
  STDERR.print "\tProcessing #{current_class}\n" if @options.verbose
49
53
 
50
54
  generated = false
51
-
55
+
52
56
  # Is current_clas derived from ActiveRecord::Base?
53
57
  if current_class.respond_to?'reflect_on_all_associations'
58
+
59
+
54
60
  node_attribs = []
55
61
  if @options.brief || current_class.abstract_class?
56
62
  node_type = 'model-brief'
57
63
  else
58
64
  node_type = 'model'
65
+
59
66
  # Collect model's content columns
60
- current_class.content_columns.each do |a|
67
+
68
+ content_columns = current_class.content_columns
69
+
70
+ if @options.hide_magic
71
+ # From patch #13351
72
+ # http://wiki.rubyonrails.org/rails/pages/MagicFieldNames
73
+ magic_fields = [
74
+ "created_at", "created_on", "updated_at", "updated_on",
75
+ "lock_version", "type", "id", "position", "parent_id", "lft",
76
+ "rgt", "quote", "template"
77
+ ]
78
+ magic_fields << current_class.table_name + "_count" if current_class.respond_to? 'table_name'
79
+ content_columns = current_class.content_columns.select {|c| ! magic_fields.include? c.name}
80
+ else
81
+ content_columns = current_class.content_columns
82
+ end
83
+
84
+ content_columns.each do |a|
61
85
  content_column = a.name
62
86
  content_column += ' :' + a.type.to_s unless @options.hide_types
63
87
  node_attribs << content_column
@@ -104,7 +128,11 @@ class ModelsDiagram < AppDiagram
104
128
  return if assoc.macro.to_s == 'belongs_to'
105
129
 
106
130
  # Only non standard association names needs a label
107
- if assoc.class_name == assoc.name.to_s.singularize.camelize
131
+
132
+ # from patch #12384
133
+ # if assoc.class_name == assoc.name.to_s.singularize.camelize
134
+ assoc_class_name = (assoc.class_name.respond_to? 'underscore') ? assoc.class_name.underscore.singularize.camelize : assoc.class_name
135
+ if assoc_class_name == assoc.name.to_s.singularize.camelize
108
136
  assoc_name = ''
109
137
  else
110
138
  assoc_name = assoc.name.to_s
@@ -119,7 +147,9 @@ class ModelsDiagram < AppDiagram
119
147
  assoc_type = 'many-many'
120
148
  @habtm << [class_name, assoc.class_name, assoc_name]
121
149
  end
122
- @graph.add_edge [assoc_type, class_name, assoc.class_name, assoc_name]
150
+ # from patch #12384
151
+ # @graph.add_edge [assoc_type, class_name, assoc.class_name, assoc_name]
152
+ @graph.add_edge [assoc_type, class_name, assoc_class_name, assoc_name]
123
153
  end # process_association
124
154
 
125
155
  end # class ModelsDiagram
@@ -1,7 +1,7 @@
1
1
  # RailRoad - RoR diagrams generator
2
2
  # http://railroad.rubyforge.org
3
3
  #
4
- # Copyright 2007 - Javier Smaldone (http://www.smaldone.com.ar)
4
+ # Copyright 2007-2008 - Javier Smaldone (http://www.smaldone.com.ar)
5
5
  # See COPYING for more details
6
6
 
7
7
  require 'ostruct'
@@ -19,10 +19,13 @@ class OptionsStruct < OpenStruct
19
19
  :join => false,
20
20
  :label => false,
21
21
  :modules => false,
22
+ :hide_magic => false,
22
23
  :hide_types => false,
23
24
  :hide_public => false,
24
25
  :hide_protected => false,
25
26
  :hide_private => false,
27
+ :plugins_models => false,
28
+ :root => '',
26
29
  :transitive => false,
27
30
  :verbose => false,
28
31
  :xmi => false,
@@ -39,8 +42,7 @@ class OptionsStruct < OpenStruct
39
42
  " (no attributes nor methods)") do |b|
40
43
  self.brief = b
41
44
  end
42
- opts.on("-e", "--exclude file1[,fileN]", Array, "Exclude files",
43
- " (relative path to 'app/models/' or", " 'app/controllers/')") do |list|
45
+ opts.on("-e", "--exclude file1[,fileN]", Array, "Exclude given files") do |list|
44
46
  self.exclude = list
45
47
  end
46
48
  opts.on("-i", "--inheritance", "Include inheritance relations") do |i|
@@ -53,6 +55,9 @@ class OptionsStruct < OpenStruct
53
55
  opts.on("-o", "--output FILE", "Write diagram to file FILE") do |f|
54
56
  self.output = f
55
57
  end
58
+ opts.on("-r", "--root PATH", "Set PATH as the application root") do |r|
59
+ self.root = r
60
+ end
56
61
  opts.on("-v", "--verbose", "Enable verbose output",
57
62
  " (produce messages to STDOUT)") do |v|
58
63
  self.verbose = v
@@ -67,6 +72,9 @@ class OptionsStruct < OpenStruct
67
72
  " (not only ActiveRecord::Base derived)") do |a|
68
73
  self.all = a
69
74
  end
75
+ opts.on("--hide-magic", "Hide magic field names") do |h|
76
+ self.hide_magic = h
77
+ end
70
78
  opts.on("--hide-types", "Hide attributes type") do |h|
71
79
  self.hide_types = h
72
80
  end
@@ -76,6 +84,9 @@ class OptionsStruct < OpenStruct
76
84
  opts.on("-m", "--modules", "Include modules") do |m|
77
85
  self.modules = m
78
86
  end
87
+ opts.on("-p", "--plugins-models", "Include plugins models") do |p|
88
+ self.plugins_models = p
89
+ end
79
90
  opts.on("-t", "--transitive", "Include transitive associations",
80
91
  "(through inheritance)") do |t|
81
92
  self.transitive = t
@@ -106,26 +117,33 @@ class OptionsStruct < OpenStruct
106
117
  opts.separator ""
107
118
  opts.separator "Commands (you must supply one of these):"
108
119
  opts.on("-M", "--models", "Generate models diagram") do |c|
109
- if self.command == 'controllers'
110
- STDERR.print "Error: Can't generate models AND " +
111
- "controllers diagram\n\n"
120
+ if self.command != ''
121
+ STDERR.print "Error: Can only generate one diagram type\n\n"
112
122
  exit 1
113
123
  else
114
124
  self.command = 'models'
115
125
  end
116
126
  end
117
127
  opts.on("-C", "--controllers", "Generate controllers diagram") do |c|
118
- if self.command == 'models'
119
- STDERR.print "Error: Can't generate models AND " +
120
- "controllers diagram\n\n"
128
+ if self.command != ''
129
+ STDERR.print "Error: Can only generate one diagram type\n\n"
121
130
  exit 1
122
131
  else
123
132
  self.command = 'controllers'
124
133
  end
125
134
  end
135
+ # From Ana Nelson's patch
136
+ opts.on("-A", "--aasm", "Generate \"acts as state machine\" diagram") do |c|
137
+ if self.command == 'controllers'
138
+ STDERR.print "Error: Can only generate one diagram type\n\n"
139
+ exit 1
140
+ else
141
+ self.command = 'aasm'
142
+ end
143
+ end
126
144
  opts.separator ""
127
145
  opts.separator "For bug reporting and additional information, please see:"
128
- opts.separator "http://railroad.rubyforge.org"
146
+ opts.separator "http://railroad.rubyforge.org/"
129
147
  end # do
130
148
 
131
149
  begin
@@ -1,10 +1,11 @@
1
1
  require 'rubygems'
2
2
  SPEC = Gem::Specification.new do |s|
3
3
  s.name = "railroad"
4
- s.version = "0.4.1"
4
+ s.version = "0.5.0"
5
5
  s.author = "Javier Smaldone"
6
6
  s.email = "javier@smaldone.com.ar"
7
7
  s.homepage = "http://railroad.rubyforge.org"
8
+ s.rubyforge_project = "railroad"
8
9
  s.platform = Gem::Platform::RUBY
9
10
  s.summary = "A DOT diagram generator for Ruby on Rail applications"
10
11
  s.files = Dir.glob("lib/railroad/*.rb") +
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railroad
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Smaldone
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-09 00:00:00 -03:00
12
+ date: 2008-05-10 00:00:00 -03:00
13
13
  default_executable: railroad
14
14
  dependencies: []
15
15
 
@@ -23,6 +23,7 @@ extra_rdoc_files:
23
23
  - README
24
24
  - COPYING
25
25
  files:
26
+ - lib/railroad/aasm_diagram.rb
26
27
  - lib/railroad/models_diagram.rb
27
28
  - lib/railroad/app_diagram.rb
28
29
  - lib/railroad/controllers_diagram.rb
@@ -53,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
54
  version:
54
55
  requirements: []
55
56
 
56
- rubyforge_project:
57
+ rubyforge_project: railroad
57
58
  rubygems_version: 1.1.1
58
59
  signing_key:
59
60
  specification_version: 2