railroady 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,36 +17,33 @@ class ModelsDiagram < AppDiagram
17
17
 
18
18
  # Process model files
19
19
  def generate
20
- STDERR.puts "Generating models diagram" if @options.verbose
20
+ STDERR.puts 'Generating models diagram' if @options.verbose
21
21
  get_files.each do |f|
22
22
  begin
23
23
  process_class extract_class_name(f).constantize
24
24
  rescue Exception
25
- STDERR.puts "Warning: exception #{$!} raised while trying to load model class #{f}"
25
+ STDERR.puts "Warning: exception #{$ERROR_INFO} raised while trying to load model class #{f}"
26
26
  end
27
-
28
27
  end
29
28
  end
30
29
 
31
- def get_files(prefix ='')
32
- files = !@options.specify.empty? ? Dir.glob(@options.specify) : Dir.glob(prefix + "app/models/**/*.rb")
33
- files += Dir.glob("vendor/plugins/**/app/models/*.rb") if @options.plugins_models
34
- files -= Dir.glob(prefix + "app/models/concerns/**/*.rb") unless @options.include_concerns
35
- files += get_engine_files if @options.engine_models
30
+ def get_files(prefix = '')
31
+ files = !@options.specify.empty? ? Dir.glob(@options.specify) : Dir.glob(prefix + 'app/models/**/*.rb')
32
+ files += Dir.glob('vendor/plugins/**/app/models/*.rb') if @options.plugins_models
33
+ files -= Dir.glob(prefix + 'app/models/concerns/**/*.rb') unless @options.include_concerns
34
+ files += engine_files if @options.engine_models
36
35
  files -= Dir.glob(@options.exclude)
37
36
  files
38
37
  end
39
38
 
40
- def get_engine_files
41
- engines.collect { |engine| Dir.glob("#{engine.root.to_s}/app/models/**/*.rb")}.flatten
39
+ def engine_files
40
+ engines.collect { |engine| Dir.glob("#{engine.root}/app/models/**/*.rb") }.flatten
42
41
  end
43
42
 
44
-
45
43
  def extract_class_name(filename)
46
- filename.split('/').last.camelize.chomp(".rb")
44
+ filename.match(/.*\/models\/(.*).rb$/)[1].camelize
47
45
  end
48
46
 
49
-
50
47
  # Process a model class
51
48
  def process_class(current_class)
52
49
  STDERR.puts "Processing #{current_class}" if @options.verbose
@@ -58,7 +55,7 @@ class ModelsDiagram < AppDiagram
58
55
  process_mongoid_model(current_class)
59
56
  elsif defined?(DataMapper::Resource) && current_class.new.is_a?(DataMapper::Resource)
60
57
  process_datamapper_model(current_class)
61
- elsif current_class.respond_to?'reflect_on_all_associations'
58
+ elsif current_class.respond_to? 'reflect_on_all_associations'
62
59
  process_active_record_model(current_class)
63
60
  elsif @options.all && (current_class.is_a? Class)
64
61
  process_basic_class(current_class)
@@ -69,14 +66,13 @@ class ModelsDiagram < AppDiagram
69
66
  if @options.inheritance && generated && include_inheritance?(current_class)
70
67
  @graph.add_edge ['is-a', current_class.superclass.name, current_class.name]
71
68
  end
72
-
73
69
  end # process_class
74
70
 
75
71
  def include_inheritance?(current_class)
76
72
  STDERR.puts current_class.superclass if @options.verbose
77
73
  (defined?(ActiveRecord::Base) && current_class.superclass != ActiveRecord::Base) ||
78
- (defined?(CouchRest::Model::Base) && current_class.superclass != CouchRest::Model::Base) ||
79
- (current_class.superclass != Object)
74
+ (defined?(CouchRest::Model::Base) && current_class.superclass != CouchRest::Model::Base) ||
75
+ (current_class.superclass != Object)
80
76
  end
81
77
 
82
78
  def process_basic_class(current_class)
@@ -98,18 +94,14 @@ class ModelsDiagram < AppDiagram
98
94
  node_type = 'model'
99
95
 
100
96
  # Collect model's content columns
101
- #content_columns = current_class.content_columns
97
+ # content_columns = current_class.content_columns
102
98
 
103
99
  if @options.hide_magic
