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

Inherits:
Command
  • Object
show all
Defined in:
lib/brut/cli/apps/scaffold.rb

Direct Known Subclasses

Form

Defined Under Namespace

Classes: Route

Instance Method Summary collapse

Methods inherited from Command

#after_bootstrap, args, #args, #before_execute, command_name, default_env, #delegate_to_commands, description, detailed_description, env_var, #err, #global_options, #handle_bootstrap_exception, #initialize, name_matches?, option_parser, #options, opts, #out, requires_project_env, requires_project_env?, #system!

Methods included from Framework::Errors

#abstract_method!, #bug!

Methods included from I18n::ForCLI

#capture, #html_escape, #safe

Methods included from I18n::BaseMethods

#l, #t, #t_direct, #this_field_value

Methods included from ExecutionResults

#abort_execution, #as_execution_result, #cli_usage_error, #continue_execution, #show_cli_usage, #stop_execution

Constructor Details

This class inherits a constructor from Brut::CLI::Command

Instance Method Details

#execute(form: false) ⇒ Object



414
415
416
417
418
419
420
421
422
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
# File 'lib/brut/cli/apps/scaffold.rb', line 414

def execute(form: false)
  if args.length != 1
    raise "#{self.class.command_name} requires exactly one argument, got #{args.length}"
  end
  route = Route.new(args[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|
      err.puts "'#{path.relative_path_from(Brut.container.project_root)}' exists already"
    end
    err.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 = if form
                         'raise "You need to implement your Handler\#{form.class.input_definitions.length < 2 ? " and likely your Form as well" : ""}"'
                       else
                         'raise "You need to implement your Handler"'
                       end
  handler_code = begin
                   handle_params = []
                   if form
                     handle_params << :form
                   end
                   handle_params += route.path_params
                   handle_params_code = handle_params.map { "#{it}:" }.join(", ")
    %{class #{handler_class_name} < AppHandler
  def handle(#{handle_params_code}) # add other args here as needed
#{handle_method_code}
  end
end}
                 end

  spec_code = %{require "spec_helper"

RSpec.describe #{handler_class_name} do
  subject(:handler) { described_class.new }
  describe "#handle!" do
it "needs tests" do
  expect(true).to eq(false)
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?
    out.puts app_path.relative_path_from(Brut.container.project_root)
    out.puts "will contain:\n\n#{route_code}\n\n"
    if form
      out.puts form_source_path.relative_path_from(Brut.container.project_root)
      out.puts "will contain:\n\n#{form_code}\n\n"
    end
    out.puts handler_source_path.relative_path_from(Brut.container.project_root)
    out.puts "will contain:\n\n#{handler_code}\n\n"
    out.puts handler_spec_path.relative_path_from(Brut.container.project_root)
    out.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"
    out.puts "\n\n"
    if form
      out.printf printf_string,form_class_name,form_source_path.relative_path_from(Brut.container.project_root)
    end
    out.printf printf_string,handler_class_name, handler_source_path.relative_path_from(Brut.container.project_root)
    out.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?
      out.puts "Could not find routes declaration in #{app_path.relative_path_from(Brut.container.project_root)}"
      out.puts "Please add this to wherever you have defined your routes:\n\n#{route_code}\n\n"
    elsif routes_editor.routes_existed?
      out.puts "Routes declaration in #{app_path.relative_path_from(Brut.container.project_root)} contained the route defition already"
      out.puts "Please make sure everything is correct.  Here is the defintion that was not inserted:\n\n#{route_code}"
    end
  end
  0
end