fractaledmind / enlitenment

A Rails application template script to lead your app to SQLite enlightenment.
44 stars 3 forks source link

Default JOBS_CONTROLLER breaks if AdminController does not exist #2

Closed thedumbtechguy closed 2 months ago

thedumbtechguy commented 2 months ago

Describe the bug

In the application, we default JOBS_CONTROLLER to AdminController which might not exist.

JOBS_CONTROLLER = ENV.fetch("JOBS_CONTROLLER", "AdminController").freeze

To Reproduce

 bin/rails app:template \
  LOCATION=/Users/user/Desktop/enlitenment-main/template.rb

Expected behavior Provide git diffs to accompany the text description of the expected outcome.

Additional context Add any other context about the problem here.

thedumbtechguy commented 2 months ago

For this one, I used

diff --git a/template.rb b/template.rb
index da8dd1f..9441ff6 100644
--- a/template.rb
+++ b/template.rb
@@ -9,7 +9,7 @@ AT_LEAST_RAILS_8 = RAILS_GEM_VERSION.release >= RAILS_8_VERSION
 SKIP_SOLID_QUEUE = ENV.fetch("SKIP_SOLID_QUEUE", false).freeze
 QUEUE_DB = ENV.fetch("QUEUE_DB", "queue").freeze
 JOBS_ROUTE = ENV.fetch("JOBS_ROUTE", "/jobs").freeze
-JOBS_CONTROLLER = ENV.fetch("JOBS_CONTROLLER", "AdminController").freeze
+JOBS_CONTROLLER = ENV.fetch("JOBS_CONTROLLER") { "AdminController".safe_constantize&.to_s || "ApplicationController" }.freeze

 SKIP_SOLID_CACHE = ENV.fetch("SKIP_SOLID_CACHE", false).freeze
 CACHE_DB = ENV.fetch("CACHE_DB", "cache").freeze
fractaledmind commented 2 months ago

My thought was it was preferable for the setup to not work than for someone to unintentionally ship their job dashboard as publicly available.

thedumbtechguy commented 2 months ago

Maybe some prompts to ask the user what they'd like to do?

fractaledmind commented 2 months ago

Ok, I don't want to have too many prompts. You can easily just change/remove the generated code. How about this for a default:

If the JOBS_CONTROLLER cannot be constantized, the script generates a controller to secure the web UI:

# app/controllers/mission_control/base_controller.rb
module MissionControl
  mattr_writer :username
  mattr_writer :password

  class << self
    # use method instead of attr_accessor to ensure
    # this works if variable set after SolidErrors is loaded
    def username
      @username ||= ENV["MISSION_CONTROL_USERNAME"] || @@username
    end

    def password
      @password ||= ENV["MISSION_CONTROL_PASSWORD"] || @@password
    end
  end

  class BaseController < ActionController::Base
    protect_from_forgery with: :exception

    http_basic_authenticate_with name: MissionControl.username, password: MissionControl.password
  end
end

Then, I can set MissionControl::BaseController as the configured base controller and we know that controller exists. Plus, there is zero chance you ship your jobs web UI publicly. If/when you want something better than this, you just edit your code as desired.

thedumbtechguy commented 2 months ago

@fractaledmind

I like the idea of a generated controller.

I've shared the console log below.

Fetching https://github.com/rails/solid_cache.git
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Bundle complete! 24 Gemfile dependencies, 131 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Post-install message from solid_cache:
Upgrading from Solid Cache v0.3 or earlier? There are new database migrations in v0.4.
See https://github.com/rails/solid_cache/blob/main/upgrading_to_version_0.4.x.md for upgrade instructions.
      def_db    cache (database.yml)
      add_db    cache -> development (database.yml)
      add_db    cache -> test (database.yml)
      add_db    cache -> production (database.yml)
         run    bin/rails generate solid_cache:install from "."
=> [plutonium] starting reloader
/Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/inflector/methods.rb:290:in `const_get': uninitialized constant AdminController (NameError)

      Object.const_get(camel_cased_word)
            ^^^^^^^^^^
Did you mean?  AdminsController
               ActionController
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/inflector/methods.rb:290:in `constantize'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/mission_control-jobs-0.3.0/lib/mission_control/jobs/engine.rb:56:in `block in <class:Engine>'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/lazy_load_hooks.rb:94:in `block in execute_hook'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/lazy_load_hooks.rb:87:in `with_execution_control'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/lazy_load_hooks.rb:92:in `execute_hook'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/lazy_load_hooks.rb:78:in `block in run_load_hooks'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/lazy_load_hooks.rb:77:in `each'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.2.0/lib/active_support/lazy_load_hooks.rb:77:in `run_load_hooks'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/application/finisher.rb:94:in `block in <module:Finisher>'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/initializable.rb:32:in `instance_exec'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/initializable.rb:32:in `run'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/initializable.rb:61:in `block in run_initializers'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:228:in `block in tsort_each'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:431:in `each_strongly_connected_component_from'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:349:in `block in each_strongly_connected_component'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:347:in `each'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:347:in `call'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:347:in `each_strongly_connected_component'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:226:in `tsort_each'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/3.2.0/tsort.rb:205:in `tsort_each'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/initializable.rb:60:in `run_initializers'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/application.rb:428:in `initialize!'
        from /Users/user/code/tall_mast/config/environment.rb:5:in `<main>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.17/lib/zeitwerk/kernel.rb:34:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/application.rb:404:in `require_environment!'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/command/actions.rb:20:in `boot_application!'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/commands/generate/generate_command.rb:21:in `perform'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.1/lib/thor/command.rb:28:in `run'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.1/lib/thor/invocation.rb:127:in `invoke_command'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/command/base.rb:178:in `invoke_command'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.1/lib/thor.rb:527:in `dispatch'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/command/base.rb:73:in `perform'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/command.rb:71:in `block in invoke'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/command.rb:149:in `with_argv'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/command.rb:69:in `invoke'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.2.0/lib/rails/commands.rb:18:in `<main>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/bootsnap-1.18.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from bin/rails:4:in `<main>'
       error    Failed to run `bin/rails generate solid_cache:install`. Resolve and try again
fractaledmind commented 2 months ago

This looks like an error from multiple runs without resetting. The template now shouldn't output AdminController if that constant doesn't exist. Can you be sure to reset your code base as if you've never run the script once and try again?

fractaledmind commented 2 months ago

Whoops 😅 didn't push the code. One sec

fractaledmind commented 2 months ago

Ok, you can try now.

thedumbtechguy commented 2 months ago

Tested and working.