104
100
  # From patch #13351
105
101
  # http://wiki.rubyonrails.org/rails/pages/MagicFieldNames
106
- magic_fields = [
107
- "created_at", "created_on", "updated_at", "updated_on",
108
- "lock_version", "type", "id", "position", "parent_id", "lft",
109
- "rgt", "quote", "template"
110
- ]
111
- magic_fields << current_class.table_name + "_count" if current_class.respond_to? 'table_name'
112
- content_columns = current_class.content_columns.select {|c| ! magic_fields.include? c.name}
102
+ magic_fields = %w(created_at created_on updated_at updated_on lock_version type id position parent_id lft rgt quote template)
103
+ magic_fields << current_class.table_name + '_count' if current_class.respond_to? 'table_name'
104
+ content_columns = current_class.content_columns.select { |c| !magic_fields.include? c.name }
113
105
  else
114
106
  content_columns = current_class.columns
115
107
  end
@@ -127,7 +119,7 @@ class ModelsDiagram < AppDiagram
127
119
  if @options.inheritance && ! @options.transitive
128
120
  superclass_associations = current_class.superclass.reflect_on_all_associations
129
121
 
130
- associations = associations.select{|a| ! superclass_associations.include? a}
122
+ associations = associations.select { |a| !superclass_associations.include? a }
131
123
  # This doesn't works!
132
124
  # associations -= current_class.superclass.reflect_on_all_associations
133
125
  end
@@ -141,7 +133,7 @@ class ModelsDiagram < AppDiagram
141
133
 
142
134
  def process_datamapper_model(current_class)
143
135
  node_attribs = []
144
- if @options.brief #|| current_class.abstract_class?
136
+ if @options.brief # || current_class.abstract_class?
145
137
  node_type = 'model-brief'
146
138
  else
147
139
  node_type = 'model'
@@ -153,9 +145,8 @@ class ModelsDiagram < AppDiagram
153
145
  # From patch #13351
154
146
  # http://wiki.rubyonrails.org/rails/pages/MagicFieldNames
155
147
  magic_fields =
156
- ["created_at", "created_on", "updated_at", "updated_on", "lock_version", "_type", "_id",
157
- "position", "parent_id", "lft", "rgt", "quote", "template"]
158
- props = props.select {|c| !magic_fields.include?(c.name.to_s) }
148
+ %w(created_at created_on updated_at updated_on lock_version _type _id position parent_id lft rgt quote template)
149
+ props = props.select { |c| !magic_fields.include?(c.name.to_s) }
159
150
  end
160
151
 
161
152
  props.each do |a|
@@ -192,12 +183,8 @@ class ModelsDiagram < AppDiagram
192
183
  if @options.hide_magic
193
184
  # From patch #13351
194
185
  # http://wiki.rubyonrails.org/rails/pages/MagicFieldNames
195
- magic_fields = [
196
- "created_at", "created_on", "updated_at", "updated_on",
197
- "lock_version", "_type", "_id", "position", "parent_id", "lft",
198
- "rgt", "quote", "template"
199
- ]
200
- content_columns = content_columns.select {|c| !magic_fields.include?(c.name) }
186
+ magic_fields = %w(created_at created_on updated_at updated_on lock_version _type _id position parent_id lft rgt quote template)
187
+ content_columns = content_columns.select { |c| !magic_fields.include?(c.name) }
201
188
  end
202
189
 
203
190
  content_columns.each do |a|
@@ -213,7 +200,7 @@ class ModelsDiagram < AppDiagram
213
200
  associations = current_class.relations.values
214
201
 
215
202
  if @options.inheritance && !@options.transitive &&
216
- current_class.superclass.respond_to?(:relations)
203
+ current_class.superclass.respond_to?(:relations)
217
204
  associations -= current_class.superclass.relations.values
218
205
  end
219
206
 
@@ -242,11 +229,8 @@ class ModelsDiagram < AppDiagram
242
229
  content_columns = current_class.properties
243
230
 
244
231
  if @options.hide_magic
245
- magic_fields = [
246
- "created_at", "updated_at",
247
- "type", "_id", "_rev"
248
- ]
249
- content_columns = content_columns.select {|c| !magic_fields.include?(c.name) }
232
+ magic_fields = %w(created_at updated_at type _id _rev)
233
+ content_columns = content_columns.select { |c| !magic_fields.include?(c.name) }
250
234
  end
