Class: RubyUiScaffold::Generators::InstallGenerator
- Inherits:
-
Rails::Generators::Base
- Object
- Rails::Generators::Base
- RubyUiScaffold::Generators::InstallGenerator
- Includes:
- ComponentInstaller
- Defined in:
- lib/generators/ruby_ui_scaffold/install/install_generator.rb
Overview
One-shot installer that wires up the prerequisites every scaffold needs on a fresh Rails app: the ruby_ui gem, phlex, ruby_ui, and the BASE set of components every generated scaffold uses (index/show/form shell).
Column/flag-specific components (badge, checkbox, textarea, combobox, select, date_picker, data_table) are NOT installed here — the scaffold generator installs those on demand, so apps only carry what they use.
Invoked as: ‘bin/rails g ruby_ui_scaffold:install`
Every step is idempotent — re-running the installer is safe and only touches what’s actually missing.
Instance Method Summary collapse
- #check_phlex_rails_gem ⇒ Object
- #done ⇒ Object
-
#ensure_ruby_ui_gem ⇒ Object
Ensure the ‘ruby_ui` gem is available.
-
#inject_tailwind_sources ⇒ Object
Tailwind v4 auto-detection misses ‘.rb` files by default, so the Phlex view + component class names never make it into the compiled stylesheet — meaning `mx-auto`, `max-w-prose`, etc.
-
#install_base_components ⇒ Object
Install the BASE components every scaffold uses (the index/show/form shell), so a bare ‘:install` leaves the ground ready.
- #install_phlex ⇒ Object
- #install_ruby_ui ⇒ Object
Methods included from ComponentInstaller
#component_installed?, #uninstalled_components
Instance Method Details
#check_phlex_rails_gem ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/generators/ruby_ui_scaffold/install/install_generator.rb', line 26 def check_phlex_rails_gem return if Gem.loaded_specs.key?("phlex-rails") say "\n ❌ The `phlex-rails` gem isn't bundled in this app.", :red say " ruby_ui_scaffold declares it as a runtime dependency — running", :red say " `bundle install` should pull it in. If you've excluded it via", :red say " Bundler groups, add it back and retry:\n", :red say %( gem "phlex-rails"), :cyan say " bundle install" say " bin/rails g ruby_ui_scaffold:install\n", :cyan exit(1) end |
#done ⇒ Object
128 129 130 131 132 |
# File 'lib/generators/ruby_ui_scaffold/install/install_generator.rb', line 128 def done say "\n ✅ ruby_ui_scaffold install complete.", :green say "\n Generate your first scaffold:\n", :cyan say " bin/rails g ruby_ui_scaffold MyModel name:string\n", :cyan end |
#ensure_ruby_ui_gem ⇒ Object
Ensure the ‘ruby_ui` gem is available. Unlike `phlex-rails` (a declared runtime dependency of this gem), `ruby_ui` is distributed via GitHub and can’t be a gemspec dependency — so on a fresh app it usually isn’t bundled yet. Rather than abort, add it to the Gemfile and ‘bundle install` automatically, then let the rest of the installer proceed: the subsequent `ruby_ui:install` / `ruby_ui:component` steps run in subprocesses (via run_rails_generator!) that boot with the freshly updated bundle, so they find the gem even though THIS process didn’t load it. Idempotent — skips the Gemfile edit when an entry already exists, and does nothing at all once the gem loads.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/generators/ruby_ui_scaffold/install/install_generator.rb', line 49 def ensure_ruby_ui_gem return if ruby_ui_loadable? gemfile = File.join(destination_root, "Gemfile") abort_ruby_ui_unavailable! unless File.exist?(gemfile) if File.read(gemfile).match?(/^\s*gem\s+["']ruby_ui["']/) say "\n → ruby_ui is in the Gemfile but not bundled yet — running `bundle install`.", :cyan else say "\n → ruby_ui gem not found — adding it to your Gemfile.", :cyan gem "ruby_ui", github: "ruby-ui/ruby_ui", branch: "main", require: false end run_bundle_install! end |
#inject_tailwind_sources ⇒ Object
Tailwind v4 auto-detection misses ‘.rb` files by default, so the Phlex view + component class names never make it into the compiled stylesheet — meaning `mx-auto`, `max-w-prose`, etc. render with no effect. Inject explicit `@source` directives so Tailwind scans `app/views/*/.rb` and `app/components/*/.rb`. Idempotent.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/generators/ruby_ui_scaffold/install/install_generator.rb', line 112 def inject_tailwind_sources css_path = File.join(destination_root, "app/assets/tailwind/application.css") return unless File.exist?(css_path) contents = File.read(css_path) sources_to_add = [] sources_to_add << %(@source "../../views/**/*.rb";) unless contents.include?("../../views/**/*.rb") sources_to_add << %(@source "../../components/**/*.rb";) unless contents.include?("../../components/**/*.rb") return if sources_to_add.empty? say "\n → Adding Tailwind @source directives for Phlex views/components", :cyan inject_into_file css_path, after: /@import "tailwindcss";\n/ do "\n" + sources_to_add.join("\n") + "\n" end end |
#install_base_components ⇒ Object
Install the BASE components every scaffold uses (the index/show/form shell), so a bare ‘:install` leaves the ground ready. We deliberately don’t run ‘ruby_ui:component:all` — column/flag-specific components are installed on demand by the scaffold generator. `ruby_ui:component` resolves transitive dependencies itself (e.g. alert_dialog → button), so the BASE list only names what the scaffold references directly.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/generators/ruby_ui_scaffold/install/install_generator.rb', line 92 def install_base_components missing = uninstalled_components(::RubyUiScaffold::ComponentResolver::BASE) if missing.empty? say " ✓ Base scaffold components already installed", :green return end say "\n → Installing #{missing.size} base component(s) every scaffold uses", :cyan missing.each do |component| say " • #{component}", :cyan run_rails_generator!("ruby_ui:component", component) end end |
#install_phlex ⇒ Object
65 66 67 68 69 70 71 72 73 |
# File 'lib/generators/ruby_ui_scaffold/install/install_generator.rb', line 65 def install_phlex if File.exist?(File.join(destination_root, "app/views/base.rb")) say " ✓ phlex already installed (app/views/base.rb exists)", :green return end say "\n → Running `phlex:install`", :cyan run_rails_generator!("phlex:install") end |
#install_ruby_ui ⇒ Object
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/generators/ruby_ui_scaffold/install/install_generator.rb', line 75 def install_ruby_ui components_base = File.join(destination_root, "app/components/base.rb") if File.exist?(components_base) && File.read(components_base).include?("RubyUI") say " ✓ ruby_ui already installed (Components::Base includes RubyUI)", :green return end say "\n → Running `ruby_ui:install`", :cyan run_rails_generator!("ruby_ui:install") end |