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