251
235
 
252
236
  content_columns.each do |a|
@@ -263,17 +247,17 @@ class ModelsDiagram < AppDiagram
263
247
 
264
248
  # Process a model association
265
249
  def process_association(class_name, assoc)
266
- STDERR.puts "- Processing model association #{assoc.name.to_s}" if @options.verbose
250
+ STDERR.puts "- Processing model association #{assoc.name}" if @options.verbose
267
251
 
268
252
  # Skip "belongs_to" associations
269
253
  macro = assoc.macro.to_s
270
- return if %w[belongs_to referenced_in].include?(macro) && !@options.show_belongs_to
254
+ return if %w(belongs_to referenced_in).include?(macro) && !@options.show_belongs_to
271
255
 
272
256
  # Skip "through" associations
273
257
  through = assoc.options.include?(:through)
274
258
  return if through && @options.hide_through
275
259
 
276
- #TODO:
260
+ # TODO:
277
261
  # FAIL: assoc.methods.include?(:class_name)
278
262
  # FAIL: assoc.responds_to?(:class_name)
279
263
  assoc_class_name = assoc.class_name rescue nil
@@ -290,15 +274,15 @@ class ModelsDiagram < AppDiagram
290
274
  end
291
275
 
292
276
  # Patch from "alpack" to support classes in a non-root module namespace. See: http://disq.us/yxl1v
293
- if class_name.include?("::") && !assoc_class_name.include?("::")
294
- assoc_class_name = class_name.split("::")[0..-2].push(assoc_class_name).join("::")
277
+ if class_name.include?('::') && !assoc_class_name.include?('::')
278
+ assoc_class_name = class_name.split('::')[0..-2].push(assoc_class_name).join('::')
295
279
  end
296
- assoc_class_name.gsub!(%r{^::}, '')
280
+ assoc_class_name.gsub!(/^::/, '')
297
281
 
298
- if %w[has_one references_one embeds_one].include?(macro)
282
+ if %w(has_one references_one embeds_one).include?(macro)
299
283
  assoc_type = 'one-one'
300
284
  elsif macro == 'has_many' && (!assoc.options[:through]) ||
301
- %w[references_many embeds_many].include?(macro)
285
+ %w(references_many embeds_many).include?(macro)
302
286
  assoc_type = 'one-many'
303
287
  else # habtm or has_many, :through
304
288
  # Add FAKE associations too in order to understand mistakes
@@ -313,7 +297,7 @@ class ModelsDiagram < AppDiagram
313
297
 
314
298
  # Process a DataMapper relationship
315
299
  def process_datamapper_relationship(class_name, relation)
316
- STDERR.puts "- Processing DataMapper model relationship #{relation.name.to_s}" if @options.verbose
300
+ STDERR.puts "- Processing DataMapper model relationship #{relation.name}" if @options.verbose
317
301
 
318
302
  # Skip "belongs_to" relationships
319
303
  dm_type = relation.class.to_s.split('::')[-2]
@@ -332,7 +316,7 @@ class ModelsDiagram < AppDiagram
332
316
 
333
317
  # Only non standard association names needs a label
334
318
  assoc_name = ''
335
- if !(relation.name.to_s.singularize.camelize.eql?(assoc_class_name.split('::').last))
319
+ unless relation.name.to_s.singularize.camelize.eql?(assoc_class_name.split('::').last)
336
320
  assoc_name = relation.name.to_s
337
321
  end
338
322
 
@@ -344,9 +328,6 @@ class ModelsDiagram < AppDiagram
344
328
  rel_type = 'one-many'
345
329
  end
346
330
 
347
- @graph.add_edge [rel_type, class_name, assoc_class_name, assoc_name ]
331
+ @graph.add_edge [rel_type, class_name, assoc_class_name, assoc_name]
348
332
  end
349
-
350
333
  end # class ModelsDiagram
351
-
352
-
@@ -8,201 +8,197 @@ require 'ostruct'
8
8
 
9
9
  # RailRoady command line options parser
10
10
  class OptionsStruct < OpenStruct
11
-
12
11
  require 'optparse'
13
12
 
