Skip to content

Commit

Permalink
Insolate and namespace CableReady::Installer
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoroth committed May 2, 2024
1 parent 55bb972 commit a87a16e
Show file tree
Hide file tree
Showing 18 changed files with 445 additions and 418 deletions.
365 changes: 196 additions & 169 deletions lib/cable_ready/installer.rb

Large diffs are not rendered by default.

58 changes: 29 additions & 29 deletions lib/install/action_cable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
if defined?(ActionCable::Engine)
say "✅ ActionCable::Engine is loaded and in scope"
else
halt "ActionCable::Engine is not loaded, please add or uncomment `require \"action_cable/engine\"` to your `config/application.rb`"
CableReady::Installer.halt "ActionCable::Engine is not loaded, please add or uncomment `require \"action_cable/engine\"` to your `config/application.rb`"
return
end

return if pack_path_missing?
return if CableReady::Installer.pack_path_missing?

# verify that the Action Cable pubsub config is created
cable_config = Rails.root.join("config/cable.yml")
Expand All @@ -35,7 +35,7 @@
"url" => "<%= ENV.fetch(\"REDIS_URL\") { \"redis://localhost:6379/1\" } %>",
"channel_prefix" => "#{app_name}_development"
}
backup(cable_config) do
CableReady::Installer.backup(cable_config) do
cable_config.write(yaml.to_yaml)
end
say "✅ config/cable.yml was updated to use the redis adapter in development"
Expand All @@ -44,24 +44,24 @@
end

if Rails::VERSION::MAJOR >= 7
add_gem "redis@~> 5"
CableReady::Installer.add_gem "redis@~> 5"
else
add_gem "redis@~> 4"
CableReady::Installer.add_gem "redis@~> 4"
end

