module Refinery::ExtensionGeneration
Public Class Methods
included(base)
click to toggle source
# File lib/refinery/extension_generation.rb, line 4 def self.included(base) base.class_eval do argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" class_option :namespace, :type => :string, :default => nil, :banner => 'NAMESPACE', :required => false class_option :authors, :type => :array, :default => [], :banner => 'author author', :required => false, :desc => 'Indicates authors of this extension' class_option :extension, :type => :string, :default => nil, :banner => 'ENGINE', :required => false class_option :i18n, :type => :array, :default => [], :required => false, :banner => "field field", :desc => 'Indicates generated fields' class_option :install, :type => :boolean, :default => false, :required => false, :banner => nil, :desc => 'Bundles and runs the generated generator, rake db:migrate, rake db:seed for you' remove_class_option :skip_namespace end end
Public Instance Methods
attributes_for_translation_table()
click to toggle source
# File lib/refinery/extension_generation.rb, line 71 def attributes_for_translation_table localized_attributes.inject([]) { |memo, attr| memo << ":#{attr.name} => :#{attr.type}"}.join(', ') end
extension_class_name()
click to toggle source
# File lib/refinery/extension_generation.rb, line 41 def extension_class_name @extension_class_name ||= extension_name.camelize end
extension_name()
click to toggle source
# File lib/refinery/extension_generation.rb, line 33 def extension_name @extension_name ||= options[:extension].presence || singular_name end
extension_plural_class_name()
click to toggle source
# File lib/refinery/extension_generation.rb, line 45 def extension_plural_class_name @extension_plural_class_name ||= if options[:extension].present? # Use exactly what the user requested, not a plural version. extension_class_name else extension_class_name.pluralize end end
extension_plural_name()
click to toggle source
# File lib/refinery/extension_generation.rb, line 54 def extension_plural_name @extension_plural_name ||= if options[:extension].present? # Use exactly what the user requested, not a plural version. extension_name else extension_name.pluralize end end
image_attributes()
click to toggle source
# File lib/refinery/extension_generation.rb, line 79 def image_attributes @image_attributes ||= attributes.select { |a| a.refinery_type == :image }.uniq end
localized?()
click to toggle source
# File lib/refinery/extension_generation.rb, line 63 def localized? localized_attributes.any? end
localized_attributes()
click to toggle source
# File lib/refinery/extension_generation.rb, line 67 def localized_attributes @localized_attributes ||= attributes.select{ |a| options[:i18n].include?(a.name)} end
namespacing()
click to toggle source
# File lib/refinery/extension_generation.rb, line 18 def namespacing @namespacing ||= if options[:namespace].present? # Use exactly what the user requested, not a pluralised version. options[:namespace].to_s.camelize else # If the user has passed an engine, we want to generate it inside of # that extension. if options[:extension].present? options[:extension].to_s.camelize else class_name.pluralize end end end
resource_attributes()
click to toggle source
# File lib/refinery/extension_generation.rb, line 83 def resource_attributes @resource_attributes ||= attributes.select { |a| a.refinery_type == :resource }.uniq end
string_attributes()
click to toggle source
# File lib/refinery/extension_generation.rb, line 75 def string_attributes @string_attributes ||= attributes.select { |a| /string|text/ === a.refinery_type.to_s}.uniq end
Protected Instance Methods
append_extension_to_gemfile!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 89 def append_extension_to_gemfile! unless Rails.env.test? || (self.behavior != :revoke && extension_in_gemfile?) path = extension_pathname.parent.relative_path_from(gemfile.parent) append_file gemfile, "\ngem '#{gem_name}', path: '#{path}'" end end
clash_keywords()
click to toggle source
# File lib/refinery/extension_generation.rb, line 96 def clash_keywords @clash_keywords ||= begin clash_keywords = [] unless (clash_file = source_pathname.parent.join('clash_keywords.yml')).file? clash_file = source_pathname.parent.parent.join('clash_keywords.yml') end clash_keywords = YAML.load_file(clash_file) if clash_file.file? clash_keywords end end
copy_or_merge_seeds!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 226 def copy_or_merge_seeds! FileMerger.new(self, source_seed_file, destination_seed_file).call end
default_generate!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 107 def default_generate! sanity_check! evaluate_templates! unless options[:pretend] merge_existing_files! if existing_extension? copy_or_merge_seeds! if self.behavior != :revoke append_extension_to_gemfile! end install! if options[:install] finalize_extension! end
destination_pathname()
click to toggle source
# File lib/refinery/extension_generation.rb, line 125 def destination_pathname @destination_pathname ||= Pathname.new(self.destination_root.to_s) end
erase_destination!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 150 def erase_destination! if Pathname.glob(extension_pathname.join('**', '*')).all?(&:directory?) say_status :remove, relative_to_original_destination_root(extension_pathname.to_s), true FileUtils.rm_rf extension_pathname unless options[:pretend] end end
evaluate_templates!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 157 def evaluate_templates! viable_templates.each do |source_path, destination_path| next if /seeds.rb.erb/ === source_path.to_s && self.behavior != :revoke destination_path.sub!('.erb', '') if source_path.to_s !~ /views/ template source_path, destination_path end end
existing_extension?()
click to toggle source
# File lib/refinery/extension_generation.rb, line 167 def existing_extension? options[:extension].present? && extension_pathname.directory? end
exit_with_message!(message)
click to toggle source
# File lib/refinery/extension_generation.rb, line 171 def exit_with_message!(message) STDERR.puts "\n#{message}\n\n" exit 1 end
extension_in_gemfile?()
click to toggle source
# File lib/refinery/extension_generation.rb, line 176 def extension_in_gemfile? gemfile.read.scan(%r{#{gem_name}}).any? end
extension_path_for(path, extension, apply_tmp = true)
click to toggle source
# File lib/refinery/extension_generation.rb, line 133 def extension_path_for(path, extension, apply_tmp = true) path = extension_pathname.join path.sub(%r{#{source_pathname}/?}, '') path = substitute_path_placeholders path if options[:namespace].present? || options[:extension].present? path = increment_migration_timestamp(path) # Detect whether this is a special file that needs to get merged not overwritten. # This is important only when nesting extensions. # Routes and #{gem_name}\.rb have an .erb extension as path points to the generator template # We have to exclude it when checking if the file already exists and include it in the regexps path = extension_path_for_nested_extension(path, apply_tmp) if options[:extension].present? end path end
extension_pathname()
click to toggle source
# File lib/refinery/extension_generation.rb, line 129 def extension_pathname destination_pathname.join('vendor', 'extensions', extension_plural_name) end
finalize_extension!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 180 def finalize_extension! if self.behavior != :revoke && !options[:pretend] instruct_user! else erase_destination! end end
gem_name()
click to toggle source
# File lib/refinery/extension_generation.rb, line 188 def gem_name "refinerycms-#{extension_plural_name}" end
gemfile()
click to toggle source
# File lib/refinery/extension_generation.rb, line 192 def gemfile @gemfile ||= begin Bundler.default_gemfile || destination_pathname.join('Gemfile') end end
generator_command()
click to toggle source
# File lib/refinery/extension_generation.rb, line 198 def generator_command raise "You must override the method 'generator_command' in your generator." end
install!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 202 def install! run "bundle install" run "rails generate refinery:#{extension_plural_name}" run "rake db:migrate" run "rake db:seed" end
instruct_user!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 230 def instruct_user! unless Rails.env.test? puts "------------------------" if options[:install] puts "Your extension has been generated and installed." else puts "Now run:" puts "bundle install" puts "rails generate refinery:#{extension_plural_name}" puts "rake db:migrate" puts "rake db:seed" end puts "Please restart your rails server." puts "------------------------" end end
merge_existing_files!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 209 def merge_existing_files! # go through all of the temporary files and merge what we need into the current files. tmp_directories = [] globs = %w[config/locales/*.yml config/routes.rb.erb lib/refinerycms-extension_plural_name.rb.erb] Pathname.glob(source_pathname.join("{#{globs.join(',')}}"), File::FNM_DOTMATCH).each do |path| # get the path to the current tmp file. # Both the new and current paths need to strip the .erb portion from the generator template new_file_path = extension_path_for(path, extension_name).sub(/\.erb$/, '') tmp_directories << new_file_path.split.first current_path = extension_path_for(path, extension_name, false).sub(/\.erb$/, '') FileMerger.new(self, current_path, new_file_path, :to => current_path, :mode => 'w+').call end tmp_directories.uniq.each(&:rmtree) end
reject_file?(file)
click to toggle source
# File lib/refinery/extension_generation.rb, line 247 def reject_file?(file) !localized? && file.to_s.include?('locale_picker') end
reject_template?(file)
click to toggle source
# File lib/refinery/extension_generation.rb, line 251 def reject_template?(file) file.directory? || reject_file?(file) end
sanity_check!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 255 def sanity_check! prevent_clashes! prevent_uncountability! prevent_empty_attributes! prevent_invalid_extension! end
source_pathname()
click to toggle source
# File lib/refinery/extension_generation.rb, line 262 def source_pathname @source_pathname ||= Pathname.new(self.class.source_root.to_s) end
Private Instance Methods
all_templates()
click to toggle source
# File lib/refinery/extension_generation.rb, line 348 def all_templates Pathname.glob source_pathname.join('**', '**') end
destination_seed_file()
click to toggle source
# File lib/refinery/extension_generation.rb, line 325 def destination_seed_file destination_pathname.join extension_path_for(source_seed_file.sub('.erb', ''), extension_name) end
extension_path_for_nested_extension(path, apply_tmp)
click to toggle source
# File lib/refinery/extension_generation.rb, line 267 def extension_path_for_nested_extension(path, apply_tmp) return nil if !path.sub(/\.erb$/, '').file? && %r{readme.md|(lib/)?#{plural_name}.rb$} === path.to_s if apply_tmp && %r{(locales/.*\.yml)|((config/routes|#{gem_name})\.rb\.erb)$} === path.to_s path = path.dirname + 'tmp' + path.basename end path end
increment_migration_timestamp(path)
click to toggle source
# File lib/refinery/extension_generation.rb, line 278 def increment_migration_timestamp(path) # Increment the migration file leading number # Only relevant for nested or namespaced extensions, where a previous migration exists return path unless %r{/migrate/\d+.*\.rb.erb\z} === path.to_s && last_migration_file(path) path.sub(%r{\d+_}) { |m| "#{last_migration_file(path).match(%r{migrate/(\d+)_})[1].to_i + 1}_" } end
last_migration_file(path)
click to toggle source
# File lib/refinery/extension_generation.rb, line 286 def last_migration_file(path) Dir[destination_pathname.join(path.dirname + '*.rb')].sort.last end
prevent_clashes!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 290 def prevent_clashes! if clash_keywords.member?(singular_name.downcase) exit_with_message!("Please choose a different name. The generated code would fail for class '#{singular_name}' as it conflicts with a reserved keyword.") end end
prevent_empty_attributes!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 307 def prevent_empty_attributes! if attributes.empty? && self.behavior != :revoke exit_with_message! "You must specify a name and at least one field." \ "\nFor help, run: #{generator_command}" end end
prevent_invalid_extension!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 314 def prevent_invalid_extension! if options[:extension].present? && !extension_pathname.directory? exit_with_message! "You can't use '--extension #{options[:extension]}' because an" \ " extension with the name '#{options[:extension]}' doesn't exist." end end
prevent_uncountability!()
click to toggle source
# File lib/refinery/extension_generation.rb, line 296 def prevent_uncountability! if singular_name == plural_name message = if singular_name.singularize == singular_name "The extension name you specified will not work as the singular name is equal to the plural name." else "Please specify the singular name '#{singular_name.singularize}' instead of '#{plural_name}'." end exit_with_message! message end end
source_seed_file()
click to toggle source
# File lib/refinery/extension_generation.rb, line 321 def source_seed_file source_pathname.join 'db', 'seeds.rb.erb' end
substitute_path_placeholders(path)
click to toggle source
# File lib/refinery/extension_generation.rb, line 329 def substitute_path_placeholders(path) Pathname.new path.to_s.gsub('extension_plural_name', extension_plural_name). gsub('plural_name', plural_name). gsub('singular_name', singular_name). gsub('namespace', namespacing.underscore) end
viable_templates()
click to toggle source
# File lib/refinery/extension_generation.rb, line 336 def viable_templates @viable_templates ||= begin all_templates.reject(&method(:reject_template?)).inject({}) do |hash, path| if (destination_path = extension_path_for(path, extension_name)).present? hash[path.to_s] = destination_path.to_s end hash end end end