14
- def initialize(args={})
15
- init_options = { :all => false,
16
- :brief => false,
17
- :specify => [],
18
- :exclude => [],
19
- :inheritance => false,
20
- :join => false,
21
- :label => false,
22
- :modules => false,
23
- :all_columns => false,
24
- :hide_magic => false,
25
- :hide_types => false,
26
- :hide_public => false,
27
- :hide_protected => false,
28
- :hide_private => false,
29
- :plugins_models => false,
30
- :engine_models => false,
31
- :engine_controllers => false,
32
- :include_concerns => false,
33
- :root => '',
34
- :show_belongs_to => false,
35
- :hide_through => false,
36
- :transitive => false,
37
- :verbose => false,
38
- :alphabetize => false,
39
- :xmi => false,
40
- :command => '',
41
- :config_file => 'config/environment',
42
- :app_name => 'railroady', :app_human_name => 'Railroady', :app_version =>'', :copyright =>'' }
13
+ def initialize(args = {})
14
+ init_options = { all: false,
15
+ brief: false,
16
+ specify: [],
17
+ exclude: [],
18
+ inheritance: false,
19
+ join: false,
20
+ label: false,
21
+ modules: false,
22
+ all_columns: false,
23
+ hide_magic: false,
24
+ hide_types: false,
25
+ hide_public: false,
26
+ hide_protected: false,
27
+ hide_private: false,
28
+ plugins_models: false,
29
+ engine_models: false,
30
+ engine_controllers: false,
31
+ include_concerns: false,
32
+ root: '',
33
+ show_belongs_to: false,
34
+ hide_through: false,
35
+ transitive: false,
36
+ verbose: false,
37
+ alphabetize: false,
38
+ xmi: false,
39
+ command: '',
40
+ config_file: 'config/environment',
41
+ app_name: 'railroady', app_human_name: 'Railroady', app_version: '', copyright: '' }
43
42
  super(init_options.merge(args))
44
43
  end # initialize
45
44
 
46
45
  def parse(args)
47
46
  @opt_parser = OptionParser.new do |opts|
48
- opts.banner = "Usage: #{self.app_name} [options] command"
49
- opts.separator ""
50
- opts.separator "Common options:"
51
- opts.on("-b", "--brief", "Generate compact diagram",
52
- " (no attributes nor methods)") do |b|
47
+ opts.banner = "Usage: #{app_name} [options] command"
48
+ opts.separator ''
49
+ opts.separator 'Common options:'
50
+ opts.on('-b', '--brief', 'Generate compact diagram',
51
+ ' (no attributes nor methods)') do |b|
53
52
  self.brief = b
54
53
  end
55
- opts.on("-s", "--specify file1[,fileN]", Array, "Specify only given files") do |list|
54
+ opts.on('-s', '--specify file1[,fileN]', Array, 'Specify only given files') do |list|
56
55
  self.specify = list
57
56
  end
58
- opts.on("-e", "--exclude file1[,fileN]", Array, "Exclude given files") do |list|
57
+ opts.on('-e', '--exclude file1[,fileN]', Array, 'Exclude given files') do |list|
59
58
  self.exclude = list
60
59
  end
61
- opts.on("-i", "--inheritance", "Include inheritance relations") do |i|
60
+ opts.on('-i', '--inheritance', 'Include inheritance relations') do |i|
62
61
  self.inheritance = i
63
62
  end
64
- opts.on("-l", "--label", "Add a label with diagram information",
65
- " (type, date, migration, version)") do |l|
63
+ opts.on('-l', '--label', 'Add a label with diagram information',
64
+ ' (type, date, migration, version)') do |l|
66
65
  self.label = l
67
66
  end
68
- opts.on("-o", "--output FILE", "Write diagram to file FILE") do |f|
67
+ opts.on('-o', '--output FILE', 'Write diagram to file FILE') do |f|
69
68
  self.output = f
70
69
  end
71
- opts.on("-r", "--root PATH", "Set PATH as the application root") do |r|
70
+ opts.on('-r', '--root PATH', 'Set PATH as the application root') do |r|
72
71
  self.root = r
73
72
  end
74
- opts.on("-v", "--verbose", "Enable verbose output",
75
- " (produce messages to STDOUT)") do |v|
73
+ opts.on('-v', '--verbose', 'Enable verbose output',
74
+ ' (produce messages to STDOUT)') do |v|
76
75
  self.verbose = v
