Skip to content

Commit 5275757

Browse files
gantactran
authored andcommitted
Fix problem with specifying model files as argument (#514)
* Refactor AnnotateModels#get_model_files * Add the tests for `AnnotateModels#get_model_files` * Remove unnecessary `reject` call
1 parent 7c8e916 commit 5275757

File tree

2 files changed

+157
-23
lines changed

2 files changed

+157
-23
lines changed

lib/annotate/annotate_models.rb

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -649,34 +649,52 @@ def options_with_position(options, position_in)
649649
# of model files from root dir. Otherwise we take all the model files
650650
# in the model_dir directory.
651651
def get_model_files(options)
652-
models = []
653-
unless options[:is_rake]
654-
models = ARGV.dup.reject { |m| m.match(/^(.*)=/) }
655-
end
652+
model_files = []
656653

657-
if models.empty?
658-
begin
659-
model_dir.each do |dir|
660-
Dir.chdir(dir) do
661-
lst =
662-
if options[:ignore_model_sub_dir]
663-
Dir["*.rb"].map{ |f| [dir, f] }
664-
else
665-
Dir["**/*.rb"].reject{ |f| f["concerns/"] }.map{ |f| [dir, f] }
666-
end
667-
models.concat(lst)
668-
end
669-
end
670-
rescue SystemCallError
671-
puts "No models found in directory '#{model_dir.join("', '")}'."
672-
puts "Either specify models on the command line, or use the --model-dir option."
673-
puts "Call 'annotate --help' for more info."
674-
exit 1
654+
model_files = list_model_files_from_argument unless options[:is_rake]
655+
656+
return model_files unless model_files.empty?
657+
658+
model_dir.each do |dir|
659+
Dir.chdir(dir) do
660+
list = if options[:ignore_model_sub_dir]
661+
Dir["*.rb"].map { |f| [dir, f] }
662+
else
663+
Dir["**/*.rb"].reject { |f| f["concerns/"] }.map { |f| [dir, f] }
664+
end
665+
model_files.concat(list)
675666
end
676667
end
677668

678-
models
669+
model_files
670+
rescue SystemCallError
671+
puts "No models found in directory '#{model_dir.join("', '")}'."
672+
puts "Either specify models on the command line, or use the --model-dir option."
673+
puts "Call 'annotate --help' for more info."
674+
exit 1
675+
end
676+
677+
def list_model_files_from_argument
678+
return [] if ARGV.empty?
679+
680+
specified_files = ARGV.map { |file| File.expand_path(file) }
681+
682+
model_files = model_dir.flat_map do |dir|
683+
absolute_dir_path = File.expand_path(dir)
684+
specified_files
685+
.find_all { |file| file.start_with?(absolute_dir_path) }
686+
.map { |file| [dir, file.sub("#{absolute_dir_path}/", '')] }
687+
end
688+
689+
if model_files.size != specified_files.size
690+
puts "The specified file could not be found in directory '#{model_dir.join("', '")}'."
691+
puts "Call 'annotate --help' for more info."
692+
exit 1
693+
end
694+
695+
model_files
679696
end
697+
private :list_model_files_from_argument
680698

681699
# Retrieve the classes belonging to the model names we're asked to process
682700
# Check for namespaced models in subdirectories as well as models

spec/annotate/annotate_models_spec.rb

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'annotate/annotate_models'
44
require 'annotate/active_record_patch'
55
require 'active_support/core_ext/string'
6+
require 'files'
67

78
describe AnnotateModels do
89
def mock_index(name, params = {})
@@ -951,6 +952,121 @@ def self.when_called_with(options = {})
951952
end
952953
end
953954

955+
describe '#get_model_files' do
956+
subject { described_class.get_model_files(options) }
957+
958+
before do
959+
ARGV.clear
960+
961+
described_class.model_dir = [model_dir]
962+
end
963+
964+
context 'when `model_dir` is valid' do
965+
let(:model_dir) do
966+
Files do
967+
file 'foo.rb'
968+
dir 'bar' do
969+
file 'baz.rb'
970+
dir 'qux' do
971+
file 'quux.rb'
972+
end
973+
end
974+
dir 'concerns' do
975+
file 'corge.rb'
976+
end
977+
end
978+
end
979+
980+
context 'when the model files are not specified' do
981+
context 'when no option is specified' do
982+
let(:options) { {} }
983+
984+
it 'returns all model files under `model_dir` directory' do
985+
is_expected.to contain_exactly(
986+
[model_dir, 'foo.rb'],
987+
[model_dir, File.join('bar', 'baz.rb')],
988+
[model_dir, File.join('bar', 'qux', 'quux.rb')]
989+
)
990+
end
991+
end
992+
993+
context 'when `ignore_model_sub_dir` option is enabled' do
994+
let(:options) { { ignore_model_sub_dir: true } }
995+
996+
it 'returns model files just below `model_dir` directory' do
997+
is_expected.to contain_exactly([model_dir, 'foo.rb'])
998+
end
999+
end
1000+
end
1001+
1002+
context 'when the model files are specified' do
1003+
let(:additional_model_dir) { 'additional_model' }
1004+
let(:model_files) do
1005+
[
1006+
File.join(model_dir, 'foo.rb'),
1007+
"./#{File.join(additional_model_dir, 'corge/grault.rb')}" # Specification by relative path
1008+
]
1009+
end
1010+
1011+
before { ARGV.concat(model_files) }
1012+
1013+
context 'when no option is specified' do
1014+
let(:options) { {} }
1015+
1016+
context 'when all the specified files are in `model_dir` directory' do
1017+
before do
1018+
described_class.model_dir << additional_model_dir
1019+
end
1020+
1021+
it 'returns specified files' do
1022+
is_expected.to contain_exactly(
1023+
[model_dir, 'foo.rb'],
1024+
[additional_model_dir, 'corge/grault.rb']
1025+
)
1026+
end
1027+
end
1028+
1029+
context 'when a model file outside `model_dir` directory is specified' do
1030+
it 'exits with the status code' do
1031+
begin
1032+
subject
1033+
raise
1034+
rescue SystemExit => e
1035+
expect(e.status).to eq(1)
1036+
end
1037+
end
1038+
end
1039+
end
1040+
1041+
context 'when `is_rake` option is enabled' do
1042+
let(:options) { { is_rake: true } }
1043+
1044+
it 'returns all model files under `model_dir` directory' do
1045+
is_expected.to contain_exactly(
1046+
[model_dir, 'foo.rb'],
1047+
[model_dir, File.join('bar', 'baz.rb')],
1048+
[model_dir, File.join('bar', 'qux', 'quux.rb')]
1049+
)
1050+
end
1051+
end
1052+
end
1053+
end
1054+
1055+
context 'when `model_dir` is invalid' do
1056+
let(:model_dir) { '/not_exist_path' }
1057+
let(:options) { {} }
1058+
1059+
it 'exits with the status code' do
1060+
begin
1061+
subject
1062+
raise
1063+
rescue SystemExit => e
1064+
expect(e.status).to eq(1)
1065+
end
1066+
end
1067+
end
1068+
end
1069+
9541070
describe '#get_model_class' do
9551071
require 'tmpdir'
9561072

0 commit comments

Comments
 (0)