annotate 2.7.5 → 3.2.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 +4 -4
- data/{AUTHORS.rdoc → AUTHORS.md} +2 -2
- data/CHANGELOG.md +326 -0
- data/{README.rdoc → README.md} +154 -100
- data/RELEASE.md +19 -0
- data/annotate.gemspec +11 -27
- data/bin/annotate +7 -191
- data/lib/annotate/annotate_models/file_patterns.rb +127 -0
- data/lib/annotate/annotate_models.rb +183 -188
- data/lib/annotate/annotate_routes/header_generator.rb +113 -0
- data/lib/annotate/annotate_routes/helpers.rb +69 -0
- data/lib/annotate/annotate_routes.rb +69 -200
- data/lib/annotate/constants.rb +38 -0
- data/lib/annotate/helpers.rb +30 -0
- data/lib/annotate/parser.rb +303 -0
- data/lib/annotate/version.rb +1 -1
- data/lib/annotate.rb +23 -82
- data/lib/generators/annotate/templates/auto_annotate_models.rake +45 -41
- data/lib/tasks/annotate_models.rake +37 -35
- data/lib/tasks/annotate_models_migrate.rake +17 -4
- data/lib/tasks/annotate_routes.rake +12 -6
- data/potato.md +41 -0
- metadata +25 -17
- data/CHANGELOG.rdoc +0 -220
- data/TODO.rdoc +0 -11
data/bin/annotate
CHANGED
@@ -14,203 +14,19 @@ end
|
|
14
14
|
here = File.expand_path(File.dirname __FILE__)
|
15
15
|
$LOAD_PATH << "#{here}/../lib"
|
16
16
|
|
17
|
-
require 'optparse'
|
18
17
|
require 'annotate'
|
19
|
-
|
20
|
-
|
21
|
-
has_set_position = {}
|
22
|
-
target_action = :do_annotations
|
23
|
-
positions = %w(before top after bottom)
|
24
|
-
|
25
|
-
OptionParser.new do |opts|
|
26
|
-
opts.banner = 'Usage: annotate [options] [model_file]*'
|
27
|
-
|
28
|
-
opts.on('-d', '--delete', 'Remove annotations from all model files or the routes.rb file') do
|
29
|
-
target_action = :remove_annotations
|
30
|
-
end
|
31
|
-
|
32
|
-
opts.on('-p', '--position [before|top|after|bottom]', positions,
|
33
|
-
'Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/route/serializer file(s)') do |p|
|
34
|
-
ENV['position'] = p
|
35
|
-
%w(position_in_class position_in_factory position_in_fixture position_in_test position_in_routes position_in_serializer).each do |key|
|
36
|
-
ENV[key] = p unless has_set_position[key]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
opts.on('--pc', '--position-in-class [before|top|after|bottom]', positions,
|
41
|
-
'Place the annotations at the top (before) or the bottom (after) of the model file') do |p|
|
42
|
-
ENV['position_in_class'] = p
|
43
|
-
has_set_position['position_in_class'] = true
|
44
|
-
end
|
45
|
-
|
46
|
-
opts.on('--pf', '--position-in-factory [before|top|after|bottom]', positions,
|
47
|
-
'Place the annotations at the top (before) or the bottom (after) of any factory files') do |p|
|
48
|
-
ENV['position_in_factory'] = p
|
49
|
-
has_set_position['position_in_factory'] = true
|
50
|
-
end
|
51
|
-
|
52
|
-
opts.on('--px', '--position-in-fixture [before|top|after|bottom]', positions,
|
53
|
-
'Place the annotations at the top (before) or the bottom (after) of any fixture files') do |p|
|
54
|
-
ENV['position_in_fixture'] = p
|
55
|
-
has_set_position['position_in_fixture'] = true
|
56
|
-
end
|
57
|
-
|
58
|
-
opts.on('--pt', '--position-in-test [before|top|after|bottom]', positions,
|
59
|
-
'Place the annotations at the top (before) or the bottom (after) of any test files') do |p|
|
60
|
-
ENV['position_in_test'] = p
|
61
|
-
has_set_position['position_in_test'] = true
|
62
|
-
end
|
63
|
-
|
64
|
-
opts.on('--pr', '--position-in-routes [before|top|after|bottom]', positions,
|
65
|
-
'Place the annotations at the top (before) or the bottom (after) of the routes.rb file') do |p|
|
66
|
-
ENV['position_in_routes'] = p
|
67
|
-
has_set_position['position_in_routes'] = true
|
68
|
-
end
|
69
|
-
|
70
|
-
opts.on('--ps', '--position-in-serializer [before|top|after|bottom]', positions,
|
71
|
-
'Place the annotations at the top (before) or the bottom (after) of the serializer files') do |p|
|
72
|
-
ENV['position_in_serializer'] = p
|
73
|
-
has_set_position['position_in_serializer'] = true
|
74
|
-
end
|
75
|
-
|
76
|
-
opts.on('--w', '--wrapper STR', 'Wrap annotation with the text passed as parameter.',
|
77
|
-
'If --w option is used, the same text will be used as opening and closing') do |p|
|
78
|
-
ENV['wrapper'] = p
|
79
|
-
end
|
80
|
-
|
81
|
-
opts.on('--wo', '--wrapper-open STR', 'Annotation wrapper opening.') do |p|
|
82
|
-
ENV['wrapper_open'] = p
|
83
|
-
end
|
84
|
-
|
85
|
-
opts.on('--wc', '--wrapper-close STR', 'Annotation wrapper closing') do |p|
|
86
|
-
ENV['wrapper_close'] = p
|
87
|
-
end
|
88
|
-
|
89
|
-
opts.on('-r', '--routes', "Annotate routes.rb with the output of 'rake routes'") do
|
90
|
-
ENV['routes'] = 'true'
|
91
|
-
end
|
92
|
-
|
93
|
-
opts.on('-a', '--active-admin', 'Annotate active_admin models') do
|
94
|
-
ENV['active_admin'] = 'true'
|
95
|
-
end
|
96
|
-
|
97
|
-
opts.on('-v', '--version', 'Show the current version of this gem') do
|
98
|
-
puts "annotate v#{Annotate.version}"; exit
|
99
|
-
end
|
100
|
-
|
101
|
-
opts.on('-m', '--show-migration', 'Include the migration version number in the annotation') do
|
102
|
-
ENV['include_version'] = 'yes'
|
103
|
-
end
|
104
|
-
|
105
|
-
opts.on('-k', '--show-foreign-keys',
|
106
|
-
"List the table's foreign key constraints in the annotation") do
|
107
|
-
ENV['show_foreign_keys'] = 'yes'
|
108
|
-
end
|
18
|
+
require 'annotate/parser'
|
109
19
|
|
110
|
-
|
111
|
-
'--complete-foreign-keys', 'Complete foreign key names in the annotation') do
|
112
|
-
ENV['show_foreign_keys'] = 'yes'
|
113
|
-
ENV['show_complete_foreign_keys'] = 'yes'
|
114
|
-
end
|
115
|
-
|
116
|
-
opts.on('-i', '--show-indexes',
|
117
|
-
"List the table's database indexes in the annotation") do
|
118
|
-
ENV['show_indexes'] = 'yes'
|
119
|
-
end
|
120
|
-
|
121
|
-
opts.on('-s', '--simple-indexes',
|
122
|
-
"Concat the column's related indexes in the annotation") do
|
123
|
-
ENV['simple_indexes'] = 'yes'
|
124
|
-
end
|
125
|
-
|
126
|
-
opts.on('--model-dir dir',
|
127
|
-
"Annotate model files stored in dir rather than app/models, separate multiple dirs with commas") do |dir|
|
128
|
-
ENV['model_dir'] = dir
|
129
|
-
end
|
130
|
-
|
131
|
-
opts.on('--root-dir dir',
|
132
|
-
"Annotate files stored within root dir projects, separate multiple dirs with commas") do |dir|
|
133
|
-
ENV['root_dir'] = dir
|
134
|
-
end
|
135
|
-
|
136
|
-
opts.on('--ignore-model-subdirects',
|
137
|
-
"Ignore subdirectories of the models directory") do |dir|
|
138
|
-
ENV['ignore_model_sub_dir'] = 'yes'
|
139
|
-
end
|
140
|
-
|
141
|
-
opts.on('--sort',
|
142
|
-
"Sort columns alphabetically, rather than in creation order") do |dir|
|
143
|
-
ENV['sort'] = 'yes'
|
144
|
-
end
|
145
|
-
|
146
|
-
opts.on('--classified-sort',
|
147
|
-
"Sort columns alphabetically, but first goes id, then the rest columns, then the timestamp columns and then the association columns") do |dir|
|
148
|
-
ENV['classified_sort'] = 'yes'
|
149
|
-
end
|
150
|
-
|
151
|
-
opts.on('-R', '--require path',
|
152
|
-
"Additional file to require before loading models, may be used multiple times") do |path|
|
153
|
-
if !ENV['require'].blank?
|
154
|
-
ENV['require'] = ENV['require'] + ",#{path}"
|
155
|
-
else
|
156
|
-
ENV['require'] = path
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
opts.on('-e', '--exclude [tests,fixtures,factories,serializers]', Array, "Do not annotate fixtures, test files, factories, and/or serializers") do |exclusions|
|
161
|
-
exclusions ||= %w(tests fixtures factories)
|
162
|
-
exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = 'yes' }
|
163
|
-
end
|
164
|
-
|
165
|
-
opts.on('-f', '--format [bare|rdoc|markdown]', %w(bare rdoc markdown), 'Render Schema Infomation as plain/RDoc/Markdown') do |fmt|
|
166
|
-
ENV["format_#{fmt}"] = 'yes'
|
167
|
-
end
|
168
|
-
|
169
|
-
opts.on('--force', 'Force new annotations even if there are no changes.') do |force|
|
170
|
-
ENV['force'] = 'yes'
|
171
|
-
end
|
172
|
-
|
173
|
-
opts.on('--frozen', 'Do not allow to change annotations. Exits non-zero if there are going to be changes to files.') do
|
174
|
-
ENV['frozen'] = 'yes'
|
175
|
-
end
|
176
|
-
|
177
|
-
opts.on('--timestamp', 'Include timestamp in (routes) annotation') do
|
178
|
-
ENV['timestamp'] = 'true'
|
179
|
-
end
|
180
|
-
|
181
|
-
opts.on('--trace', 'If unable to annotate a file, print the full stack trace, not just the exception message.') do |value|
|
182
|
-
ENV['trace'] = 'yes'
|
183
|
-
end
|
184
|
-
|
185
|
-
opts.on('-I', '--ignore-columns REGEX', "don't annotate columns that match a given REGEX (i.e., `annotate -I '^(id|updated_at|created_at)'`") do |regex|
|
186
|
-
ENV['ignore_columns'] = regex
|
187
|
-
end
|
188
|
-
|
189
|
-
opts.on('--ignore-routes REGEX', "don't annotate routes that match a given REGEX (i.e., `annotate -I '(mobile|resque|pghero)'`") do |regex|
|
190
|
-
ENV['ignore_routes'] = regex
|
191
|
-
end
|
192
|
-
|
193
|
-
opts.on('--hide-limit-column-types VALUES', "don't show limit for given column types, separated by commas (i.e., `integer,boolean,text`)") do |values|
|
194
|
-
ENV['hide_limit_column_types'] = "#{values}"
|
195
|
-
end
|
196
|
-
|
197
|
-
opts.on('--hide-default-column-types VALUES', "don't show default for given column types, separated by commas (i.e., `json,jsonb,hstore`)") do |values|
|
198
|
-
ENV['hide_default_column_types'] = "#{values}"
|
199
|
-
end
|
20
|
+
Annotate.bootstrap_rake
|
200
21
|
|
201
|
-
|
202
|
-
ENV['ignore_unknown_models'] = 'true'
|
203
|
-
end
|
22
|
+
options_result = Annotate::Parser.parse(ARGV)
|
204
23
|
|
205
|
-
|
206
|
-
ENV['with_comment'] = 'true'
|
207
|
-
end
|
208
|
-
end.parse!
|
24
|
+
exit if options_result[:exit]
|
209
25
|
|
210
26
|
options = Annotate.setup_options(
|
211
27
|
is_rake: ENV['is_rake'] && !ENV['is_rake'].empty?
|
212
28
|
)
|
213
|
-
Annotate.eager_load(options) if Annotate.include_models?
|
29
|
+
Annotate.eager_load(options) if Annotate::Helpers.include_models?
|
214
30
|
|
215
|
-
AnnotateModels.send(target_action, options) if Annotate.include_models?
|
216
|
-
AnnotateRoutes.send(target_action, options) if Annotate.include_routes?
|
31
|
+
AnnotateModels.send(options_result[:target_action], options) if Annotate::Helpers.include_models?
|
32
|
+
AnnotateRoutes.send(options_result[:target_action], options) if Annotate::Helpers.include_routes?
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module AnnotateModels
|
2
|
+
# This module provides module method to get file paths.
|
3
|
+
module FilePatterns
|
4
|
+
# Controller files
|
5
|
+
CONTROLLER_DIR = File.join('app', 'controllers')
|
6
|
+
|
7
|
+
# Active admin registry files
|
8
|
+
ACTIVEADMIN_DIR = File.join('app', 'admin')
|
9
|
+
|
10
|
+
# Helper files
|
11
|
+
HELPER_DIR = File.join('app', 'helpers')
|
12
|
+
|
13
|
+
# File.join for windows reverse bar compat?
|
14
|
+
# I dont use windows, can`t test
|
15
|
+
UNIT_TEST_DIR = File.join('test', 'unit')
|
16
|
+
MODEL_TEST_DIR = File.join('test', 'models') # since rails 4.0
|
17
|
+
SPEC_MODEL_DIR = File.join('spec', 'models')
|
18
|
+
|
19
|
+
FIXTURE_TEST_DIR = File.join('test', 'fixtures')
|
20
|
+
FIXTURE_SPEC_DIR = File.join('spec', 'fixtures')
|
21
|
+
|
22
|
+
# Other test files
|
23
|
+
CONTROLLER_TEST_DIR = File.join('test', 'controllers')
|
24
|
+
CONTROLLER_SPEC_DIR = File.join('spec', 'controllers')
|
25
|
+
REQUEST_SPEC_DIR = File.join('spec', 'requests')
|
26
|
+
ROUTING_SPEC_DIR = File.join('spec', 'routing')
|
27
|
+
|
28
|
+
# Object Daddy http://github.com/flogic/object_daddy/tree/master
|
29
|
+
EXEMPLARS_TEST_DIR = File.join('test', 'exemplars')
|
30
|
+
EXEMPLARS_SPEC_DIR = File.join('spec', 'exemplars')
|
31
|
+
|
32
|
+
# Machinist http://github.com/notahat/machinist
|
33
|
+
BLUEPRINTS_TEST_DIR = File.join('test', 'blueprints')
|
34
|
+
BLUEPRINTS_SPEC_DIR = File.join('spec', 'blueprints')
|
35
|
+
|
36
|
+
# Factory Bot https://github.com/thoughtbot/factory_bot
|
37
|
+
FACTORY_BOT_TEST_DIR = File.join('test', 'factories')
|
38
|
+
FACTORY_BOT_SPEC_DIR = File.join('spec', 'factories')
|
39
|
+
|
40
|
+
# Fabrication https://github.com/paulelliott/fabrication.git
|
41
|
+
FABRICATORS_TEST_DIR = File.join('test', 'fabricators')
|
42
|
+
FABRICATORS_SPEC_DIR = File.join('spec', 'fabricators')
|
43
|
+
|
44
|
+
# Serializers https://github.com/rails-api/active_model_serializers
|
45
|
+
SERIALIZERS_DIR = File.join('app', 'serializers')
|
46
|
+
SERIALIZERS_TEST_DIR = File.join('test', 'serializers')
|
47
|
+
SERIALIZERS_SPEC_DIR = File.join('spec', 'serializers')
|
48
|
+
|
49
|
+
class << self
|
50
|
+
def generate(root_directory, pattern_type, options)
|
51
|
+
case pattern_type
|
52
|
+
when 'test' then test_files(root_directory)
|
53
|
+
when 'fixture' then fixture_files(root_directory)
|
54
|
+
when 'scaffold' then scaffold_files(root_directory)
|
55
|
+
when 'factory' then factory_files(root_directory)
|
56
|
+
when 'serializer' then serialize_files(root_directory)
|
57
|
+
when 'additional_file_patterns'
|
58
|
+
[options[:additional_file_patterns] || []].flatten
|
59
|
+
when 'controller'
|
60
|
+
[File.join(root_directory, CONTROLLER_DIR, '%PLURALIZED_MODEL_NAME%_controller.rb')]
|
61
|
+
when 'admin'
|
62
|
+
[
|
63
|
+
File.join(root_directory, ACTIVEADMIN_DIR, '%MODEL_NAME%.rb'),
|
64
|
+
File.join(root_directory, ACTIVEADMIN_DIR, '%PLURALIZED_MODEL_NAME%.rb')
|
65
|
+
]
|
66
|
+
when 'helper'
|
67
|
+
[File.join(root_directory, HELPER_DIR, '%PLURALIZED_MODEL_NAME%_helper.rb')]
|
68
|
+
else
|
69
|
+
[]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def test_files(root_directory)
|
76
|
+
[
|
77
|
+
File.join(root_directory, UNIT_TEST_DIR, '%MODEL_NAME%_test.rb'),
|
78
|
+
File.join(root_directory, MODEL_TEST_DIR, '%MODEL_NAME%_test.rb'),
|
79
|
+
File.join(root_directory, SPEC_MODEL_DIR, '%MODEL_NAME%_spec.rb')
|
80
|
+
]
|
81
|
+
end
|
82
|
+
|
83
|
+
def fixture_files(root_directory)
|
84
|
+
[
|
85
|
+
File.join(root_directory, FIXTURE_TEST_DIR, '%TABLE_NAME%.yml'),
|
86
|
+
File.join(root_directory, FIXTURE_SPEC_DIR, '%TABLE_NAME%.yml'),
|
87
|
+
File.join(root_directory, FIXTURE_TEST_DIR, '%PLURALIZED_MODEL_NAME%.yml'),
|
88
|
+
File.join(root_directory, FIXTURE_SPEC_DIR, '%PLURALIZED_MODEL_NAME%.yml')
|
89
|
+
]
|
90
|
+
end
|
91
|
+
|
92
|
+
def scaffold_files(root_directory)
|
93
|
+
[
|
94
|
+
File.join(root_directory, CONTROLLER_TEST_DIR, '%PLURALIZED_MODEL_NAME%_controller_test.rb'),
|
95
|
+
File.join(root_directory, CONTROLLER_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_controller_spec.rb'),
|
96
|
+
File.join(root_directory, REQUEST_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_spec.rb'),
|
97
|
+
File.join(root_directory, ROUTING_SPEC_DIR, '%PLURALIZED_MODEL_NAME%_routing_spec.rb')
|
98
|
+
]
|
99
|
+
end
|
100
|
+
|
101
|
+
def factory_files(root_directory)
|
102
|
+
[
|
103
|
+
File.join(root_directory, EXEMPLARS_TEST_DIR, '%MODEL_NAME%_exemplar.rb'),
|
104
|
+
File.join(root_directory, EXEMPLARS_SPEC_DIR, '%MODEL_NAME%_exemplar.rb'),
|
105
|
+
File.join(root_directory, BLUEPRINTS_TEST_DIR, '%MODEL_NAME%_blueprint.rb'),
|
106
|
+
File.join(root_directory, BLUEPRINTS_SPEC_DIR, '%MODEL_NAME%_blueprint.rb'),
|
107
|
+
File.join(root_directory, FACTORY_BOT_TEST_DIR, '%MODEL_NAME%_factory.rb'), # (old style)
|
108
|
+
File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%MODEL_NAME%_factory.rb'), # (old style)
|
109
|
+
File.join(root_directory, FACTORY_BOT_TEST_DIR, '%TABLE_NAME%.rb'), # (new style)
|
110
|
+
File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%TABLE_NAME%.rb'), # (new style)
|
111
|
+
File.join(root_directory, FACTORY_BOT_TEST_DIR, '%PLURALIZED_MODEL_NAME%.rb'), # (new style)
|
112
|
+
File.join(root_directory, FACTORY_BOT_SPEC_DIR, '%PLURALIZED_MODEL_NAME%.rb'), # (new style)
|
113
|
+
File.join(root_directory, FABRICATORS_TEST_DIR, '%MODEL_NAME%_fabricator.rb'),
|
114
|
+
File.join(root_directory, FABRICATORS_SPEC_DIR, '%MODEL_NAME%_fabricator.rb')
|
115
|
+
]
|
116
|
+
end
|
117
|
+
|
118
|
+
def serialize_files(root_directory)
|
119
|
+
[
|
120
|
+
File.join(root_directory, SERIALIZERS_DIR, '%MODEL_NAME%_serializer.rb'),
|
121
|
+
File.join(root_directory, SERIALIZERS_TEST_DIR, '%MODEL_NAME%_serializer_test.rb'),
|
122
|
+
File.join(root_directory, SERIALIZERS_SPEC_DIR, '%MODEL_NAME%_serializer_spec.rb')
|
123
|
+
]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|