Commit f95913ba by Ryan Committed by Andrew W. Lee

Add option for additional file patterns (#633)

This PR adds an option named `additional_file_patterns`. You can specify custom path patterns (including globs) that the gem will use to annotate. For example, I used it like this on a project: ```ruby Annotate.set_defaults( 'additional_file_patterns' => [ File.join(Rails.application.root, 'app/lib/forms/%PLURALIZED_MODEL_NAME%/**/*.rb'), File.join(Rails.application.root, 'spec/lib/forms/%PLURALIZED_MODEL_NAME%/**/*.rb') ], ... ) ``` This makes it possible to have files nested under a directory which corresponds to the model. I believe this fixes #594.
parent f612f8ad
......@@ -36,7 +36,7 @@ module Annotate
:exclude_sti_subclasses, :ignore_unknown_models, :with_comment
].freeze
OTHER_OPTIONS = [
:ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close,
:additional_file_patterns, :ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close,
:wrapper, :routes, :hide_limit_column_types, :hide_default_column_types,
:ignore_routes, :active_admin
].freeze
......@@ -88,6 +88,7 @@ module Annotate
options[key] = !ENV[key.to_s].blank? ? ENV[key.to_s].split(',') : []
end
options[:additional_file_patterns] ||= []
options[:model_dir] = ['app/models'] if options[:model_dir].empty?
options[:wrapper_open] ||= options[:wrapper]
......
......@@ -159,13 +159,15 @@ module AnnotateModels
]
end
def files_by_pattern(root_directory, pattern_type)
def files_by_pattern(root_directory, pattern_type, options)
case pattern_type
when 'test' then test_files(root_directory)
when 'fixture' then fixture_files(root_directory)
when 'scaffold' then scaffold_files(root_directory)
when 'factory' then factory_files(root_directory)
when 'serializer' then serialize_files(root_directory)
when 'additional_file_patterns'
[options[:additional_file_patterns] || []].flatten
when 'controller'
[File.join(root_directory, CONTROLLER_DIR, "%PLURALIZED_MODEL_NAME%_controller.rb")]
when 'admin'
......@@ -177,14 +179,20 @@ module AnnotateModels
end
end
def get_patterns(pattern_types = [])
def get_patterns(options, pattern_types = [])
current_patterns = []
root_dir.each do |root_directory|
Array(pattern_types).each do |pattern_type|
current_patterns += files_by_pattern(root_directory, pattern_type)
patterns = files_by_pattern(root_directory, pattern_type, options)
current_patterns += if pattern_type.to_sym == :additional_file_patterns
patterns
else
patterns.map { |p| p.sub(/^[\/]*/, '') }
end
end
end
current_patterns.map { |p| p.sub(/^[\/]*/, '') }
current_patterns
end
# Simple quoting for the default column value
......@@ -581,8 +589,9 @@ module AnnotateModels
end
def matched_types(options)
types = MATCHED_TYPES
types = MATCHED_TYPES.dup
types << 'admin' if options[:active_admin] =~ TRUE_RE && !types.include?('admin')
types << 'additional_file_patterns' if options[:additional_file_patterns].present?
types
end
......@@ -634,8 +643,11 @@ module AnnotateModels
end
next if options[exclusion_key]
get_patterns(key)
get_patterns(options, key)
.map { |f| resolve_filename(f, model_name, table_name) }
.map { |f| expand_glob_into_files(f) }
.flatten
.each do |f|
if annotate_one_file(f, info, position_key, options_with_position(options, position_key))
annotated << f
......@@ -793,6 +805,10 @@ module AnnotateModels
end
end
def expand_glob_into_files(glob)
Dir.glob(glob)
end
def annotate_model_file(annotated, file, header, options)
begin
return false if /#{SKIP_ANNOTATION_PREFIX}.*/ =~ (File.exist?(file) ? File.read(file) : '')
......@@ -830,7 +846,7 @@ module AnnotateModels
model_file_name = file
deannotated_klass = true if remove_annotation_of_file(model_file_name, options)
get_patterns(matched_types(options))
get_patterns(options, matched_types(options))
.map { |f| resolve_filename(f, model_name, table_name) }
.each do |f|
if File.exist?(f)
......
......@@ -7,47 +7,48 @@ if Rails.env.development?
# You can override any of these by setting an environment variable of the
# same name.
Annotate.set_defaults(
'routes' => 'false',
'position_in_routes' => 'before',
'position_in_class' => 'before',
'position_in_test' => 'before',
'position_in_fixture' => 'before',
'position_in_factory' => 'before',
'position_in_serializer' => 'before',
'show_foreign_keys' => 'true',
'show_complete_foreign_keys' => 'false',
'show_indexes' => 'true',
'simple_indexes' => 'false',
'model_dir' => 'app/models',
'root_dir' => '',
'include_version' => 'false',
'require' => '',
'exclude_tests' => 'false',
'exclude_fixtures' => 'false',
'exclude_factories' => 'false',
'exclude_serializers' => 'false',
'exclude_scaffolds' => 'true',
'exclude_controllers' => 'true',
'exclude_helpers' => 'true',
'exclude_sti_subclasses' => 'false',
'ignore_model_sub_dir' => 'false',
'ignore_columns' => nil,
'ignore_routes' => nil,
'ignore_unknown_models' => 'false',
'hide_limit_column_types' => '<%= AnnotateModels::NO_LIMIT_COL_TYPES.join(",") %>',
'hide_default_column_types' => '<%= AnnotateModels::NO_DEFAULT_COL_TYPES.join(",") %>',
'skip_on_db_migrate' => 'false',
'format_bare' => 'true',
'format_rdoc' => 'false',
'format_markdown' => 'false',
'sort' => 'false',
'force' => 'false',
'frozen' => 'false',
'classified_sort' => 'true',
'trace' => 'false',
'wrapper_open' => nil,
'wrapper_close' => nil,
'with_comment' => 'true'
'additional_file_patterns' => [],
'routes' => 'false',
'position_in_routes' => 'before',
'position_in_class' => 'before',
'position_in_test' => 'before',
'position_in_fixture' => 'before',
'position_in_factory' => 'before',
'position_in_serializer' => 'before',
'show_foreign_keys' => 'true',
'show_complete_foreign_keys' => 'false',
'show_indexes' => 'true',
'simple_indexes' => 'false',
'model_dir' => 'app/models',
'root_dir' => '',
'include_version' => 'false',
'require' => '',
'exclude_tests' => 'false',
'exclude_fixtures' => 'false',
'exclude_factories' => 'false',
'exclude_serializers' => 'false',
'exclude_scaffolds' => 'true',
'exclude_controllers' => 'true',
'exclude_helpers' => 'true',
'exclude_sti_subclasses' => 'false',
'ignore_model_sub_dir' => 'false',
'ignore_columns' => nil,
'ignore_routes' => nil,
'ignore_unknown_models' => 'false',
'hide_limit_column_types' => '<%= AnnotateModels::NO_LIMIT_COL_TYPES.join(",") %>',
'hide_default_column_types' => '<%= AnnotateModels::NO_DEFAULT_COL_TYPES.join(",") %>',
'skip_on_db_migrate' => 'false',
'format_bare' => 'true',
'format_rdoc' => 'false',
'format_markdown' => 'false',
'sort' => 'false',
'force' => 'false',
'frozen' => 'false',
'classified_sort' => 'true',
'trace' => 'false',
'wrapper_open' => nil,
'wrapper_close' => nil,
'with_comment' => 'true'
)
end
......
......@@ -780,6 +780,69 @@ EOS
end
end
describe '#files_by_pattern' do
subject { AnnotateModels.files_by_pattern(root_directory, pattern_type, options) }
context 'when pattern_type=additional_file_patterns' do
let(:pattern_type) { 'additional_file_patterns' }
let(:root_directory) { nil }
context 'with additional_file_patterns' do
let(:additional_file_patterns) do
[
'%PLURALIZED_MODEL_NAME%/**/*.rb',
'%PLURALIZED_MODEL_NAME%/*_form'
]
end
let(:options) { { additional_file_patterns: additional_file_patterns } }
it do
expect(subject).to eq(additional_file_patterns)
end
end
context 'without additional_file_patterns' do
let(:options) { {} }
it do
expect(subject).to eq([])
end
end
end
end
describe '#get_patterns' do
subject { AnnotateModels.get_patterns(options, pattern_type) }
context 'when pattern_type=additional_file_patterns' do
let(:pattern_type) { 'additional_file_patterns' }
context 'with additional_file_patterns' do
let(:additional_file_patterns) do
[
'/%PLURALIZED_MODEL_NAME%/**/*.rb',
'/bar/%PLURALIZED_MODEL_NAME%/*_form'
]
end
let(:options) { { additional_file_patterns: additional_file_patterns } }
it do
expect(subject).to eq(additional_file_patterns)
end
end
context 'without additional_file_patterns' do
let(:options) { {} }
it do
expect(subject).to eq([])
end
end
end
end
describe '#get_schema_info with custom options' do
def self.when_called_with(options = {})
expected = options.delete(:returns)
......@@ -1505,6 +1568,24 @@ end
expect(filename). to eq 'test/unit/example_model_test.rb'
end
it 'should return the additional glob' do
filename_template = '/foo/bar/%MODEL_NAME%/testing.rb'
model_name = 'example_model'
table_name = 'example_models'
filename = AnnotateModels.resolve_filename(filename_template, model_name, table_name)
expect(filename). to eq '/foo/bar/example_model/testing.rb'
end
it 'should return the additional glob' do
filename_template = '/foo/bar/%PLURALIZED_MODEL_NAME%/testing.rb'
model_name = 'example_model'
table_name = 'example_models'
filename = AnnotateModels.resolve_filename(filename_template, model_name, table_name)
expect(filename). to eq '/foo/bar/example_models/testing.rb'
end
it 'should return the fixture path for a model' do
filename_template = 'test/fixtures/%TABLE_NAME%.yml'
model_name = 'example_model'
......@@ -1523,6 +1604,7 @@ end
expect(filename). to eq 'test/fixtures/parent/children.yml'
end
end
describe 'annotating a file' do
before do
@model_dir = Dir.mktmpdir('annotate_models')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment