cable_ready 5.0.0.pre9 → 5.0.0.pre10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +4 -1
- data/Gemfile.lock +119 -100
- data/README.md +2 -5
- data/app/assets/javascripts/cable_ready.js +457 -151
- data/app/assets/javascripts/cable_ready.min.js +1 -1
- data/app/assets/javascripts/cable_ready.min.js.map +1 -1
- data/app/assets/javascripts/cable_ready.umd.js +441 -165
- data/app/assets/javascripts/cable_ready.umd.min.js +1 -1
- data/app/assets/javascripts/cable_ready.umd.min.js.map +1 -1
- data/app/channels/cable_ready/stream.rb +7 -5
- data/app/helpers/cable_ready/view_helper.rb +58 -0
- data/app/jobs/cable_ready_broadcast_job.rb +9 -8
- data/app/models/concerns/cable_ready/updatable/collection_updatable_callbacks.rb +2 -0
- data/app/models/concerns/cable_ready/updatable/collections_registry.rb +2 -0
- data/app/models/concerns/cable_ready/updatable/model_updatable_callbacks.rb +5 -2
- data/app/models/concerns/cable_ready/updatable.rb +67 -19
- data/app/models/concerns/extend_has_many.rb +2 -0
- data/cable_ready.gemspec +4 -6
- data/lib/cable_ready/broadcaster.rb +2 -0
- data/lib/cable_ready/cable_car.rb +2 -0
- data/lib/cable_ready/channel.rb +12 -4
- data/lib/cable_ready/channels.rb +3 -1
- data/lib/cable_ready/config.rb +16 -2
- data/lib/cable_ready/engine.rb +19 -9
- data/lib/cable_ready/identifiable.rb +23 -5
- data/lib/cable_ready/importmap.rb +2 -0
- data/lib/cable_ready/installer.rb +224 -0
- data/lib/cable_ready/operation_builder.rb +1 -1
- data/lib/cable_ready/sanity_checker.rb +1 -31
- data/lib/cable_ready/version.rb +1 -1
- data/lib/cable_ready.rb +3 -8
- data/lib/cable_ready_helper.rb +13 -0
- data/lib/generators/cable_ready/channel_generator.rb +51 -12
- data/lib/generators/cable_ready/templates/config/initializers/cable_ready.rb +10 -6
- data/lib/install/action_cable.rb +144 -0
- data/lib/install/broadcaster.rb +109 -0
- data/lib/install/bundle.rb +54 -0
- data/lib/install/compression.rb +51 -0
- data/lib/install/config.rb +39 -0
- data/lib/install/development.rb +34 -0
- data/lib/install/esbuild.rb +101 -0
- data/lib/install/importmap.rb +96 -0
- data/lib/install/initializers.rb +15 -0
- data/lib/install/mrujs.rb +121 -0
- data/lib/install/npm_packages.rb +13 -0
- data/lib/install/shakapacker.rb +61 -0
- data/lib/install/spring.rb +54 -0
- data/lib/install/updatable.rb +34 -0
- data/lib/install/vite.rb +62 -0
- data/lib/install/webpacker.rb +81 -0
- data/lib/install/yarn.rb +56 -0
- data/lib/tasks/cable_ready/cable_ready.rake +249 -0
- data/package.json +28 -18
- data/{rollup.config.js → rollup.config.mjs} +9 -8
- data/web-test-runner.config.mjs +12 -0
- data/yarn.lock +2210 -404
- metadata +37 -161
- data/LATEST +0 -1
- data/app/helpers/cable_ready_helper.rb +0 -26
- data/lib/generators/cable_ready/helpers_generator.rb +0 -43
- data/lib/generators/cable_ready/initializer_generator.rb +0 -14
- data/test/dummy/app/channels/application_cable/channel.rb +0 -4
- data/test/dummy/app/channels/application_cable/connection.rb +0 -4
- data/test/dummy/app/controllers/application_controller.rb +0 -2
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/jobs/application_job.rb +0 -7
- data/test/dummy/app/mailers/application_mailer.rb +0 -4
- data/test/dummy/app/models/application_record.rb +0 -3
- data/test/dummy/app/models/dugong.rb +0 -4
- data/test/dummy/app/models/global_idable_entity.rb +0 -16
- data/test/dummy/app/models/post.rb +0 -4
- data/test/dummy/app/models/section.rb +0 -6
- data/test/dummy/app/models/team.rb +0 -6
- data/test/dummy/app/models/topic.rb +0 -4
- data/test/dummy/app/models/user.rb +0 -7
- data/test/dummy/config/application.rb +0 -22
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -76
- data/test/dummy/config/environments/production.rb +0 -120
- data/test/dummy/config/environments/test.rb +0 -59
- data/test/dummy/config/initializers/application_controller_renderer.rb +0 -8
- data/test/dummy/config/initializers/assets.rb +0 -12
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -8
- data/test/dummy/config/initializers/cable_ready.rb +0 -18
- data/test/dummy/config/initializers/content_security_policy.rb +0 -28
- data/test/dummy/config/initializers/cookies_serializer.rb +0 -5
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -6
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -4
- data/test/dummy/config/initializers/permissions_policy.rb +0 -11
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/puma.rb +0 -43
- data/test/dummy/config/routes.rb +0 -3
- data/test/dummy/db/migrate/20210902154139_create_users.rb +0 -9
- data/test/dummy/db/migrate/20210902154153_create_posts.rb +0 -10
- data/test/dummy/db/migrate/20210904081930_create_topics.rb +0 -9
- data/test/dummy/db/migrate/20210904093607_create_sections.rb +0 -9
- data/test/dummy/db/migrate/20210913191735_create_teams.rb +0 -8
- data/test/dummy/db/migrate/20210913191759_add_team_reference_to_users.rb +0 -5
- data/test/dummy/db/migrate/20220329222959_create_dugongs.rb +0 -8
- data/test/dummy/db/migrate/20220329230221_create_active_storage_tables.active_storage.rb +0 -36
- data/test/dummy/db/schema.rb +0 -84
- data/test/dummy/test/models/dugong_test.rb +0 -7
- data/test/dummy/test/models/post_test.rb +0 -7
- data/test/dummy/test/models/section_test.rb +0 -7
- data/test/dummy/test/models/team_test.rb +0 -7
- data/test/dummy/test/models/topic_test.rb +0 -7
- data/test/dummy/test/models/user_test.rb +0 -7
- data/test/lib/cable_ready/cable_car_test.rb +0 -50
- data/test/lib/cable_ready/compoundable_test.rb +0 -26
- data/test/lib/cable_ready/helper_test.rb +0 -25
- data/test/lib/cable_ready/identifiable_test.rb +0 -69
- data/test/lib/cable_ready/operation_builder_test.rb +0 -189
- data/test/lib/cable_ready/updatable_test.rb +0 -135
- data/test/lib/generators/cable_ready/channel_generator_test.rb +0 -157
- data/test/support/generator_test_helpers.rb +0 -28
- data/test/test_helper.rb +0 -18
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
return if pack_path_missing?
|
|
6
|
+
|
|
7
|
+
# verify that all critical dependencies are up to date; if not, queue for later
|
|
8
|
+
lines = package_json.readlines
|
|
9
|
+
|
|
10
|
+
if !lines.index { |line| line =~ /^\s*["']esbuild-rails["']: ["']\^1.0.3["']/ }
|
|
11
|
+
add_package "esbuild-rails@^1.0.3"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
if !lines.index { |line| line =~ /^\s*["']@hotwired\/stimulus["']:/ }
|
|
15
|
+
add_package "@hotwired/stimulus@^3.2"
|
|
16
|
+
end
|
|
17
|
+
# copy esbuild.config.mjs to app root
|
|
18
|
+
esbuild_src = fetch("/", "esbuild.config.mjs.tt")
|
|
19
|
+
esbuild_path = Rails.root.join("esbuild.config.mjs")
|
|
20
|
+
if esbuild_path.exist?
|
|
21
|
+
if esbuild_path.read == esbuild_src.read
|
|
22
|
+
say "✅ esbuild.config.mjs present in app root"
|
|
23
|
+
else
|
|
24
|
+
backup(esbuild_path) do
|
|
25
|
+
template(esbuild_src, esbuild_path, verbose: false, entrypoint: entrypoint)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
template(esbuild_src, esbuild_path, entrypoint: entrypoint)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
step_path = "/app/javascript/controllers/"
|
|
33
|
+
application_js_src = fetch(step_path, "application.js.tt")
|
|
34
|
+
application_js_path = controllers_path / "application.js"
|
|
35
|
+
index_src = fetch(step_path, "index.js.esbuild.tt")
|
|
36
|
+
index_path = controllers_path / "index.js"
|
|
37
|
+
friendly_index_path = index_path.relative_path_from(Rails.root).to_s
|
|
38
|
+
|
|
39
|
+
# create entrypoint/controllers, if necessary
|
|
40
|
+
empty_directory controllers_path unless controllers_path.exist?
|
|
41
|
+
|
|
42
|
+
# configure Stimulus application superclass to import Action Cable consumer
|
|
43
|
+
friendly_application_js_path = application_js_path.relative_path_from(Rails.root).to_s
|
|
44
|
+
if application_js_path.exist?
|
|
45
|
+
backup(application_js_path) do
|
|
46
|
+
if application_js_path.read.include?("import consumer")
|
|
47
|
+
say "✅ #{friendly_application_js_path} is present"
|
|
48
|
+
else
|
|
49
|
+
inject_into_file application_js_path, "import consumer from \"../channels/consumer\"\n", after: "import { Application } from \"@hotwired/stimulus\"\n", verbose: false
|
|
50
|
+
inject_into_file application_js_path, "application.consumer = consumer\n", after: "application.debug = false\n", verbose: false
|
|
51
|
+
say "✅ #{friendly_application_js_path} has been updated to import the Action Cable consumer"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
copy_file(application_js_src, application_js_path)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if index_path.exist?
|
|
59
|
+
if index_path.read != index_src.read
|
|
60
|
+
backup(index_path, delete: true) do
|
|
61
|
+
copy_file(index_src, index_path, verbose: false)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
else
|
|
65
|
+
copy_file(index_src, index_path)
|
|
66
|
+
end
|
|
67
|
+
say "✅ #{friendly_index_path} has been created"
|
|
68
|
+
|
|
69
|
+
controllers_pattern = /import ['"].\/controllers['"]/
|
|
70
|
+
controllers_commented_pattern = /\s*\/\/\s*#{controllers_pattern}/
|
|
71
|
+
|
|
72
|
+
if pack.match?(controllers_pattern)
|
|
73
|
+
if pack.match?(controllers_commented_pattern)
|
|
74
|
+
proceed = if options.key? "uncomment"
|
|
75
|
+
options["uncomment"]
|
|
76
|
+
else
|
|
77
|
+
!no?("✨ Stimulus seems to be commented out in your application.js. Do you want to import your controllers? (Y/n)")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if proceed
|
|
81
|
+
# uncomment_lines only works with Ruby comments 🙄
|
|
82
|
+
lines = pack_path.readlines
|
|
83
|
+
matches = lines.select { |line| line =~ controllers_commented_pattern }
|
|
84
|
+
lines[lines.index(matches.last).to_i] = "import \".\/controllers\"\n" # standard:disable Style/RedundantStringEscape
|
|
85
|
+
pack_path.write lines.join
|
|
86
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
87
|
+
else
|
|
88
|
+
say "🤷 your Stimulus controllers are not being imported in your application.js. We trust that you have a reason for this."
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
92
|
+
end
|
|
93
|
+
else
|
|
94
|
+
lines = pack_path.readlines
|
|
95
|
+
matches = lines.select { |line| line =~ /^import / }
|
|
96
|
+
lines.insert lines.index(matches.last).to_i + 1, "import \".\/controllers\"\n" # standard:disable Style/RedundantStringEscape
|
|
97
|
+
pack_path.write lines.join
|
|
98
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
complete_step :esbuild
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
return if pack_path_missing?
|
|
6
|
+
|
|
7
|
+
if !importmap_path.exist?
|
|
8
|
+
halt "#{friendly_importmap_path} is missing. You need a valid importmap config file to proceed."
|
|
9
|
+
return
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
importmap = importmap_path.read
|
|
13
|
+
|
|
14
|
+
backup(importmap_path) do
|
|
15
|
+
if !importmap.include?("pin_all_from \"#{entrypoint}/controllers\"")
|
|
16
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
17
|
+
pin_all_from "#{entrypoint}/controllers", under: "controllers"
|
|
18
|
+
RUBY
|
|
19
|
+
say "✅ pin controllers folder"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if !importmap.include?("pin_all_from \"#{entrypoint}/channels\"")
|
|
23
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
24
|
+
pin_all_from "#{entrypoint}/channels", under: "channels"
|
|
25
|
+
RUBY
|
|
26
|
+
say "✅ pin channels folder"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if !importmap.include?("pin_all_from \"#{entrypoint}/config\"")
|
|
30
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
31
|
+
pin_all_from "#{entrypoint}/config", under: "config"
|
|
32
|
+
RUBY
|
|
33
|
+
say "✅ pin config folder"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if !importmap.include?("pin \"@rails/actioncable\"")
|
|
37
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
38
|
+
pin "@rails/actioncable", to: "actioncable.esm.js", preload: true
|
|
39
|
+
RUBY
|
|
40
|
+
say "✅ pin Action Cable"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if !importmap.include?("pin \"cable_ready\"")
|
|
44
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
45
|
+
pin "cable_ready", to: "cable_ready.min.js", preload: true
|
|
46
|
+
RUBY
|
|
47
|
+
say "✅ pin CableReady"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if !importmap.include?("pin \"morphdom\"")
|
|
51
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
52
|
+
pin "morphdom", to: "https://ga.jspm.io/npm:morphdom@2.6.1/dist/morphdom.js", preload: true
|
|
53
|
+
RUBY
|
|
54
|
+
say "✅ pin morphdom"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
application_js_src = fetch("/", "app/javascript/controllers/application.js.tt")
|
|
59
|
+
application_js_path = controllers_path / "application.js"
|
|
60
|
+
index_src = fetch("/", "app/javascript/controllers/index.js.importmap.tt")
|
|
61
|
+
index_path = controllers_path / "index.js"
|
|
62
|
+
|
|
63
|
+
# create entrypoint/controllers, as well as the index, application and application_controller
|
|
64
|
+
empty_directory controllers_path unless controllers_path.exist?
|
|
65
|
+
|
|
66
|
+
# configure Stimulus application superclass to import Action Cable consumer
|
|
67
|
+
backup(application_js_path) do
|
|
68
|
+
if application_js_path.exist?
|
|
69
|
+
friendly_application_js_path = application_js_path.relative_path_from(Rails.root).to_s
|
|
70
|
+
if application_js_path.read.include?("import consumer")
|
|
71
|
+
say "✅ #{friendly_application_js_path} is present"
|
|
72
|
+
else
|
|
73
|
+
inject_into_file application_js_path, "import consumer from \"../channels/consumer\"\n", after: "import { Application } from \"@hotwired/stimulus\"\n", verbose: false
|
|
74
|
+
inject_into_file application_js_path, "application.consumer = consumer\n", after: "application.debug = false\n", verbose: false
|
|
75
|
+
say "✅ #{friendly_application_js_path} has been updated to import the Action Cable consumer"
|
|
76
|
+
end
|
|
77
|
+
else
|
|
78
|
+
copy_file(application_js_src, application_js_path)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
if index_path.exist?
|
|
83
|
+
friendly_index_path = index_path.relative_path_from(Rails.root).to_s
|
|
84
|
+
if index_path.read == index_src.read
|
|
85
|
+
say "✅ #{friendly_index_path} is present"
|
|
86
|
+
else
|
|
87
|
+
backup(index_path, delete: true) do
|
|
88
|
+
copy_file(index_src, index_path, verbose: false)
|
|
89
|
+
end
|
|
90
|
+
say "✅ #{friendly_index_path} has been created"
|
|
91
|
+
end
|
|
92
|
+
else
|
|
93
|
+
copy_file(index_src, index_path)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
complete_step :importmap
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
cr_initializer_src = fetch("/", "config/initializers/cable_ready.rb")
|
|
6
|
+
cr_initializer_path = Rails.root.join("config/initializers/cable_ready.rb")
|
|
7
|
+
|
|
8
|
+
if !cr_initializer_path.exist?
|
|
9
|
+
copy_file(cr_initializer_src, cr_initializer_path, verbose: false)
|
|
10
|
+
say "✅ CableReady initializer created at config/initializers/cable_ready.rb"
|
|
11
|
+
else
|
|
12
|
+
say "⏩ config/initializers/cable_ready.rb already exists. Skipping."
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
complete_step :initializers
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
return if pack_path_missing?
|
|
6
|
+
|
|
7
|
+
mrujs_path = config_path / "mrujs.js"
|
|
8
|
+
|
|
9
|
+
proceed = false
|
|
10
|
+
|
|
11
|
+
if !File.exist?(mrujs_path)
|
|
12
|
+
proceed = if options.key? "mrujs"
|
|
13
|
+
options["mrujs"]
|
|
14
|
+
else
|
|
15
|
+
!no?("✨ Would you like to install and enable mrujs? It's a modern, drop-in replacement for rails-ujs (Y/n)")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if proceed
|
|
20
|
+
if bundler == "importmap"
|
|
21
|
+
|
|
22
|
+
if !importmap_path.exist?
|
|
23
|
+
halt "#{friendly_importmap_path} is missing. You need a valid importmap config file to proceed."
|
|
24
|
+
return
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
importmap = importmap_path.read
|
|
28
|
+
|
|
29
|
+
if !importmap.include?("pin \"mrujs\"")
|
|
30
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
31
|
+
pin "mrujs", to: "https://ga.jspm.io/npm:mrujs@0.10.1/dist/index.module.js"
|
|
32
|
+
RUBY
|
|
33
|
+
say "✅ pin mrujs"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if !importmap.include?("pin \"mrujs/plugins\"")
|
|
37
|
+
append_file(importmap_path, <<~RUBY, verbose: false)
|
|
38
|
+
pin "mrujs/plugins", to: "https://ga.jspm.io/npm:mrujs@0.10.1/plugins/dist/plugins.module.js"
|
|
39
|
+
RUBY
|
|
40
|
+
say "✅ pin mrujs plugins"
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
# queue mrujs for installation
|
|
44
|
+
if !package_json.read.include?('"mrujs":')
|
|
45
|
+
add_package "mrujs@^0.10.1"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# queue @rails/ujs for removal
|
|
49
|
+
if package_json.read.include?('"@rails/ujs":')
|
|
50
|
+
drop_package "@rails/ujs"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
step_path = "/app/javascript/config/"
|
|
55
|
+
mrujs_src = fetch(step_path, "mrujs.js.tt")
|
|
56
|
+
|
|
57
|
+
# create entrypoint/config/mrujs.js if necessary
|
|
58
|
+
copy_file(mrujs_src, mrujs_path) unless mrujs_path.exist?
|
|
59
|
+
|
|
60
|
+
# import mrujs config in entrypoint/config/index.js
|
|
61
|
+
index_path = config_path / "index.js"
|
|
62
|
+
index = index_path.read
|
|
63
|
+
friendly_index_path = index_path.relative_path_from(Rails.root).to_s
|
|
64
|
+
mrujs_pattern = /import ['"].\/mrujs['"]/
|
|
65
|
+
mrujs_import = "import '.\/mrujs'\n" # standard:disable Style/RedundantStringEscape
|
|
66
|
+
|
|
67
|
+
if !index.match?(mrujs_pattern)
|
|
68
|
+
append_file(index_path, mrujs_import, verbose: false)
|
|
69
|
+
end
|
|
70
|
+
say "✅ mrujs imported in #{friendly_index_path}"
|
|
71
|
+
|
|
72
|
+
# remove @rails/ujs from application.js
|
|
73
|
+
rails_ujs_pattern = /import Rails from ['"]@rails\/ujs['"]/
|
|
74
|
+
|
|
75
|
+
lines = pack_path.readlines
|
|
76
|
+
if lines.index { |line| line =~ rails_ujs_pattern }
|
|
77
|
+
gsub_file pack_path, rails_ujs_pattern, "", verbose: false
|
|
78
|
+
say "✅ @rails/ujs removed from #{friendly_pack_path}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# set Action View to generate remote forms when using form_with
|
|
82
|
+
application_path = Rails.root.join("config/application.rb")
|
|
83
|
+
application_pattern = /^[^#]*config\.action_view\.form_with_generates_remote_forms = true/
|
|
84
|
+
defaults_pattern = /config\.load_defaults \d\.\d/
|
|
85
|
+
|
|
86
|
+
lines = application_path.readlines
|
|
87
|
+
backup(application_path) do
|
|
88
|
+
if !lines.index { |line| line =~ application_pattern }
|
|
89
|
+
if (index = lines.index { |line| line =~ /^[^#]*#{defaults_pattern}/ })
|
|
90
|
+
gsub_file application_path, /\s*#{defaults_pattern}\n/, verbose: false do
|
|
91
|
+
<<-RUBY
|
|
92
|
+
\n#{lines[index]}
|
|
93
|
+
# form_with helper will generate remote forms by default (mrujs)
|
|
94
|
+
config.action_view.form_with_generates_remote_forms = true
|
|
95
|
+
RUBY
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
insert_into_file application_path, after: "class Application < Rails::Application" do
|
|
99
|
+
<<-RUBY
|
|
100
|
+
|
|
101
|
+
# form_with helper will generate remote forms by default (mrujs)
|
|
102
|
+
config.action_view.form_with_generates_remote_forms = true
|
|
103
|
+
RUBY
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
say "✅ form_with_generates_remote_forms set to true in config/application.rb"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# remove turbolinks from Gemfile because it's incompatible with mrujs (and unnecessary)
|
|
111
|
+
turbolinks_pattern = /^[^#]*gem ["']turbolinks["']/
|
|
112
|
+
|
|
113
|
+
lines = gemfile_path.readlines
|
|
114
|
+
if lines.index { |line| line =~ turbolinks_pattern }
|
|
115
|
+
remove_gem :turbolinks
|
|
116
|
+
else
|
|
117
|
+
say "✅ turbolinks is not present in Gemfile"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
complete_step :mrujs
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
lines = package_json.readlines
|
|
6
|
+
|
|
7
|
+
if !lines.index { |line| line =~ /^\s*["']cable_ready["']: ["'].*#{cr_npm_version}["']/ }
|
|
8
|
+
add_package "cable_ready@#{cr_npm_version}"
|
|
9
|
+
else
|
|
10
|
+
say "⏩ cable_ready npm package is already present"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
complete_step :npm_packages
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
return if pack_path_missing?
|
|
6
|
+
|
|
7
|
+
# verify that all critical dependencies are up to date; if not, queue for later
|
|
8
|
+
lines = package_json.readlines
|
|
9
|
+
if !lines.index { |line| line =~ /^\s*["']@hotwired\/stimulus["']:/ }
|
|
10
|
+
add_package "@hotwired/stimulus@^3.2"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if !lines.index { |line| line =~ /^\s*["']@hotwired\/stimulus-webpack-helpers["']: ["']\^1.0.1["']/ }
|
|
14
|
+
add_package "@hotwired/stimulus-webpack-helpers@^1.0.1"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
step_path = "/app/javascript/controllers/"
|
|
18
|
+
application_js_src = fetch(step_path, "application.js.tt")
|
|
19
|
+
application_js_path = controllers_path / "application.js"
|
|
20
|
+
index_src = fetch(step_path, "index.js.shakapacker.tt")
|
|
21
|
+
index_path = controllers_path / "index.js"
|
|
22
|
+
|
|
23
|
+
# create entrypoint/controllers, as well as the index, application and application_controller
|
|
24
|
+
empty_directory controllers_path unless controllers_path.exist?
|
|
25
|
+
|
|
26
|
+
copy_file(application_js_src, application_js_path) unless application_js_path.exist?
|
|
27
|
+
copy_file(index_src, index_path) unless index_path.exist?
|
|
28
|
+
|
|
29
|
+
controllers_pattern = /import ['"]controllers['"]/
|
|
30
|
+
controllers_commented_pattern = /\s*\/\/\s*#{controllers_pattern}/
|
|
31
|
+
|
|
32
|
+
if pack.match?(controllers_pattern)
|
|
33
|
+
if pack.match?(controllers_commented_pattern)
|
|
34
|
+
proceed = if options.key? "uncomment"
|
|
35
|
+
options["uncomment"]
|
|
36
|
+
else
|
|
37
|
+
!no?("✨ Do you want to import your Stimulus controllers in application.js? (Y/n)")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if proceed
|
|
41
|
+
# uncomment_lines only works with Ruby comments 🙄
|
|
42
|
+
lines = pack_path.readlines
|
|
43
|
+
matches = lines.select { |line| line =~ controllers_commented_pattern }
|
|
44
|
+
lines[lines.index(matches.last).to_i] = "import \"controllers\"\n"
|
|
45
|
+
pack_path.write lines.join
|
|
46
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
47
|
+
else
|
|
48
|
+
say "🤷 your Stimulus controllers are not being imported in your application.js. We trust that you have a reason for this."
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
lines = pack_path.readlines
|
|
55
|
+
matches = lines.select { |line| line =~ /^import / }
|
|
56
|
+
lines.insert lines.index(matches.last).to_i + 1, "import \"controllers\"\n"
|
|
57
|
+
pack_path.write lines.join
|
|
58
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
complete_step :shakapacker
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
spring_pattern = /^[^#]*gem ["']spring["']/
|
|
6
|
+
|
|
7
|
+
proceed = false
|
|
8
|
+
lines = gemfile_path.readlines
|
|
9
|
+
|
|
10
|
+
if lines.index { |line| line =~ spring_pattern }
|
|
11
|
+
proceed = if options.key? "spring"
|
|
12
|
+
options["spring"]
|
|
13
|
+
else
|
|
14
|
+
!no?("✨ Would you like to disable the spring gem? \nIt's been removed from Rails 7, and is the frequent culprit behind countless mystery bugs. (Y/n)")
|
|
15
|
+
end
|
|
16
|
+
else
|
|
17
|
+
say "⏩ Spring is not installed."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
if proceed
|
|
21
|
+
spring_watcher_pattern = /^[^#]*gem ["']spring-watcher-listen["']/
|
|
22
|
+
bin_rails_pattern = /^[^#]*load File.expand_path\("spring", __dir__\)/
|
|
23
|
+
|
|
24
|
+
if (index = lines.index { |line| line =~ spring_pattern })
|
|
25
|
+
remove_gem :spring
|
|
26
|
+
|
|
27
|
+
bin_spring = Rails.root.join("bin/spring")
|
|
28
|
+
if bin_spring.exist?
|
|
29
|
+
run "bin/spring binstub --remove --all"
|
|
30
|
+
say "✅ Removed spring binstubs"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
bin_rails = Rails.root.join("bin/rails")
|
|
34
|
+
bin_rails_content = bin_rails.readlines
|
|
35
|
+
if (index = bin_rails_content.index { |line| line =~ bin_rails_pattern })
|
|
36
|
+
backup(bin_rails) do
|
|
37
|
+
bin_rails_content[index] = "# #{bin_rails_content[index]}"
|
|
38
|
+
bin_rails.write bin_rails_content.join
|
|
39
|
+
end
|
|
40
|
+
say "✅ Removed spring from bin/rails"
|
|
41
|
+
end
|
|
42
|
+
create_file "tmp/cable_ready_installer/kill_spring", verbose: false
|
|
43
|
+
else
|
|
44
|
+
say "✅ spring has been successfully removed"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if lines.index { |line| line =~ spring_watcher_pattern }
|
|
48
|
+
remove_gem "spring-watcher-listen"
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
say "⏩ Skipping."
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
complete_step :spring
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
if application_record_path.exist?
|
|
6
|
+
lines = application_record_path.readlines
|
|
7
|
+
|
|
8
|
+
if !lines.index { |line| line =~ /^\s*include CableReady::Updatable/ }
|
|
9
|
+
proceed = if options.key? "updatable"
|
|
10
|
+
options["updatable"]
|
|
11
|
+
else
|
|
12
|
+
!no?("✨ Include CableReady::Updatable in Active Record model classes? (Y/n)")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
unless proceed
|
|
16
|
+
complete_step :updatable
|
|
17
|
+
|
|
18
|
+
puts "⏩ Skipping."
|
|
19
|
+
return
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
index = lines.index { |line| line.include?("class ApplicationRecord < ActiveRecord::Base") }
|
|
23
|
+
lines.insert index + 1, " include CableReady::Updatable\n"
|
|
24
|
+
application_record_path.write lines.join
|
|
25
|
+
|
|
26
|
+
say "✅ included CableReady::Updatable in ApplicationRecord"
|
|
27
|
+
else
|
|
28
|
+
say "⏩ CableReady::Updatable has already been included in Active Record model classes. Skipping."
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
say "⏩ ApplicationRecord doesn't exist. Skipping."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
complete_step :updatable
|
data/lib/install/vite.rb
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
return if pack_path_missing?
|
|
6
|
+
|
|
7
|
+
# verify that all critical dependencies are up to date; if not, queue for later
|
|
8
|
+
lines = package_json.readlines
|
|
9
|
+
if !lines.index { |line| line =~ /^\s*["']@hotwired\/stimulus["']:/ }
|
|
10
|
+
add_package "@hotwired/stimulus@^3.2"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if !lines.index { |line| line =~ /^\s*["']stimulus-vite-helpers["']: ["']\^3["']/ }
|
|
14
|
+
add_package "stimulus-vite-helpers@^3"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
step_path = "/app/javascript/controllers/"
|
|
18
|
+
application_js_src = fetch(step_path, "application.js.tt")
|
|
19
|
+
application_js_path = controllers_path / "application.js"
|
|
20
|
+
index_src = fetch(step_path, "index.js.vite.tt")
|
|
21
|
+
index_path = controllers_path / "index.js"
|
|
22
|
+
|
|
23
|
+
# create entrypoint/controllers, as well as the index, application and application_controller
|
|
24
|
+
empty_directory controllers_path unless controllers_path.exist?
|
|
25
|
+
|
|
26
|
+
copy_file(application_js_src, application_js_path) unless application_js_path.exist?
|
|
27
|
+
copy_file(index_src, index_path) unless index_path.exist?
|
|
28
|
+
|
|
29
|
+
controllers_pattern = /import ['"](\.\.\/)?controllers['"]/
|
|
30
|
+
controllers_commented_pattern = /\s*\/\/\s*#{controllers_pattern}/
|
|
31
|
+
prefix = "..\/" # standard:disable Style/RedundantStringEscape
|
|
32
|
+
|
|
33
|
+
if pack.match?(controllers_pattern)
|
|
34
|
+
if pack.match?(controllers_commented_pattern)
|
|
35
|
+
proceed = if options.key? "uncomment"
|
|
36
|
+
options["uncomment"]
|
|
37
|
+
else
|
|
38
|
+
!no?("✨ Do you want to import your Stimulus controllers in application.js? (Y/n)")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if proceed
|
|
42
|
+
# uncomment_lines only works with Ruby comments 🙄
|
|
43
|
+
lines = pack_path.readlines
|
|
44
|
+
matches = lines.select { |line| line =~ controllers_commented_pattern }
|
|
45
|
+
lines[lines.index(matches.last).to_i] = "import \"#{prefix}controllers\"\n"
|
|
46
|
+
pack_path.write lines.join
|
|
47
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
48
|
+
else
|
|
49
|
+
say "🤷 your Stimulus controllers are not being imported in your application.js. We trust that you have a reason for this."
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
lines = pack_path.readlines
|
|
56
|
+
matches = lines.select { |line| line =~ /^import / }
|
|
57
|
+
lines.insert lines.index(matches.last).to_i + 1, "import \"#{prefix}controllers\"\n"
|
|
58
|
+
pack_path.write lines.join
|
|
59
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
complete_step :vite
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cable_ready/installer"
|
|
4
|
+
|
|
5
|
+
return if pack_path_missing?
|
|
6
|
+
|
|
7
|
+
# verify that all critical dependencies are up to date; if not, queue for later
|
|
8
|
+
lines = package_json.readlines
|
|
9
|
+
if !lines.index { |line| line =~ /^\s*["']webpack["']: ["']\^4.46.0["']/ }
|
|
10
|
+
add_package "webpack@^4.46.0"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if !lines.index { |line| line =~ /^\s*["']webpack-cli["']: ["']\^3.3.12["']/ }
|
|
14
|
+
add_package "webpack-cli@^3.3.12"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if !lines.index { |line| line =~ /^\s*["']@rails\/webpacker["']: ["']\^5.4.3["']/ }
|
|
18
|
+
add_package "@rails/webpacker@^5.4.3"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if !lines.index { |line| line =~ /^\s*["']@hotwired\/stimulus["']:/ }
|
|
22
|
+
add_package "@hotwired/stimulus@^3.2"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if !lines.index { |line| line =~ /^\s*["']@hotwired\/stimulus-webpack-helpers["']: ["']\^1.0.1["']/ }
|
|
26
|
+
add_package "@hotwired/stimulus-webpack-helpers@^1.0.1"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if !lines.index { |line| line =~ /^\s*["']webpack-dev-server["']: ["']\^3.11.3["']/ }
|
|
30
|
+
add_dev_package "webpack-dev-server@^3.11.3"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
step_path = "/app/javascript/controllers/"
|
|
34
|
+
application_js_src = fetch(step_path, "application.js.tt")
|
|
35
|
+
application_js_path = controllers_path / "application.js"
|
|
36
|
+
index_src = fetch(step_path, "index.js.webpacker.tt")
|
|
37
|
+
index_path = controllers_path / "index.js"
|
|
38
|
+
|
|
39
|
+
# create entrypoint/controllers, as well as the index, application and application_controller
|
|
40
|
+
empty_directory controllers_path unless controllers_path.exist?
|
|
41
|
+
|
|
42
|
+
# webpacker 5.4 did not colloquially feature a controllers/application.js file
|
|
43
|
+
copy_file(application_js_src, application_js_path) unless application_js_path.exist?
|
|
44
|
+
copy_file(index_src, index_path) unless index_path.exist?
|
|
45
|
+
|
|
46
|
+
controllers_pattern = /import ['"]controllers['"]/
|
|
47
|
+
controllers_commented_pattern = /\s*\/\/\s*#{controllers_pattern}/
|
|
48
|
+
|
|
49
|
+
if pack.match?(controllers_pattern)
|
|
50
|
+
if pack.match?(controllers_commented_pattern)
|
|
51
|
+
proceed = if options.key? "uncomment"
|
|
52
|
+
options["uncomment"]
|
|
53
|
+
else
|
|
54
|
+
!no?("✨ Do you want to import your Stimulus controllers in application.js? (Y/n)")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
if proceed
|
|
58
|
+
# uncomment_lines only works with Ruby comments 🙄
|
|
59
|
+
lines = pack_path.readlines
|
|
60
|
+
matches = lines.select { |line| line =~ controllers_commented_pattern }
|
|
61
|
+
lines[lines.index(matches.last).to_i] = "import \"controllers\"\n"
|
|
62
|
+
pack_path.write lines.join
|
|
63
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
64
|
+
else
|
|
65
|
+
say "🤷 your Stimulus controllers are not being imported in your application.js. We trust that you have a reason for this."
|
|
66
|
+
end
|
|
67
|
+
else
|
|
68
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
lines = pack_path.readlines
|
|
72
|
+
matches = lines.select { |line| line =~ /^import / }
|
|
73
|
+
lines.insert lines.index(matches.last).to_i + 1, "import \"controllers\"\n"
|
|
74
|
+
pack_path.write lines.join
|
|
75
|
+
say "✅ Stimulus controllers imported in #{friendly_pack_path}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# ensure webpacker is installed in the Gemfile
|
|
79
|
+
add_gem "webpacker@5.4.3"
|
|
80
|
+
|
|
81
|
+
complete_step :webpacker
|