Module: Padrino::Generators::Actions
- Included in:
- AdminApp, AdminPage, App, Component, Controller, Helper, Mailer, Migration, Model, Plugin, Project, Task
- Defined in:
- padrino-gen/lib/padrino-gen/generators/actions.rb
Overview
Common actions needed to support project and component generation.
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#already_exists?(name, project_name = nil) ⇒ Boolean
Returns true if constant name already exists.
-
#app_skeleton(app, tiny = false) ⇒ Object
Generates standard and tiny applications within a project.
-
#apply_component_for(choice, component) ⇒ Object
Returns the related module for a given component and option.
-
#apply_default_fields(fields) ⇒ Array<String>
Apply default field types.
-
#check_app_existence(app) ⇒ Object
Raise SystemExit if the app does not exist.
-
#destination_root(*paths) ⇒ String
Returns the root for this Thor class (also aliased as destination root).
-
#empty_directory_with_keep_file(destination, config = {}) ⇒ Object
Creates an empty directory with .keep file.
-
#execute_component_setup(component, choice) ⇒ Object
Performs the necessary generator for a given component choice.
-
#fetch_app_name(app = 'app') ⇒ String
Returns the app_name for the application at root.
-
#fetch_component_choice(component) ⇒ String
Returns the component choice stored within the .component file of an application.
-
#fetch_project_name(app = 'app') ⇒ String
Returns the namespace for the project.
-
#in_app_root? ⇒ Boolean
Returns true if inside a Padrino application.
-
#include_component_module_for(component, choice = nil) ⇒ Object
Includes the component module for the given component and choice.
-
#initializer(name, data = nil) ⇒ Object
Registers and creates initializer.
-
#inject_into_file(destination, *args, &block) ⇒ Object
Avoids editing destination file if it does not exist.
-
#insert_hook(include_text, where) ⇒ Object
Inserts an hook before or after load in our boot.rb.
-
#insert_into_gemfile(name, options = {}) ⇒ Object
Inserts a required gem into the Gemfile to add the bundler dependency.
-
#insert_middleware(include_text, app = nil) ⇒ Object
Inserts a middleware inside app.rb.
-
#invalid_fields(fields) ⇒ Array<String>
Returns the field with an unacceptable name(for symbol) else returns nil.
-
#keep_file(destination) ⇒ Object
Creates an empty .keep file.
-
#middleware(name, source) ⇒ Object
Creates and inserts middleware.
-
#recognize_path ⇒ Object
Recognizes the path of application.
-
#require_contrib(contrib) ⇒ Object
Insert the regired gem and add in boot.rb custom contribs.
-
#require_dependencies(*gem_names) ⇒ Object
Adds all the specified gems into the Gemfile for bundler.
-
#resolve_valid_choice(component) ⇒ String
Prompts the user if necessary until a valid choice is returned for the component.
-
#retrieve_component_config(target) ⇒ Hash
Loads the component config back into a hash.
-
#run_bundler ⇒ Object
Run the bundler.
-
#store_component_choice(key, value) ⇒ Symbol
Set the component choice in the .component file of the application.
-
#store_component_config(destination, opts = {}) ⇒ Object
Creates a component_config file at the destination containing all component options.
-
#test? ⇒ Boolean
Return true if our project has test component.
-
#tiny? ⇒ Boolean
Return true if we have a tiny skeleton.
-
#valid_choice?(component, choice) ⇒ Boolean
Returns true if the option passed is a valid choice for component.
-
#valid_constant?(name) ⇒ Exception
Ensures that project name is valid, else raise an NameError.
-
#validate_namespace(name) ⇒ Object
Validates namespace name (controller name, etc.) or fails with an error.
Instance Method Details
#already_exists?(name, project_name = nil) ⇒ Boolean
Returns true if constant name already exists.
221 222 223 224 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 221 def already_exists?(name, project_name = nil) project_name = project_name ? (Object.const_get(project_name) rescue nil) : nil Object.const_defined?(name) || project_name&.const_defined?(name) end |
#app_skeleton(app, tiny = false) ⇒ Object
Generates standard and tiny applications within a project.
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 474 def app_skeleton(app, tiny = false) directory('app/', destination_root(app)) if tiny template 'templates/controller.rb.tt', destination_root(app, 'controllers.rb') @helper_name = DEFAULT_HELPER_NAME template 'templates/helper.rb.tt', destination_root(app, 'helpers.rb') @short_name = 'notifier' template 'templates/mailer.rb.tt', destination_root(app, 'mailers.rb') else empty_directory destination_root(app, 'controllers') empty_directory destination_root(app, 'helpers') empty_directory destination_root(app, 'views') empty_directory destination_root(app, 'views', 'layouts') end end |
#apply_component_for(choice, component) ⇒ Object
Returns the related module for a given component and option.
59 60 61 62 63 64 65 66 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 59 def apply_component_for(choice, component) # I need to override Thor#apply because for unknown reason verbose: false break tasks. path = File.(__dir__ + "/components/#{component.to_s.pluralize}/#{choice}.rb") say_status :apply, "#{component.to_s.pluralize}/#{choice}" shell.padding += 1 instance_eval(File.read(path)) shell.padding -= 1 end |
#apply_default_fields(fields) ⇒ Array<String>
Apply default field types.
250 251 252 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 250 def apply_default_fields(fields) fields.map! { |field| field =~ /:/ ? field : "#{field}:string" } end |
#check_app_existence(app) ⇒ Object
Raise SystemExit if the app does not exist.
451 452 453 454 455 456 457 458 459 460 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 451 def check_app_existence(app) return if File.exist?(destination_root(app)) say say '=================================================================' say "Unable to locate '#{app.underscore.camelize}' application " say '=================================================================' say raise SystemExit end |
#destination_root(*paths) ⇒ String
Returns the root for this Thor class (also aliased as destination root).
207 208 209 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 207 def destination_root(*paths) File.(File.join(@destination_stack.last, paths)) end |
#empty_directory_with_keep_file(destination, config = {}) ⇒ Object
Creates an empty directory with .keep file
535 536 537 538 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 535 def empty_directory_with_keep_file(destination, config = {}) empty_directory(destination, config) keep_file(destination) end |
#execute_component_setup(component, choice) ⇒ Object
Performs the necessary generator for a given component choice.
41 42 43 44 45 46 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 41 def execute_component_setup(component, choice) return say_status(:skipping, "#{component} component...") if choice.to_s == 'none' say_status(:applying, "#{choice} (#{component})...") apply_component_for(choice, component) send("setup_#{component}") if respond_to?("setup_#{component}") end |
#fetch_app_name(app = 'app') ⇒ String
Returns the app_name for the application at root.
295 296 297 298 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 295 def fetch_app_name(app = 'app') app_path = destination_root(app, 'app.rb') @app_name ||= File.read(app_path).scan(/class\s(.*?)\s</).flatten[0] end |
#fetch_component_choice(component) ⇒ String
Returns the component choice stored within the .component file of an application.
98 99 100 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 98 def fetch_component_choice(component) retrieve_component_config(destination_root('.components'))[component] end |
#fetch_project_name(app = 'app') ⇒ String
Returns the namespace for the project.
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 264 def fetch_project_name(app = 'app') _app_path = destination_root(app, 'app.rb') @project_name = fetch_component_choice(:namespace) if @project_name.empty? @project_name ||= begin detected_namespace = File.basename(destination_root('.')).gsub(/\W/, '_').camelize say 'Autodetecting project namespace using folder name.', :red say '' say <<~WARNING, :red From v0.11.0 on, applications should have a `namespace` setting in their .components file. Please include a line like the following in your .components file: WARNING say "\t:namespace: #{detected_namespace}", :yellow say '' detected_namespace end end |
#in_app_root? ⇒ Boolean
Returns true if inside a Padrino application.
214 215 216 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 214 def in_app_root? File.exist?(destination_root('config/boot.rb')) end |
#include_component_module_for(component, choice = nil) ⇒ Object
Includes the component module for the given component and choice. It determines the choice using .components file.
81 82 83 84 85 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 81 def include_component_module_for(component, choice = nil) choice ||= fetch_component_choice(component) return false if choice.to_s == 'none' apply_component_for(choice, component) end |
#initializer(name, data = nil) ⇒ Object
Registers and creates initializer.
382 383 384 385 386 387 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 382 def initializer(name, data = nil) @_init_name, @_init_data = name, data register = data ? " register #{name.to_s.underscore.camelize}Initializer\n" : " register #{name}\n" inject_into_file destination_root('/app/app.rb'), register, after: "Padrino::Application\n" template 'templates/initializer.rb.tt', destination_root("/config/initializers/#{name}.rb") if data end |
#inject_into_file(destination, *args, &block) ⇒ Object
Avoids editing destination file if it does not exist.
24 25 26 27 28 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 24 def inject_into_file(destination, *args, &block) destination_path = Pathname.new(destination).absolute? ? destination : destination_root(destination) return unless File.exist?(destination_path) super end |
#insert_hook(include_text, where) ⇒ Object
Inserts an hook before or after load in our boot.rb.
352 353 354 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 352 def insert_hook(include_text, where) inject_into_file('config/boot.rb', " #{include_text}\n", after: "Padrino.#{where} do\n") end |
#insert_into_gemfile(name, options = {}) ⇒ Object
Inserts a required gem into the Gemfile to add the bundler dependency.
331 332 333 334 335 336 337 338 339 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 331 def insert_into_gemfile(name, = {}) after_pattern = [:group] ? "#{[:group].to_s.capitalize} requirements\n" : "Component requirements\n" version = .delete(:version) = .map { |k, v| k.to_s == 'require' && [true, false].include?(v) ? "#{k}: #{v}" : "#{k}: '#{v}'" }.join(', ') write_option = .empty? ? '' : ", #{}" write_version = version ? ", '#{version}'" : '' include_text = "gem '#{name}'" << write_version << write_option << "\n" inject_into_file('Gemfile', include_text, after: after_pattern) end |
#insert_middleware(include_text, app = nil) ⇒ Object
Inserts a middleware inside app.rb.
365 366 367 368 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 365 def insert_middleware(include_text, app = nil) name = app || ([:name] ? @app_name.downcase : 'app') inject_into_file("#{name}/app.rb", " use #{include_text}\n", after: "Padrino::Application\n") end |
#invalid_fields(fields) ⇒ Array<String>
Returns the field with an unacceptable name(for symbol) else returns nil.
237 238 239 240 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 237 def invalid_fields(fields) results = fields.select { |field| field.split(':').first =~ /\W/ } results.empty? ? nil : results end |
#keep_file(destination) ⇒ Object
Creates an empty .keep file
543 544 545 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 543 def keep_file(destination) create_file("#{destination}/.keep") end |
#middleware(name, source) ⇒ Object
Creates and inserts middleware.
400 401 402 403 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 400 def middleware(name, source) create_file destination_root("lib/#{name}_middleware.rb"), source insert_middleware name.to_s.underscore.camelize end |
#recognize_path ⇒ Object
Recognizes the path of application.
528 529 530 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 528 def recognize_path [:app] == '.' ? '/..' : '/../..' end |
#require_contrib(contrib) ⇒ Object
Insert the regired gem and add in boot.rb custom contribs.
414 415 416 417 418 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 414 def require_contrib(contrib) insert_into_gemfile 'padrino-contrib' contrib = "require '#{File.join('padrino-contrib', contrib)}'\n" inject_into_file destination_root('/config/boot.rb'), contrib, before: "\nPadrino.load!" end |
#require_dependencies(*gem_names) ⇒ Object
Adds all the specified gems into the Gemfile for bundler.
313 314 315 316 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 313 def require_dependencies(*gem_names) = gem_names.last.is_a?(Hash) ? gem_names.pop : {} gem_names.reverse_each { |lib| insert_into_gemfile(lib, ) } end |
#resolve_valid_choice(component) ⇒ String
Prompts the user if necessary until a valid choice is returned for the component.
150 151 152 153 154 155 156 157 158 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 150 def resolve_valid_choice(component) choices = self.class.available_choices_for(component).map(&:to_s) choice = [component] until valid_choice?(component, choice) say("Option for --#{component} '#{choice}' is not available.", :red) choice = ask("Please enter a valid option for #{component}:", limited_to: choices) end choice end |
#retrieve_component_config(target) ⇒ Hash
Loads the component config back into a hash.
135 136 137 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 135 def retrieve_component_config(target) YAML.load_file(target) end |
#run_bundler ⇒ Object
Run the bundler.
437 438 439 440 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 437 def run_bundler say 'Bundling application dependencies using bundler...', :yellow in_root { run 'bundle install --binstubs' } end |
#store_component_choice(key, value) ⇒ Symbol
Set the component choice in the .component file of the application.
115 116 117 118 119 120 121 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 115 def store_component_choice(key, value) path = destination_root('.components') config = retrieve_component_config(path) config[key] = value create_file(path, force: true) { config.to_yaml } value end |
#store_component_config(destination, opts = {}) ⇒ Object
Creates a component_config file at the destination containing all component options. Content is a YAMLized version of a hash containing component name mapping to chosen value.
187 188 189 190 191 192 193 194 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 187 def store_component_config(destination, opts = {}) components = @_components || create_file(destination, opts) do self.class.component_types.each_with_object({}) do |comp, result| result[comp] = components[comp].to_s end.to_yaml end end |
#test? ⇒ Boolean
Return true if our project has test component.
423 424 425 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 423 def test? fetch_component_choice(:test).to_s != 'none' end |
#tiny? ⇒ Boolean
Return true if we have a tiny skeleton.
430 431 432 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 430 def tiny? File.exist?(destination_root('app/controllers.rb')) end |
#valid_choice?(component, choice) ⇒ Boolean
Returns true if the option passed is a valid choice for component.
173 174 175 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 173 def valid_choice?(component, choice) choice && self.class.available_choices_for(component).include?(choice.to_sym) end |
#valid_constant?(name) ⇒ Exception
Ensures that project name is valid, else raise an NameError.
502 503 504 505 506 507 508 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 502 def valid_constant?(name) if name =~ /^\d/ raise ::NameError, "Constant name #{name} cannot start with numbers" elsif name =~ /^\W/ raise ::NameError, "Constant name #{name} cannot start with non-word character" end end |
#validate_namespace(name) ⇒ Object
Validates namespace name (controller name, etc.) or fails with an error.
520 521 522 523 |
# File 'padrino-gen/lib/padrino-gen/generators/actions.rb', line 520 def validate_namespace(name) valid_constant? name name.match(/^[[:alnum:]_]+$/) || raise(::NameError, "Namespace '#{name}' must consist only of alphanumeric characters or '_'") end |