Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option for additional file patterns #633

Merged
merged 2 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/annotate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -88,6 +88,7 @@ def self.setup_options(options = {})
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]
Expand Down
30 changes: 23 additions & 7 deletions lib/annotate/annotate_models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,15 @@ def serialize_files(root_directory)
]
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate what's going on here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will return the config setting additional_file_patterns, which is a list of files and/or globs. This allows the gem to infer models based on file structure or naming and annotate additional files.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should've been more specific - I'm curious about:

[options[:additional_file_patterns] || []].flatten

Is there any special reason behind it? Couldn't it also be:

options[:additional_file_patterns] || []

when 'controller'
[File.join(root_directory, CONTROLLER_DIR, "%PLURALIZED_MODEL_NAME%_controller.rb")]
when 'admin'
Expand All @@ -177,14 +179,20 @@ def files_by_pattern(root_directory, pattern_type)
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
Expand Down Expand Up @@ -581,8 +589,9 @@ def remove_annotation_of_file(file_name, options = {})
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
Expand Down Expand Up @@ -634,8 +643,11 @@ def annotate(klass, file, header, options = {})
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
Expand Down Expand Up @@ -793,6 +805,10 @@ def do_annotations(options = {})
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) : '')
Expand Down Expand Up @@ -830,7 +846,7 @@ def remove_annotations(options = {})
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)
Expand Down
83 changes: 42 additions & 41 deletions lib/generators/annotate/templates/auto_annotate_models.rake
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
82 changes: 82 additions & 0 deletions spec/annotate/annotate_models_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,69 @@ def mock_column(name, type, options = {})
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)
Expand Down Expand Up @@ -1505,6 +1568,24 @@ class Foo < ActiveRecord::Base
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'
Expand All @@ -1523,6 +1604,7 @@ class Foo < ActiveRecord::Base
expect(filename). to eq 'test/fixtures/parent/children.yml'
end
end

describe 'annotating a file' do
before do
@model_dir = Dir.mktmpdir('annotate_models')
Expand Down