77
76
  end
78
- opts.on("-x", "--xmi", "Produce XMI instead of DOT",
79
- " (for UML tools)") do |x|
77
+ opts.on('-x', '--xmi', 'Produce XMI instead of DOT',
78
+ ' (for UML tools)') do |x|
80
79
  self.xmi = x
81
80
  end
82
- opts.on("--alphabetize", "Sort methods alphabetically") do |a|
81
+ opts.on('--alphabetize', 'Sort methods alphabetically') do |a|
83
82
  self.alphabetize = a
84
83
  end
85
- opts.separator ""
86
- opts.separator "Models diagram options:"
87
- opts.on("-a", "--all", "Include all models",
88
- " (not only ActiveRecord::Base derived)") do |a|
84
+ opts.separator ''
85
+ opts.separator 'Models diagram options:'
86
+ opts.on('-a', '--all', 'Include all models',
87
+ ' (not only ActiveRecord::Base derived)') do |a|
89
88
  self.all = a
90
89
  end
91
- opts.on("--show-belongs_to", "Show belongs_to associations") do |s|
90
+ opts.on('--show-belongs_to', 'Show belongs_to associations') do |s|
92
91
  self.show_belongs_to = s
93
92
  end
94
- opts.on("--hide-through", "Hide through associations") do |h|
93
+ opts.on('--hide-through', 'Hide through associations') do |h|
95
94
  self.hide_through = h
96
95
  end
97
- opts.on("--all-columns", "Show all columns (not just content columns)") do |h|
96
+ opts.on('--all-columns', 'Show all columns (not just content columns)') do |h|
98
97
  self.all_columns = h
99
98
  end
100
- opts.on("--hide-magic", "Hide magic field names") do |h|
99
+ opts.on('--hide-magic', 'Hide magic field names') do |h|
101
100
  self.hide_magic = h
102
101
  end
103
- opts.on("--hide-types", "Hide attributes type") do |h|
102
+ opts.on('--hide-types', 'Hide attributes type') do |h|
104
103
  self.hide_types = h
105
104
  end
106
- opts.on("-j", "--join", "Concentrate edges") do |j|
105
+ opts.on('-j', '--join', 'Concentrate edges') do |j|
107
106
  self.join = j
108
107
  end
109
- opts.on("-m", "--modules", "Include modules") do |m|
108
+ opts.on('-m', '--modules', 'Include modules') do |m|
110
109
  self.modules = m
111
110
  end
112
- opts.on("-p", "--plugins-models", "Include plugins models") do |p|
111
+ opts.on('-p', '--plugins-models', 'Include plugins models') do |p|
113
112
  self.plugins_models = p
114
113
  end
115
- opts.on("-z", "--engine-models", "Include engine models") do |em|
114
+ opts.on('-z', '--engine-models', 'Include engine models') do |em|
116
115
  self.engine_models = em
117
116
  end
118
- opts.on("--include-concerns", "Include models in concerns subdirectory") do |c|
117
+ opts.on('--include-concerns', 'Include models in concerns subdirectory') do |c|
119
118
  self.include_concerns = c
120
119
  end
121
- opts.on("-t", "--transitive", "Include transitive associations",
122
- "(through inheritance)") do |t|
120
+ opts.on('-t', '--transitive', 'Include transitive associations',
121
+ '(through inheritance)') do |t|
123
122
  self.transitive = t
124
123
  end
125
- opts.separator ""
126
- opts.separator "Controllers diagram options:"
127
- opts.on("--hide-public", "Hide public methods") do |h|
124
+ opts.separator ''
125
+ opts.separator 'Controllers diagram options:'
126
+ opts.on('--hide-public', 'Hide public methods') do |h|
128
127
  self.hide_public = h
129
128
  end
130
- opts.on("--hide-protected", "Hide protected methods") do |h|
129
+ opts.on('--hide-protected', 'Hide protected methods') do |h|
131
130
  self.hide_protected = h
132
131
  end
133
- opts.on("--hide-private", "Hide private methods") do |h|
132
+ opts.on('--hide-private', 'Hide private methods') do |h|
134
133
  self.hide_private = h
135
134
  end
136
- opts.on("--engine-controllers", "Include engine controllers") do |ec|
135
+ opts.on('--engine-controllers', 'Include engine controllers') do |ec|
137
136
  self.engine_controllers = ec
138
137
  end
139
- opts.separator ""
140
- opts.separator "Other options:"
141
- opts.on("-h", "--help", "Show this message") do
138
+ opts.separator ''
139
+ opts.separator 'Other options:'
140
+ opts.on('-h', '--help', 'Show this message') do
142
141
  STDOUT.print "#{opts}\n"
143
142
  exit
144
143
  end
145
- opts.on("--version", "Show version and copyright") do
146
- STDOUT.print"#{self.app_human_name} version #{self.app_version}\n\n" +
147
- "#{self.copyright}\nThis is free software; see the source " +
144
+ opts.on('--version', 'Show version and copyright') do
145
+ STDOUT.print "#{app_human_name} version #{app_version}\n\n" \
146
+ "#{copyright}\nThis is free software; see the source " \
148
147
  "for copying conditions.\n\n"
149
148
  exit
150
149
  end
151
- opts.separator ""
152
- opts.on("-c", "--config FILE", "File to load environment (defaults to config/environment)") do |c|
153
- if c && c != ''
154
- self.config_file = c
155
- end
150
+ opts.separator ''
151
+ opts.on('-c', '--config FILE', 'File to load environment (defaults to config/environment)') do |c|
152
+ self.config_file = c if c && c != ''
156
153
  end
157
- opts.separator "Commands (you must supply one of these):"
158
- opts.on("-M", "--models", "Generate models diagram") do |c|
159
- if self.command != ''
154
+ opts.separator 'Commands (you must supply one of these):'
155
+ opts.on('-M', '--models', 'Generate models diagram') do |_c|
156
+ if command != ''
160
157
  STDERR.print "Error: Can only generate one diagram type\n\n"
161
158
  exit 1
162
- else
163
- self.command = 'models'
159
+ else
160
+ self.command = 'models'
164
161
  end
165
- end
166
- opts.on("-C", "--controllers", "Generate controllers diagram") do |c|
167
- if self.command != ''
162
+ end
163
+ opts.on('-C', '--controllers', 'Generate controllers diagram') do |_c|
164
+ if command != ''
168
165
  STDERR.print "Error: Can only generate one diagram type\n\n"
169
166
  exit 1
170
- else
171
- self.command = 'controllers'
167
+ else
168
+ self.command = 'controllers'
172
169
  end
173
170
  end
174
171
  # From Ana Nelson's patch
175
- opts.on("-A", "--aasm", "Generate \"acts as state machine\" diagram") do |c|
176
- if self.command == 'controllers'
172
+ opts.on('-A', '--aasm', "Generate \"acts as state machine\" diagram") do |_c|
173
+ if command == 'controllers'
177
174
  STDERR.print "Error: Can only generate one diagram type\n\n"
178
175
  exit 1
179
- else
176
+ else
180
177
  self.command = 'aasm'
181
178
  end
182
- end
183
- opts.separator ""
184
- opts.separator "For bug reporting and additional information, please see:"
185
- opts.separator "http://railroad.rubyforge.org/"
179
+ end
180
+ opts.separator ''
181
+ opts.separator 'For bug reporting and additional information, please see:'
182
+ opts.separator 'http://railroad.rubyforge.org/'
186
183
  end # do
187
184
 
188
185
  begin
189
186
  @opt_parser.parse!(args)
190
187
  rescue OptionParser::AmbiguousOption
191
- option_error "Ambiguous option"
188
+ option_error 'Ambiguous option'
192
189
  rescue OptionParser::InvalidOption
193
- option_error "Invalid option"
190
+ option_error 'Invalid option'
194
191
  rescue OptionParser::InvalidArgument
195
- option_error "Invalid argument"
192
+ option_error 'Invalid argument'
196
193
  rescue OptionParser::MissingArgument
197
- option_error "Missing argument"
194
+ option_error 'Missing argument'
198
195
  end
199
196
  end # parse
200
197
 
201
- private
198
+ private
202
199
 
203
200
  def option_error(msg)
204
201
  STDERR.print "Error: #{msg}\n\n #{@opt_parser}\n"
205
202
  exit 1
206
203
  end
207
-
208
204
  end # class OptionsStruct