-
-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR is the CableReady counterpart to stimulusreflex/stimulus_reflex#610. I'm not going to rehash everything discussed in the SR installer; it is a modified subset of the same system. There are some small differences but great pains have been taken to keep everything consistent. **It is possible to install CableReady, and then add StimulusReflex to the project and install StimulusReflex at a later date.** Note that if you try to run the CableReady installer when StimulusReflex is in your project, it will exit and tell you to run the SR installer; It supports all major bundlers in their default configuration: Rails 6.1: webpacker 5.4.3, shakapacker, vite Rails 7: importmap, esbuild, shakapacker, vite I've adapted the `cable_ready:channel` generator to work with the new installer. The `cable_ready:initializer` generator has been removed in favor of the installer. ```bash rails cable_ready:install # fully automatic detections, with prompts rails cable_ready:install esbuild # specify a bundler rails cable_ready:install entrypoint=app/frontend webpacker # install with webpacker 5.4.3 in app/frontend rails cable_ready:install:step action_cable yarn bundle # re-run one or more steps rails cable_ready:install:restart # wipe state and restart install rails cable_ready:install uncomment=true # uncomment any necessary includes that have been commented rails cable_ready:install spring=false # do not remove spring (equivalent to answering `n`) rails cable_ready:install trace=true # debug install process with full stack trace rails cable_ready:install:step mrujs # install mrujs rails cable_ready:install:step compression # monkey patch Action Cable to compress WS traffic with deflate # full fat install with zero interactive prompts, suitable for scripting rails cable_ready:install esbuild entrypoint=app/javascript uncomment=true spring=true ``` ## Why should this be added We really need to up our installation and integration game to overcome the emotional barrier people often feel when comparing us against a built-in solution. The more we can make installing CR feel like ordering a Big Mac combo, the less water "golden path" arguments hold. Closes #179 with massive kudos to @julianrubisch for showing me how to structure an installer. Closes #180 with apologies to @Matt-Yorkley for the delay Fixes #130 with a hat-tip to @julianrubisch Fixes #131 ----- Co-authored-by: Marco Roth <[email protected]> Co-authored-by: Julian Rubisch <[email protected]>
- Loading branch information
1 parent
93774d1
commit a7c607e
Showing
48 changed files
with
2,006 additions
and
249 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
class CableReadyBroadcastJob < (defined?(ActiveJob::Base) ? ActiveJob::Base : Object) | ||
include CableReady::Broadcaster | ||
queue_as :default if defined?(ActiveJob::Base) | ||
if defined?(ActiveJob::Base) | ||
class CableReadyBroadcastJob < ActiveJob::Base | ||
include CableReady::Broadcaster | ||
|
||
def perform(identifier:, operations:, model: nil) | ||
if model.present? | ||
cable_ready[identifier.safe_constantize].apply!(operations).broadcast_to(model) | ||
else | ||
cable_ready[identifier].apply!(operations).broadcast | ||
def perform(identifier:, operations:, model: nil) | ||
if model.present? | ||
cable_ready[identifier.safe_constantize].apply!(operations).broadcast_to(model) | ||
else | ||
cable_ready[identifier].apply!(operations).broadcast | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
# frozen_string_literal: true | ||
|
||
require "cable_ready/version" | ||
|
||
### general utilities | ||
|
||
def fetch(step_path, file) | ||
relative_path = step_path + file | ||
location = template_src + relative_path | ||
|
||
Pathname.new(location) | ||
end | ||
|
||
def complete_step(step) | ||
create_file "tmp/cable_ready_installer/#{step}", verbose: false | ||
end | ||
|
||
def create_or_append(path, *args, &block) | ||
FileUtils.touch(path) | ||
append_file(path, *args, &block) | ||
end | ||
|
||
def current_template | ||
ENV["LOCATION"].split("/").last.gsub(".rb", "") | ||
end | ||
|
||
def pack_path_missing? | ||
return false unless pack_path.nil? | ||
halt "#{friendly_pack_path} is missing. You need a valid application pack file to proceed." | ||
end | ||
|
||
def halt(message) | ||
say "❌ #{message}", :red | ||
create_file "tmp/cable_ready_installer/halt", verbose: false | ||
end | ||
|
||
def backup(path, delete: false) | ||
if !path.exist? | ||
yield | ||
return | ||
end | ||
|
||
backup_path = Pathname.new("#{path}.bak") | ||
old_path = path.relative_path_from(Rails.root).to_s | ||
filename = path.to_path.split("/").last | ||
|
||
if backup_path.exist? | ||
if backup_path.read == path.read | ||
path.delete if delete | ||
yield | ||
return | ||
end | ||
backup_path.delete | ||
end | ||
|
||
copy_file(path, backup_path, verbose: false) | ||
path.delete if delete | ||
|
||
yield | ||
|
||
if path.read != backup_path.read | ||
create_or_append(backups_path, "#{old_path}\n", verbose: false) | ||
end | ||
say "📦 #{old_path} backed up as #{filename}.bak" | ||
end | ||
|
||
def add_gem(name) | ||
create_or_append(add_gem_list, "#{name}\n", verbose: false) | ||
say "☑️ Added #{name} to the Gemfile" | ||
end | ||
|
||
def remove_gem(name) | ||
create_or_append(remove_gem_list, "#{name}\n", verbose: false) | ||
say "❎ Removed #{name} from Gemfile" | ||
end | ||
|
||
def add_package(name) | ||
create_or_append(package_list, "#{name}\n", verbose: false) | ||
say "☑️ Enqueued #{name} to be added to dependencies" | ||
end | ||
|
||
def add_dev_package(name) | ||
create_or_append(dev_package_list, "#{name}\n", verbose: false) | ||
say "☑️ Enqueued #{name} to be added to dev dependencies" | ||
end | ||
|
||
def drop_package(name) | ||
create_or_append(drop_package_list, "#{name}\n", verbose: false) | ||
say "❎ Enqueued #{name} to be removed from dependencies" | ||
end | ||
|
||
def gemfile_hash | ||
Digest::MD5.hexdigest(gemfile_path.read) | ||
end | ||
|
||
### memoized values | ||
|
||
def cr_npm_version | ||
@cr_npm_version ||= CableReady::VERSION.gsub(".pre", "-pre") | ||
end | ||
|
||
def package_json | ||
@package_json ||= Rails.root.join("package.json") | ||
end | ||
|
||
def entrypoint | ||
@entrypoint ||= File.read("tmp/cable_ready_installer/entrypoint") | ||
end | ||
|
||
def bundler | ||
@bundler ||= File.read("tmp/cable_ready_installer/bundler") | ||
end | ||
|
||
def config_path | ||
@config_path ||= Rails.root.join(entrypoint, "config") | ||
end | ||
|
||
def importmap_path | ||
@importmap_path ||= Rails.root.join("config/importmap.rb") | ||
end | ||
|
||
def friendly_importmap_path | ||
@friendly_importmap_path ||= importmap_path.relative_path_from(Rails.root).to_s | ||
end | ||
|
||
def pack | ||
@pack ||= pack_path.read | ||
end | ||
|
||
def friendly_pack_path | ||
@friendly_pack_path ||= pack_path.relative_path_from(Rails.root).to_s | ||
end | ||
|
||
def pack_path | ||
@pack_path ||= [ | ||
Rails.root.join(entrypoint, "application.js"), | ||
Rails.root.join(entrypoint, "packs/application.js"), | ||
Rails.root.join(entrypoint, "entrypoints/application.js") | ||
].find(&:exist?) | ||
end | ||
|
||
def package_list | ||
@package_list ||= Rails.root.join("tmp/cable_ready_installer/npm_package_list") | ||
end | ||
|
||
def dev_package_list | ||
@dev_package_list ||= Rails.root.join("tmp/cable_ready_installer/npm_dev_package_list") | ||
end | ||
|
||
def drop_package_list | ||
@drop_package_list ||= Rails.root.join("tmp/cable_ready_installer/drop_npm_package_list") | ||
end | ||
|
||
def template_src | ||
@template_src ||= File.read("tmp/cable_ready_installer/template_src") | ||
end | ||
|
||
def controllers_path | ||
@controllers_path ||= Rails.root.join(entrypoint, "controllers") | ||
end | ||
|
||
def gemfile_path | ||
@gemfile_path ||= Rails.root.join("Gemfile") | ||
end | ||
|
||
def gemfile | ||
@gemfile ||= gemfile_path.read | ||
end | ||
|
||
def prefix | ||
# standard:disable Style/RedundantStringEscape | ||
@prefix ||= { | ||
"vite" => "..\/", | ||
"webpacker" => "", | ||
"shakapacker" => "", | ||
"importmap" => "", | ||
"esbuild" => ".\/" | ||
}[bundler] | ||
# standard:enable Style/RedundantStringEscape | ||
end | ||
|
||
def application_record_path | ||
@application_record_path ||= Rails.root.join("app/models/application_record.rb") | ||
end | ||
|
||
def action_cable_initializer_path | ||
@action_cable_initializer_path ||= Rails.root.join("config/initializers/action_cable.rb") | ||
end | ||
|
||
def action_cable_initializer_working_path | ||
@action_cable_initializer_working_path ||= Rails.root.join(working, "action_cable.rb") | ||
end | ||
|
||
def development_path | ||
@development_path ||= Rails.root.join("config/environments/development.rb") | ||
end | ||
|
||
def development_working_path | ||
@development_working_path ||= Rails.root.join(working, "development.rb") | ||
end | ||
|
||
def backups_path | ||
@backups_path ||= Rails.root.join("tmp/cable_ready_installer/backups") | ||
end | ||
|
||
def add_gem_list | ||
@add_gem_list ||= Rails.root.join("tmp/cable_ready_installer/add_gem_list") | ||
end | ||
|
||
def remove_gem_list | ||
@remove_gem_list ||= Rails.root.join("tmp/cable_ready_installer/remove_gem_list") | ||
end | ||
|
||
def options_path | ||
@options_path ||= Rails.root.join("tmp/cable_ready_installer/options") | ||
end | ||
|
||
def options | ||
@options ||= YAML.safe_load(File.read(options_path)) | ||
end | ||
|
||
def working | ||
@working ||= Rails.root.join("tmp/cable_ready_installer/working") | ||
end |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.