Skip to content

Commit f612f8a

Browse files
authored
Add tests for the CLI (#635)
Currently there's no test coverage on CLI. This adds tests for a new class Parser which will replace the command line options currently in bin/annotate. The technical direction I'm planning to go is to remove ENV variables completely and to have things passed into as arguments. Will be adding deprecation warnings in 3.0 and then deprecate ENV variables completely in 3.1. Deprecation warnings will be non-blocking in 3.0 when an ENV variable is set and an argument isn't passed in, and will becoming blocking in 3.1.
1 parent 46d2d63 commit f612f8a

File tree

4 files changed

+768
-190
lines changed

4 files changed

+768
-190
lines changed

bin/annotate

Lines changed: 6 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -14,203 +14,19 @@ end
1414
here = File.expand_path(File.dirname __FILE__)
1515
$LOAD_PATH << "#{here}/../lib"
1616

17-
require 'optparse'
1817
require 'annotate'
19-
Annotate.bootstrap_rake
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'
10919

110-
opts.on('--ck',
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
20021

201-
opts.on('--ignore-unknown-models', "don't display warnings for bad model files") do |values|
202-
ENV['ignore_unknown_models'] = 'true'
203-
end
22+
options_result = Annotate::Parser.parse(ARGV)
20423

205-
opts.on('--with-comment', "include database comments in model annotations") do |values|
206-
ENV['with_comment'] = 'true'
207-
end
208-
end.parse!
24+
exit if options_result[:exit]
20925

21026
options = Annotate.setup_options(
21127
is_rake: ENV['is_rake'] && !ENV['is_rake'].empty?
21228
)
21329
Annotate.eager_load(options) if Annotate.include_models?
21430

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.include_models?
32+
AnnotateRoutes.send(options_result[:target_action], options) if Annotate.include_routes?

0 commit comments

Comments
 (0)