# install action-cable-redis-backport gem if using Action Cable < 7.1
unless ActionCable::VERSION::MAJOR >= 7 && ActionCable::VERSION::MINOR >= 1
if !gemfile.match?(/gem ['"]action-cable-redis-backport['"]/)
add_gem "action-cable-redis-backport@~> 1"
if !CableReady::Installer.gemfile.match?(/gem ['"]action-cable-redis-backport['"]/)
CableReady::Installer.add_gem "action-cable-redis-backport@~> 1"
end
end

# verify that the Action Cable channels folder and consumer class is available
step_path = "/app/javascript/channels/"
channels_path = Rails.root.join(entrypoint, "channels")
consumer_src = fetch(step_path, "consumer.js.tt")
channels_path = Rails.root.join(CableReady::Installer.entrypoint, "channels")
consumer_src = CableReady::Installer.fetch(step_path, "consumer.js.tt")
consumer_path = channels_path / "consumer.js"
index_src = fetch(step_path, "index.js.#{bundler}.tt")
index_src = CableReady::Installer.fetch(step_path, "index.js.#{CableReady::Installer.bundler}.tt")
index_path = channels_path / "index.js"
friendly_index_path = index_path.relative_path_from(Rails.root).to_s

Expand All @@ -73,7 +73,7 @@
if index_path.read == index_src.read
say "✅ #{friendly_index_path} is present"
else
backup(index_path) do
CableReady::Installer.backup(index_path) do
copy_file(index_src, index_path, verbose: false)
end
say "✅ #{friendly_index_path} has been created"
Expand All @@ -85,43 +85,43 @@
# import Action Cable channels into application pack
channels_pattern = /import ['"](\.\.\/|\.\/)?channels['"]/
channels_commented_pattern = /\s*\/\/\s*#{channels_pattern}/
channel_import = "import \"#{prefix}channels\"\n"
channel_import = "import \"#{CableReady::Installer.prefix}channels\"\n"

if pack.match?(channels_pattern)
if pack.match?(channels_commented_pattern)
proceed = if options.key? "uncomment"
options["uncomment"]
if CableReady::Installer.pack.match?(channels_pattern)
if CableReady::Installer.pack.match?(channels_commented_pattern)
proceed = if CableReady::Installer.options.key? "uncomment"
CableReady::Installer.options["uncomment"]
else
!no?("✨ Action Cable seems to be commented out in your application.js. Do you want to uncomment it? (Y/n)")
end

if proceed
# uncomment_lines only works with Ruby comments 🙄
lines = pack_path.readlines
lines = CableReady::Installer.pack_path.readlines
matches = lines.select { |line| line =~ channels_commented_pattern }
lines[lines.index(matches.last).to_i] = channel_import
pack_path.write lines.join
say "✅ channels imported in #{friendly_pack_path}"
CableReady::Installer.pack_path.write lines.join
say "✅ channels imported in #{CableReady::Installer.friendly_pack_path}"
else
say "🤷 your Action Cable channels are not being imported in your application.js. We trust that you have a reason for this."
end
else
say "✅ channels imported in #{friendly_pack_path}"
say "✅ channels imported in #{CableReady::Installer.friendly_pack_path}"
end
else
lines = pack_path.readlines
lines = CableReady::Installer.pack_path.readlines
matches = lines.select { |line| line =~ /^import / }
lines.insert lines.index(matches.last).to_i + 1, channel_import
pack_path.write lines.join
say "✅ channels imported in #{friendly_pack_path}"
CableReady::Installer.pack_path.write lines.join
say "✅ channels imported in #{CableReady::Installer.friendly_pack_path}"
end

# create working copy of Action Cable initializer in tmp
if action_cable_initializer_path.exist?
FileUtils.cp(action_cable_initializer_path, action_cable_initializer_working_path)
if CableReady::Installer.action_cable_initializer_path.exist?
FileUtils.cp(CableReady::Installer.action_cable_initializer_path, CableReady::Installer.action_cable_initializer_working_path)
else
# create Action Cable initializer if it doesn't already exist
create_file(action_cable_initializer_working_path, verbose: false) do
create_file(CableReady::Installer.action_cable_initializer_working_path, verbose: false) do
<<~RUBY
# frozen_string_literal: true
Expand All @@ -131,8 +131,8 @@
end

# silence notoriously chatty Action Cable logs
if !action_cable_initializer_working_path.read.match?(/^[^#]*ActionCable.server.config.logger/)
append_file(action_cable_initializer_working_path, verbose: false) do
if !CableReady::Installer.action_cable_initializer_working_path.read.match?(/^[^#]*ActionCable.server.config.logger/)
append_file(CableReady::Installer.action_cable_initializer_working_path, verbose: false) do
<<~RUBY
ActionCable.server.config.logger = Logger.new(nil)
Expand All @@ -141,4 +141,4 @@
say "✅ Action Cable logger silenced for performance and legibility"
end

complete_step :action_cable
CableReady::Installer.complete_step :action_cable
26 changes: 13 additions & 13 deletions lib/install/broadcaster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

require "cable_ready/installer"

proceed = if options.key? "broadcaster"
options["broadcaster"]
proceed = if CableReady::Installer.options.key? "broadcaster"
CableReady::Installer.options["broadcaster"]
else
!no?("✨ Make CableReady::Broadcaster available to channels, controllers, jobs and models? (Y/n)")
end

unless proceed
complete_step :broadcaster
CableReady::Installer.complete_step :broadcaster

puts "⏩ Skipping."
return
Expand All @@ -20,7 +20,7 @@
if channel_path.exist?
lines = channel_path.readlines
if !lines.index { |line| line =~ /^\s*include CableReady::Broadcaster/ }
backup(channel_path) do
CableReady::Installer.backup(channel_path) do
index = lines.index { |line| line.include?("class Channel < ActionCable::Channel::Base") }
lines.insert index + 1, " include CableReady::Broadcaster\n"
channel_path.write lines.join
Expand All @@ -37,7 +37,7 @@
if controller_path.exist?
lines = controller_path.readlines
if !lines.index { |line| line =~ /^\s*include CableReady::Broadcaster/ }
backup(controller_path) do
CableReady::Installer.backup(controller_path) do
index = lines.index { |line| line.include?("class ApplicationController < ActionController::Base") }
lines.insert index + 1, " include CableReady::Broadcaster\n"
controller_path.write lines.join
Expand All @@ -55,7 +55,7 @@
if job_path.exist?
lines = job_path.readlines
if !lines.index { |line| line =~ /^\s*include CableReady::Broadcaster/ }
backup(job_path) do
CableReady::Installer.backup(job_path) do
index = lines.index { |line| line.include?("class ApplicationJob < ActiveJob::Base") }
lines.insert index + 1, " include CableReady::Broadcaster\n"
job_path.write lines.join
Expand All @@ -72,9 +72,9 @@

# include CableReady::Broadcaster in StateMachines, if present
if defined?(StateMachines)
lines = action_cable_initializer_working_path.read
lines = CableReady::Installer.action_cable_initializer_working_path.read
if !lines.include?("StateMachines::Machine.prepend(CableReady::Broadcaster)")
inject_into_file action_cable_initializer_working_path, after: "CableReady.configure do |config|\n", verbose: false do
inject_into_file CableReady::Installer.action_cable_initializer_working_path, after: "CableReady.configure do |config|\n", verbose: false do
<<-RUBY
StateMachines::Machine.prepend(CableReady::Broadcaster)
Expand All @@ -91,13 +91,13 @@
end

# include CableReady::Broadcaster in Active Record model classes
if Rails.root.join(application_record_path).exist?
lines = application_record_path.readlines
if Rails.root.join(CableReady::Installer.application_record_path).exist?
lines = CableReady::Installer.application_record_path.readlines
if !lines.index { |line| line =~ /^\s*include CableReady::Broadcaster/ }
backup(application_record_path) do
CableReady::Installer.backup(CableReady::Installer.application_record_path) do
index = lines.index { |line| line.include?("class ApplicationRecord < ActiveRecord::Base") }
lines.insert index + 1, " include CableReady::Broadcaster\n"
application_record_path.write lines.join
CableReady::Installer.application_record_path.write lines.join
end

puts "✅ include CableReady::Broadcaster in Active Record model classes"
Expand All @@ -106,4 +106,4 @@
end
end

complete_step :broadcaster
CableReady::Installer.complete_step :broadcaster
18 changes: 9 additions & 9 deletions lib/install/bundle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

require "cable_ready/installer"

hash = gemfile_hash
hash = CableReady::Installer.gemfile_hash

# run bundle only when gems are waiting to be added or removed
add = add_gem_list.exist? ? add_gem_list.readlines.map(&:chomp) : []
remove = remove_gem_list.exist? ? remove_gem_list.readlines.map(&:chomp) : []
add = CableReady::Installer.add_gem_list.exist? ? CableReady::Installer.add_gem_list.readlines.map(&:chomp) : []
remove = CableReady::Installer.remove_gem_list.exist? ? CableReady::Installer.remove_gem_list.readlines.map(&:chomp) : []

if add.present? || remove.present?
lines = gemfile_path.readlines
lines = CableReady::Installer.gemfile_path.readlines

remove.each do |name|
index = lines.index { |line| line =~ /gem ['"]#{name}['"]/ }
Expand Down Expand Up @@ -40,15 +40,15 @@
end
end

gemfile_path.write lines.join
CableReady::Installer.gemfile_path.write lines.join

bundle_command("install --quiet", "BUNDLE_IGNORE_MESSAGES" => "1") if hash != gemfile_hash
bundle_command("install --quiet", "BUNDLE_IGNORE_MESSAGES" => "1") if hash != CableReady::Installer.gemfile_hash
end

FileUtils.cp(development_working_path, development_path)
FileUtils.cp(CableReady::Installer.development_working_path, CableReady::Installer.development_path)
say "✅ development environment configuration installed"

FileUtils.cp(action_cable_initializer_working_path, action_cable_initializer_path)
FileUtils.cp(CableReady::Installer.action_cable_initializer_working_path, CableReady::Installer.action_cable_initializer_path)
say "✅ Action Cable initializer installed"

complete_step :bundle
CableReady::Installer.complete_step :bundle
14 changes: 7 additions & 7 deletions lib/install/compression.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@

require "cable_ready/installer"

initializer = action_cable_initializer_working_path.read
initializer = CableReady::Installer.action_cable_initializer_working_path.read

proceed = false

if initializer.exclude? "PermessageDeflate.configure"
proceed = if options.key? "compression"
options["compression"]
proceed = if CableReady::Installer.options.key? "compression"
CableReady::Installer.options["compression"]
else
!no?("✨ Configure Action Cable to compress your WebSocket traffic with gzip? (Y/n)")
end
end

if proceed
if !gemfile.match?(/gem ['"]permessage_deflate['"]/)
add_gem "permessage_deflate@>= 0.1"
if !CableReady::Installer.gemfile.match?(/gem ['"]permessage_deflate['"]/)
CableReady::Installer.add_gem "permessage_deflate@>= 0.1"
end

# add permessage_deflate config to Action Cable initializer
if initializer.exclude? "PermessageDeflate.configure"
create_or_append(action_cable_initializer_working_path, verbose: false) do
CableReady::Installer.create_or_append(CableReady::Installer.action_cable_initializer_working_path, verbose: false) do
<<~RUBY
module ActionCable
module Connection
Expand All @@ -48,4 +48,4 @@ def initialize(env, event_target, event_loop, protocols)
end
end

complete_step :compression
CableReady::Installer.complete_step :compression
34 changes: 17 additions & 17 deletions lib/install/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,38 @@

require "cable_ready/installer"

return if pack_path_missing?
return if CableReady::Installer.pack_path_missing?

step_path = "/app/javascript/config/"
index_src = fetch(step_path, "index.js.tt")
index_path = config_path / "index.js"
cable_ready_src = fetch(step_path, "cable_ready.js.tt")
cable_ready_path = config_path / "cable_ready.js"
index_src = CableReady::Installer.fetch(step_path, "index.js.tt")
index_path = CableReady::Installer.config_path / "index.js"
cable_ready_src = CableReady::Installer.fetch(step_path, "cable_ready.js.tt")
cable_ready_path = CableReady::Installer.config_path / "cable_ready.js"

empty_directory config_path unless config_path.exist?
empty_directory CableReady::Installer.config_path unless CableReady::Installer.config_path.exist?

copy_file(index_src, index_path) unless index_path.exist?
CableReady::Installer.copy_file(index_src, index_path) unless index_path.exist?

index_pattern = /import ['"](\.\.\/|\.\/)?config['"]/
index_commented_pattern = /\s*\/\/\s*#{index_pattern}/
index_import = "import \"#{prefix}config\"\n"
index_import = "import \"#{CableReady::Installer.prefix}config\"\n"

if pack.match?(index_pattern)
if pack.match?(index_commented_pattern)
lines = pack_path.readlines
if CableReady::Installer.pack.match?(index_pattern)
if CableReady::Installer.pack.match?(index_commented_pattern)
lines = CableReady::Installer.pack_path.readlines
matches = lines.select { |line| line =~ index_commented_pattern }
lines[lines.index(matches.last).to_i] = index_import
pack_path.write lines.join
CableReady::Installer.pack_path.write lines.join
end
else
lines = pack_path.readlines
lines = CableReady::Installer.pack_path.readlines
matches = lines.select { |line| line =~ /^import / }
lines.insert lines.index(matches.last).to_i + 1, index_import
pack_path.write lines.join
CableReady::Installer.pack_path.write lines.join
end
say "✅ CableReady configs will be imported in #{friendly_pack_path}"
say "✅ CableReady configs will be imported in #{CableReady::Installer.friendly_pack_path}"

# create entrypoint/config/cable_ready.js and make sure it's imported in application.js
copy_file(cable_ready_src, cable_ready_path) unless cable_ready_path.exist?
CableReady::Installer.copy_file(cable_ready_src, cable_ready_path) unless cable_ready_path.exist?

complete_step :config
CableReady::Installer.complete_step :config
12 changes: 6 additions & 6 deletions lib/install/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@
require "cable_ready/installer"

# mutate working copy of development.rb to avoid bundle alerts
FileUtils.cp(development_path, development_working_path)
FileUtils.cp(CableReady::Installer.development_path, CableReady::Installer.development_working_path)

# add default_url_options to development.rb for Action Mailer
if defined?(ActionMailer)
lines = development_working_path.readlines
lines = CableReady::Installer.development_working_path.readlines
if lines.find { |line| line.include?("config.action_mailer.default_url_options") }
say "⏩ Action Mailer default_url_options already defined. Skipping."
else
index = lines.index { |line| line =~ /^Rails.application.configure do/ }
lines.insert index + 1, " config.action_mailer.default_url_options = {host: \"localhost\", port: 3000}\n\n"
development_working_path.write lines.join
CableReady::Installer.development_working_path.write lines.join

say "✅ Action Mailer default_url_options defined"
end
end

# add default_url_options to development.rb for Action Controller
lines = development_working_path.readlines
lines = CableReady::Installer.development_working_path.readlines
if lines.find { |line| line.include?("config.action_controller.default_url_options") }
say "⏩ Action Controller default_url_options already defined. Skipping."
else
index = lines.index { |line| line =~ /^Rails.application.configure do/ }
lines.insert index + 1, " config.action_controller.default_url_options = {host: \"localhost\", port: 3000}\n"
development_working_path.write lines.join
CableReady::Installer.development_working_path.write lines.join

say "✅ Action Controller default_url_options defined"
end

complete_step :development
CableReady::Installer.complete_step :development
Loading

0 comments on commit a87a16e

Please sign in to comment.