Module: Rails::Generators
Constant Summary
-
DEFAULT_ALIASES =
# File 'railties/lib/rails/generators.rb', line 30{ rails: { actions: "-a", orm: "-o", javascripts: ["-j", "--js"], resource_controller: "-c", scaffold_controller: "-c", stylesheets: "-y", template_engine: "-e", test_framework: "-t" }, test_unit: { fixture_replacement: "-r", } }.freeze -
DEFAULT_OPTIONS =
# File 'railties/lib/rails/generators.rb', line 47{ rails: { api: false, assets: true, force_plural: false, helper: true, integration_tool: nil, orm: false, resource_controller: :controller, resource_route: true, scaffold_controller: :scaffold_controller, system_tests: nil, test_framework: nil, template_engine: :erb } }.freeze -
RAILS_DEV_PATH =
Internal use only
# File 'railties/lib/rails/generators.rb', line 66
We need to store the
RAILS_DEV_PATHin a constant, otherwise the path can change when weFileUtils.cd.File.("../../..", __dir__)
Class Attribute Summary
- .namespace (also: #namespace) rw
Class Method Summary
-
.api_only!
Configure generators for
APIonly applications. -
.fallbacks
Hold configured generators fallbacks.
-
.help(command = "generate")
Show help message with available generators.
-
.hidden_namespaces
Returns an array of generator namespaces that are hidden.
-
.hide_namespace(*namespaces)
Alias for .hide_namespaces.
- .hide_namespaces(*namespaces) (also: .hide_namespace)
-
.invoke(namespace, args = ARGV, config = {})
Receives a namespace, arguments, and the behavior to invoke the generator.
- .print_generators
- .public_namespaces
- .sorted_groups
- .command_type private
- .file_lookup_paths private
-
.invoke_fallbacks_for(name, base)
private
Try fallbacks for the given base.
- .lookup_paths private
- .print_list(base, namespaces) private
- .run_after_generate_callback private
- .add_generated_file(file) Internal use only
- .after_generate_callbacks Internal use only
- .aliases Internal use only
- .configure!(config) Internal use only
-
.find_by_namespace(name, base = nil, context = nil)
Internal use only
::Railsfinds namespaces similar to Thor, it only adds one rule: - .options Internal use only
- .templates_path Internal use only
Instance Attribute Summary
- #namespace rw
Class Attribute Details
.namespace (rw) Also known as: #namespace
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 28
mattr_accessor :namespace
Class Method Details
.add_generated_file(file)
# File 'railties/lib/rails/generators.rb', line 288
def add_generated_file(file) # :nodoc: (@@generated_files ||= []) << file file end
.after_generate_callbacks
# File 'railties/lib/rails/generators.rb', line 93
def after_generate_callbacks # :nodoc: @after_generate_callbacks ||= [] end
.aliases
# File 'railties/lib/rails/generators.rb', line 85
def aliases # :nodoc: @aliases ||= DEFAULT_ALIASES.dup end
.api_only!
Configure generators for API only applications. It basically hides
everything that is usually browser related, such as assets and session
migration generators, and completely disable helpers and assets
so generators such as scaffold won't create them.
# File 'railties/lib/rails/generators.rb', line 119
def api_only! hide_namespaces "assets", "helper", "css", "js" [:rails].merge!( api: true, assets: false, helper: false, template_engine: nil ) [:mailer] ||= {} [:mailer][:template_engine] ||= :erb end
.command_type (private)
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 315
def command_type # :doc: @command_type ||= "generator" end
.configure!(config)
# File 'railties/lib/rails/generators.rb', line 69
def configure!(config) # :nodoc: api_only! if config.api_only no_color! unless config.colorize_logging aliases.deep_merge! config.aliases .deep_merge! config. fallbacks.merge! config.fallbacks templates_path.concat config.templates templates_path.uniq! hide_namespaces(*config.hidden_namespaces) after_generate_callbacks.replace config.after_generate_callbacks end
.fallbacks
Hold configured generators fallbacks. If a plugin developer wants a generator group to fall back to another group in case of missing generators, they can add a fallback.
For example, shoulda is considered a test_framework and is an extension
of test_unit. However, most part of shoulda generators are similar to
test_unit ones.
Shoulda then can tell generators to search for test_unit generators when
some of them are not available by adding a fallback:
{Rails::Generators}.fallbacks[:shoulda] = :test_unit
# File 'railties/lib/rails/generators.rb', line 111
def fallbacks @fallbacks ||= {} end
.file_lookup_paths (private)
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 323
def file_lookup_paths # :doc: @file_lookup_paths ||= [ "{#{lookup_paths.join(',')}}", "**", "*_generator.rb" ] end
.find_by_namespace(name, base = nil, context = nil)
::Rails finds namespaces similar to Thor, it only adds one rule:
Generators names must end with "_generator.rb". This is required because ::Rails
looks in load paths and loads the generator just before it's going to be used.
find_by_namespace :webrat, :rails, :integration
Will search for the following generators:
"rails:webrat", "webrat:integration", "webrat"
Notice that "rails:generators:webrat" could be loaded as well, what Rails looks for is the first and last parts of the namespace.
# File 'railties/lib/rails/generators.rb', line 243
def find_by_namespace(name, base = nil, context = nil) # :nodoc: lookups = [] lookups << "#{base}:#{name}" if base lookups << "#{name}:#{context}" if context unless base || context unless name.to_s.include?(?:) lookups << "#{name}:#{name}" lookups << "rails:#{name}" end lookups << "#{name}" end lookup(lookups) namespaces = subclasses.index_by(&:namespace) lookups.each do |namespace| klass = namespaces[namespace] return klass if klass end invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name) end
.help(command = "generate")
Show help message with available generators.
# File 'railties/lib/rails/generators.rb', line 175
def help(command = "generate") puts "Usage:" puts " bin/rails #{command} GENERATOR [args] [options]" puts puts "General options:" puts " -h, [--help] # Print generator's options and usage" puts " -p, [--pretend] # Run but do not make any changes" puts " -f, [--force] # Overwrite files that already exist" puts " -s, [--skip] # Skip files that already exist" puts " -q, [--quiet] # Suppress status output" puts puts "Please choose a generator below." puts print_generators end
.hide_namespace(*namespaces)
Alias for .hide_namespaces.
# File 'railties/lib/rails/generators.rb', line 172
alias hide_namespace hide_namespaces
.hide_namespaces(*namespaces) Also known as: .hide_namespace
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 169
def hide_namespaces(*namespaces) hidden_namespaces.concat(namespaces) end
.invoke(namespace, args = ARGV, config = {})
Receives a namespace, arguments, and the behavior to invoke the generator. It's used as the default entry point for generate, destroy, and update commands.
# File 'railties/lib/rails/generators.rb', line 270
def invoke(namespace, args = ARGV, config = {}) names = namespace.to_s.split(":") if klass = find_by_namespace(names.pop, names.any? && names.join(":")) args << "--help" if args.empty? && klass.arguments.any?(&:required?) klass.start(args, config) run_after_generate_callback if config[:behavior] == :invoke else = sorted_groups.flat_map(&:last) error = Command::CorrectableNameError.new("Could not find generator '#{namespace}'.", namespace, ) puts <<~MSG #{error.} Run `bin/rails generate --help` for more options. MSG exit 1 end end
.invoke_fallbacks_for(name, base) (private)
Try fallbacks for the given base.
# File 'railties/lib/rails/generators.rb', line 300
def invoke_fallbacks_for(name, base) return nil unless base && fallbacks[base.to_sym] invoked_fallbacks = [] Array(fallbacks[base.to_sym]).each do |fallback| next if invoked_fallbacks.include?(fallback) invoked_fallbacks << fallback klass = find_by_namespace(name, fallback) return klass if klass end nil end
.lookup_paths (private)
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 319
def lookup_paths # :doc: @lookup_paths ||= %w( rails/generators generators ) end
.options
# File 'railties/lib/rails/generators.rb', line 89
def # :nodoc: @options ||= DEFAULT_OPTIONS.dup end
.print_generators
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 197
def print_generators sorted_groups.each { |b, n| print_list(b, n) } end
.print_list(base, namespaces) (private)
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 294
def print_list(base, namespaces) # :doc: namespaces = namespaces.reject { |n| hidden_namespaces.include?(n) } super end
.public_namespaces
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 192
def public_namespaces lookup! subclasses.map(&:namespace) end
.run_after_generate_callback (private)
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 327
def run_after_generate_callback if defined?(@@generated_files) && !@@generated_files.empty? after_generate_callbacks.each do |callback| callback.call(@@generated_files) end @@generated_files = [] end end
.sorted_groups
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 201
def sorted_groups namespaces = public_namespaces namespaces.sort! groups = Hash.new { |h, k| h[k] = [] } namespaces.each do |namespace| base = namespace.split(":").first groups[base] << namespace end rails = groups.delete("rails") rails.map! { |n| n.delete_prefix("rails:") } rails.delete("app") rails.delete("plugin") rails.delete("encrypted_file") rails.delete("encryption_key_file") rails.delete("master_key") rails.delete("credentials") rails.delete("db:system:change") hidden_namespaces.each { |n| groups.delete(n.to_s) } [[ "rails", rails ]] + groups.sort.to_a end
.templates_path
# File 'railties/lib/rails/generators.rb', line 81
def templates_path # :nodoc: @templates_path ||= [] end
Instance Attribute Details
#namespace (rw)
[ GitHub ]# File 'railties/lib/rails/generators.rb', line 28
mattr_accessor :namespace