Class: Brut::CLI::Apps::Scaffold::Action

Inherits:
Commands::BaseCommand show all
Defined in:
lib/brut/cli/apps/scaffold.rb

Direct Known Subclasses

Form

Defined Under Namespace

Classes: Route

Instance Attribute Summary

Attributes inherited from Commands::BaseCommand

#parent_command

Instance Method Summary collapse

Methods inherited from Commands::BaseCommand

#accepts, #argv, #bootstrap?, #commands, #default_command, #default_command_class, #default_rack_env, #env, #env_vars, #execute, #name, #options, #puts, #stderr, #stdin, #stdout, #system!

Instance Method Details

#args_descriptionObject



418
# File 'lib/brut/cli/apps/scaffold.rb', line 418

def args_description = "action_route"

#descriptionObject



417
# File 'lib/brut/cli/apps/scaffold.rb', line 417

def description = "Create a handler for an action"

#optsObject



419
420
421
# File 'lib/brut/cli/apps/scaffold.rb', line 419

def opts = [
  [ "--http-method=METHOD", "If present, the action will be a path available on the given route and this HTTP method. If omitted, this will create an action available via POST" ],
]

#run(form: false) ⇒ Object



423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
# File 'lib/brut/cli/apps/scaffold.rb', line 423

def run(form: false)
  if argv.length != 1
    raise "#{self.class.command_name} requires exactly one argument, got #{argv.length}"
  end
  route = Route.new(argv[0])

  form_class_name    = RichString.from_string(route.form_class.join("::"))
  handler_class_name = RichString.from_string(route.handler_class.join("::"))

  relative_path         = form_class_name.underscorized
  handler_relative_path = handler_class_name.underscorized

  forms_src_dir      = Brut.container.forms_src_dir
  handlers_src_dir   = Brut.container.handlers_src_dir
  handlers_specs_dir = Brut.container.handlers_specs_dir

  form_source_path    = Pathname( (forms_src_dir      / relative_path).to_s + ".rb" )
  handler_source_path = Pathname( (handlers_src_dir   / handler_relative_path).to_s + ".rb" )
  handler_spec_path   = Pathname( (handlers_specs_dir / handler_relative_path).to_s + ".spec.rb" )
  app_path            = Pathname( Brut.container.app_src_dir / "app.rb" )

  paths_to_check = [
    handler_source_path,
    handler_spec_path,
  ]
  if form
    paths_to_check << form_source_path
  end

  exists = paths_to_check.select(&:exist?)

  if exists.any? && !global_options.overwrite?
    exists.each do |path|
      stderr.puts "'#{path.relative_path_from(Brut.container.project_root)}' exists already"
    end
    stderr.puts "Re-run with global option --overwrite to overwrite these files"
    return 1
  end

  if form
    FileUtils.mkdir_p form_source_path.dirname, noop: global_options.dry_run?
  end
  FileUtils.mkdir_p handler_source_path.dirname, noop: global_options.dry_run?
  FileUtils.mkdir_p handler_spec_path.dirname,   noop: global_options.dry_run?

  form_code = %{class #{form_class_name} < AppForm
  input :some_field, minlength: 3
end}
  handle_method_code = 'raise "You need to implement your Handler"'
  handler_code = begin
                   handle_params = []
                   if form
                     handle_params << :form
                   end
                   handle_params += route.path_params
                   initializer_params_code = handle_params.map { "#{it}:" }.join(", ")
    %{class #{handler_class_name} < AppHandler
  def initialize(#{initializer_params_code}) # add other args here as needed
  end
  def handle
#{handle_method_code}
  end
end}
                 end

  spec_code = %{require "spec_helper"

RSpec.describe #{handler_class_name} do
  describe "#handle!" do
it "needs tests" do
  expect(true).to eq(false)
  # Make sure to call handle! (not handle)
end
  end
end}

  route_code = if form
                 "form \"#{route.path_template}\""
               elsif options.http_method.nil?
                 "action \"#{route.path_template}\""
               else
                 "path \"#{route.path_template}\", method: :#{options.http_method.downcase}"
               end

  if global_options.dry_run?
    stdout.puts app_path.relative_path_from(Brut.container.project_root)
    stdout.puts "will contain:\n\n#{route_code}\n\n"
    if form
      stdout.puts form_source_path.relative_path_from(Brut.container.project_root)
      stdout.puts "will contain:\n\n#{form_code}\n\n"
    end
    stdout.puts handler_source_path.relative_path_from(Brut.container.project_root)
    stdout.puts "will contain:\n\n#{handler_code}\n\n"
    stdout.puts handler_spec_path.relative_path_from(Brut.container.project_root)
    stdout.puts "will contain:\n\n#{spec_code}\n\n"
  else
    class_name_length = [ form_class_name.length, handler_class_name.length, "Spec".length ].max
    printf_string = "%-#{class_name_length}s in %s\n"
    stdout.puts "\n\n"
    if form
      stdout.printf printf_string,form_class_name,form_source_path.relative_path_from(Brut.container.project_root)
    end
    stdout.printf printf_string,handler_class_name, handler_source_path.relative_path_from(Brut.container.project_root)
    stdout.printf printf_string,"Spec", handler_spec_path.relative_path_from(Brut.container.project_root)

    routes_editor = RoutesEditor.new(app_path:,out:)
    routes_editor.add_route!(route_code:)

    if form
      File.open(form_source_path,"w") { it.puts form_code }
    end
    File.open(handler_source_path,"w") { it.puts handler_code }
    File.open(handler_spec_path,"w") { it.puts spec_code }
    if !routes_editor.found_routes?
      stdout.puts "Could not find routes declaration in #{app_path.relative_path_from(Brut.container.project_root)}"
      stdout.puts "Please add this to wherever you have defined your routes:\n\n#{route_code}\n\n"
    elsif routes_editor.routes_existed?
      stdout.puts "Routes declaration in #{app_path.relative_path_from(Brut.container.project_root)} contained the route defition already"
      stdout.puts "Please make sure everything is correct.  Here is the defintion that was not inserted:\n\n#{route_code}"
    end
  end
  0
end