rolemodel-rails 2.1.0 → 2.3.0
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/README.md +30 -9
- data/Rakefile +3 -3
- data/lib/generators/rolemodel/all_generator.rb +1 -0
- data/lib/generators/rolemodel/core_setup/README.md +27 -0
- data/lib/generators/rolemodel/core_setup/USAGE +12 -0
- data/lib/generators/rolemodel/core_setup/core_setup_generator.rb +23 -0
- data/lib/generators/rolemodel/github/README.md +4 -0
- data/lib/generators/rolemodel/github/templates/workflows/deploy-production.yml +34 -0
- data/lib/generators/rolemodel/github/templates/workflows/deploy-staging.yml +35 -0
- data/lib/generators/rolemodel/good_job/good_job_generator.rb +7 -13
- data/lib/generators/rolemodel/heroku/README.md +20 -1
- data/lib/generators/rolemodel/heroku/heroku_generator.rb +20 -0
- data/lib/generators/rolemodel/heroku/templates/app.json.tt +5 -2
- data/lib/generators/rolemodel/heroku/templates/deploy-app/SKILL.md +202 -0
- data/lib/generators/rolemodel/linters/eslint/eslint_generator.rb +1 -0
- data/lib/generators/rolemodel/linters/rubocop/rubocop_generator.rb +5 -1
- data/lib/generators/rolemodel/lograge/README.md +1 -1
- data/lib/generators/rolemodel/lograge/templates/config/initializers/lograge.rb +1 -1
- data/lib/generators/rolemodel/optics/base/base_generator.rb +3 -2
- data/lib/generators/rolemodel/react/react_generator.rb +1 -0
- data/lib/generators/rolemodel/readme/templates/README.md.erb +2 -4
- data/lib/generators/rolemodel/saas/devise/devise_generator.rb +3 -3
- data/lib/generators/rolemodel/sentry/README.md +25 -0
- data/lib/generators/rolemodel/sentry/USAGE +13 -0
- data/lib/generators/rolemodel/sentry/sentry_generator.rb +114 -0
- data/lib/generators/rolemodel/sentry/templates/app/controllers/concerns/sentry_user.rb +13 -0
- data/lib/generators/rolemodel/sentry/templates/app/javascript/initializers/sentry.js +34 -0
- data/lib/generators/rolemodel/sentry/templates/config/initializers/sentry.rb +68 -0
- data/lib/generators/rolemodel/simple_form/README.md +6 -0
- data/lib/generators/rolemodel/simple_form/USAGE +3 -0
- data/lib/generators/rolemodel/simple_form/simple_form_generator.rb +11 -0
- data/lib/generators/rolemodel/simple_form/templates/app/inputs/switch_checkbox_input.rb +1 -1
- data/lib/generators/rolemodel/slim/templates/app/views/application/_head.html.slim.tt +0 -4
- data/lib/generators/rolemodel/tailored_select/USAGE +2 -1
- data/lib/generators/rolemodel/tailored_select/tailored_select_generator.rb +15 -0
- data/lib/generators/rolemodel/testing/factory_bot/templates/support/factory_bot.rb +2 -0
- data/lib/generators/rolemodel/testing/jasmine_playwright/jasmine_playwright_generator.rb +2 -2
- data/lib/generators/rolemodel/testing/rspec/rspec_generator.rb +8 -10
- data/lib/generators/rolemodel/testing/rspec/templates/spec/rails_helper.rb.tt +4 -1
- data/lib/generators/rolemodel/testing/rspec/templates/spec/support/capybara_drivers.rb.tt +2 -0
- data/lib/generators/rolemodel/testing/rspec/templates/spec/support/helpers/action_cable_helper.rb +2 -0
- data/lib/generators/rolemodel/testing/rspec/templates/spec/support/helpers/test_element_helper.rb +2 -0
- data/lib/generators/rolemodel/testing/rspec/templates/spec/support/helpers.rb.tt +3 -1
- data/lib/generators/rolemodel/testing/vitest/vitest_generator.rb +1 -0
- data/lib/generators/rolemodel/turbo/all/README.md +16 -0
- data/lib/generators/rolemodel/turbo/all/USAGE +5 -0
- data/lib/generators/rolemodel/turbo/all/all_generator.rb +15 -0
- data/lib/generators/rolemodel/turbo/confirm/README.md +25 -0
- data/lib/generators/rolemodel/turbo/confirm/USAGE +5 -0
- data/lib/generators/rolemodel/turbo/confirm/confirm_generator.rb +35 -0
- data/lib/generators/rolemodel/turbo/form/README.md +8 -0
- data/lib/generators/rolemodel/turbo/form/USAGE +5 -0
- data/lib/generators/rolemodel/turbo/form/form_generator.rb +29 -0
- data/lib/generators/rolemodel/turbo/form/templates/app/javascript/controllers/turbo_form_controller.js +15 -0
- data/lib/generators/rolemodel/turbo/form/templates/spec/support/helpers/turbo_form_helper.rb +8 -0
- data/lib/generators/rolemodel/{ui_components → turbo}/modals/README.md +0 -2
- data/lib/generators/rolemodel/turbo/modals/USAGE +5 -0
- data/lib/generators/rolemodel/{ui_components → turbo}/modals/modals_generator.rb +9 -22
- data/lib/generators/rolemodel/{ui_components → turbo}/modals/templates/app/helpers/turbo_frame_link_helper.rb +2 -0
- data/lib/generators/rolemodel/turbo/ready/README.md +12 -0
- data/lib/generators/rolemodel/turbo/ready/USAGE +5 -0
- data/lib/generators/rolemodel/turbo/ready/ready_generator.rb +48 -0
- data/lib/generators/rolemodel/turbo/ready/templates/app/javascript/controllers/prevent_morph_controller.js +22 -0
- data/lib/generators/rolemodel/ui_components/navbar/navbar_generator.rb +11 -14
- data/lib/generators/rolemodel/webpack/README.md +2 -1
- data/lib/generators/rolemodel/webpack/templates/postcss.config.cjs +0 -3
- data/lib/generators/rolemodel/webpack/templates/webpack.config.js +6 -14
- data/lib/generators/rolemodel/webpack/webpack_generator.rb +18 -18
- data/lib/rolemodel/generator_base.rb +15 -0
- data/lib/rolemodel/version.rb +1 -1
- data/lib/rolemodel/yarn.rb +42 -0
- data/lib/rolemodel-rails.rb +0 -1
- metadata +58 -28
- data/lib/generators/rolemodel/linters/rubocop/templates/lib/cops/form_error_response.rb +0 -54
- data/lib/generators/rolemodel/linters/rubocop/templates/lib/cops/no_chrome_tag.rb +0 -45
- data/lib/generators/rolemodel/semaphore/README.md +0 -15
- data/lib/generators/rolemodel/semaphore/USAGE +0 -11
- data/lib/generators/rolemodel/semaphore/semaphore_generator.rb +0 -25
- data/lib/generators/rolemodel/semaphore/templates/heroku-deployment-commands.sh +0 -3
- data/lib/generators/rolemodel/semaphore/templates/production-deploy.yml.erb +0 -17
- data/lib/generators/rolemodel/semaphore/templates/semaphore.yml.erb +0 -145
- data/lib/generators/rolemodel/semaphore/templates/staging-deploy.yml.erb +0 -17
- data/lib/generators/rolemodel/ui_components/modals/USAGE +0 -8
- data/lib/generators/rolemodel/ui_components/modals/templates/app/javascript/controllers/morph_controller.js +0 -23
- data/lib/generators/rolemodel/webpack/templates/app/assets/stylesheets/application.scss +0 -5
- data/lib/generators/rolemodel/webpack/templates/app/javascript/initializers/honeybadger.js +0 -26
- /data/lib/generators/rolemodel/{simple_form → tailored_select}/templates/app/inputs/tailored_select_input.rb +0 -0
- /data/lib/generators/rolemodel/{ui_components/modals/templates/app/javascript/initializers/turbo_confirm.js → turbo/confirm/templates/app/javascript/initializers/turbo_confirm.js.tt} +0 -0
- /data/lib/generators/rolemodel/{ui_components/modals/templates/app/views/application/_confirm.html.slim → turbo/confirm/templates/app/views/application/_confirm.html.slim.tt} +0 -0
- /data/lib/generators/rolemodel/{ui_components → turbo}/modals/templates/app/javascript/controllers/toggle_controller.js +0 -0
- /data/lib/generators/rolemodel/{ui_components → turbo}/modals/templates/app/javascript/initializers/frame_missing_handler.js +0 -0
- /data/lib/generators/rolemodel/{ui_components → turbo}/modals/templates/app/views/layouts/modal.html.slim.tt +0 -0
- /data/lib/generators/rolemodel/{ui_components → turbo}/modals/templates/app/views/layouts/panel.html.slim.tt +0 -0
- /data/lib/generators/rolemodel/{ui_components/modals → turbo/ready}/templates/app/javascript/initializers/before_morph_handler.js +0 -0
- /data/lib/generators/rolemodel/ui_components/navbar/templates/app/assets/stylesheets/components/shoelace/{index.scss → index.css} +0 -0
- /data/lib/generators/rolemodel/ui_components/navbar/templates/app/views/{layouts → application}/_navbar.html.slim +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Rolemodel
|
|
2
|
+
module Turbo
|
|
3
|
+
class FormGenerator < GeneratorBase
|
|
4
|
+
source_root File.expand_path('templates', __dir__)
|
|
5
|
+
|
|
6
|
+
def add_rails_request_package
|
|
7
|
+
say 'Installing @rails/request.js package', :green
|
|
8
|
+
|
|
9
|
+
ensure_yarn
|
|
10
|
+
run 'yarn add @rails/request.js'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add_stimulus_controller
|
|
14
|
+
say 'Adding Turbo Form Stimulus Controller', :green
|
|
15
|
+
|
|
16
|
+
directory 'app/javascript/controllers'
|
|
17
|
+
|
|
18
|
+
rails_command 'stimulus:manifest:update'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def add_system_spec_helper
|
|
22
|
+
say 'Adding Turbo Form System Spec Helper', :green
|
|
23
|
+
|
|
24
|
+
directory 'spec/support/helpers'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
|
2
|
+
import { patch } from '@rails/request.js'
|
|
3
|
+
|
|
4
|
+
export default class extends Controller {
|
|
5
|
+
static values = { url: String, count: Number }
|
|
6
|
+
|
|
7
|
+
async perform({ params: { url: urlParam, query: queryParams } }) {
|
|
8
|
+
const body = new FormData(this.element)
|
|
9
|
+
|
|
10
|
+
if (queryParams) Object.keys(queryParams).forEach(key => body.append(key, queryParams[key]))
|
|
11
|
+
|
|
12
|
+
const response = await patch(urlParam || this.urlValue, { body, responseKind: 'turbo-stream' })
|
|
13
|
+
if (response.ok) this.countValue += 1
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module TurboFormHelper
|
|
2
|
+
def expect_turbo_form_request
|
|
3
|
+
count_value = find("[data-controller='turbo-form']")['data-turbo-form-count-value'] || 0
|
|
4
|
+
yield
|
|
5
|
+
expect(page).to have_selector("[data-turbo-form-count-value='#{count_value.to_i + 1}']"),
|
|
6
|
+
'Expected a successful Turbo-Form request, but none was detected'
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -9,10 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
## What you get
|
|
11
11
|
|
|
12
|
-
* Custom confirm dialogs via `@rolemodel/turbo-confirm` integration
|
|
13
12
|
* RoleModel Modal pattern integration. See Notes below for usage documentation.
|
|
14
13
|
* RoleModel Panel pattern integration, if run with the `--panels` flag.
|
|
15
|
-
* some generally useful, global Turbo before-morph handlers.
|
|
16
14
|
|
|
17
15
|
> [!IMPORTANT]
|
|
18
16
|
> This generator does not provide RoleModel Panel integration, unless run with the `--panels` flag.
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
module Rolemodel
|
|
2
|
-
module
|
|
3
|
-
class ModalsGenerator < GeneratorBase
|
|
2
|
+
module Turbo
|
|
3
|
+
class ModalsGenerator < ::Rolemodel::GeneratorBase
|
|
4
4
|
source_root File.expand_path('templates', __dir__)
|
|
5
5
|
class_option :panels, type: :boolean, default: false, desc: 'Include RoleModel Panel Setup'
|
|
6
6
|
|
|
7
|
-
def turbo_confirm
|
|
8
|
-
say 'Installing Turbo Confirm package', :green
|
|
9
|
-
|
|
10
|
-
run 'yarn add @rolemodel/turbo-confirm'
|
|
11
|
-
end
|
|
12
|
-
|
|
13
7
|
def helpers_and_views
|
|
14
8
|
say 'generating views & helpers', :green
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
directory 'app/views/application'
|
|
10
|
+
directory 'app/helpers'
|
|
19
11
|
directory 'app/views/layouts'
|
|
20
12
|
end
|
|
21
13
|
|
|
@@ -26,9 +18,7 @@ module Rolemodel
|
|
|
26
18
|
directory 'app/javascript/initializers'
|
|
27
19
|
|
|
28
20
|
append_to_file 'app/javascript/application.js', <<~JS
|
|
29
|
-
import './initializers/turbo_confirm.js'
|
|
30
21
|
import './initializers/frame_missing_handler.js'
|
|
31
|
-
import './initializers/before_morph_handler.js'
|
|
32
22
|
JS
|
|
33
23
|
end
|
|
34
24
|
|
|
@@ -38,7 +28,6 @@ module Rolemodel
|
|
|
38
28
|
inject_into_file 'app/views/layouts/application.html.slim', after: /\bbody.*\n/ do
|
|
39
29
|
optimize_indentation <<~SLIM, 4
|
|
40
30
|
= turbo_frame_tag 'modal'
|
|
41
|
-
= render 'confirm'
|
|
42
31
|
SLIM
|
|
43
32
|
end
|
|
44
33
|
end
|
|
@@ -47,18 +36,15 @@ module Rolemodel
|
|
|
47
36
|
if options.panels?
|
|
48
37
|
say 'Setting Up RoleModel Panel', :green
|
|
49
38
|
|
|
50
|
-
inject_into_file 'app/views/layouts/application.html.slim', after: /\bturbo_frame_tag 'modal'
|
|
39
|
+
inject_into_file 'app/views/layouts/application.html.slim', after: /\bturbo_frame_tag 'modal'.*\n/ do
|
|
51
40
|
optimize_indentation <<~SLIM, 4
|
|
52
41
|
= turbo_frame_tag 'panel'
|
|
53
42
|
SLIM
|
|
54
43
|
end
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@import '@rolemodel/optics/dist/css/addons/panel';
|
|
60
|
-
SCSS
|
|
61
|
-
end
|
|
45
|
+
append_to_file application_stylesheet_path, <<~CSS
|
|
46
|
+
@import '@rolemodel/optics/dist/css/addons/panel';
|
|
47
|
+
CSS
|
|
62
48
|
else
|
|
63
49
|
remove_file 'app/views/layouts/panel.html.slim'
|
|
64
50
|
end
|
|
@@ -67,8 +53,9 @@ module Rolemodel
|
|
|
67
53
|
def register_stimulus_controller
|
|
68
54
|
say 'updating stimulus manifest', :green
|
|
69
55
|
|
|
70
|
-
|
|
56
|
+
rails_command 'stimulus:manifest:update'
|
|
71
57
|
end
|
|
72
58
|
end
|
|
73
59
|
end
|
|
74
60
|
end
|
|
61
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Ready Generator
|
|
2
|
+
|
|
3
|
+
This generator is designed to make your application "Turbo Ready".
|
|
4
|
+
|
|
5
|
+
That is, "ready" for modern Turbo Features such as "morphing", "scroll preservation" and meta tag injection via Turbo-Rails helpers.
|
|
6
|
+
|
|
7
|
+
## What you get
|
|
8
|
+
|
|
9
|
+
- a "head" outlet in your "head" partial (expected by all Turbo-Rails helpers)
|
|
10
|
+
- morphing and scroll preservation meta tags
|
|
11
|
+
- generally useful event handlers.
|
|
12
|
+
- a stimulus controller for skipping specific attribute morphing
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Rolemodel
|
|
2
|
+
module Turbo
|
|
3
|
+
class ReadyGenerator < ::Rolemodel::GeneratorBase
|
|
4
|
+
source_root File.expand_path('templates', __dir__)
|
|
5
|
+
|
|
6
|
+
def add_javascript_initializer
|
|
7
|
+
say 'generating & importing morph event handlers', :green
|
|
8
|
+
|
|
9
|
+
directory 'app/javascript/initializers'
|
|
10
|
+
|
|
11
|
+
append_to_file 'app/javascript/application.js', <<~JS
|
|
12
|
+
import './initializers/before_morph_handler.js'
|
|
13
|
+
JS
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def add_stimulus_controller
|
|
17
|
+
say 'adding prevent-morph controller & updating manifest', :green
|
|
18
|
+
|
|
19
|
+
directory 'app/javascript/controllers'
|
|
20
|
+
|
|
21
|
+
rails_command 'stimulus:manifest:update'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def inject_meta_tags
|
|
25
|
+
say 'adding meta tags to head partial', :green
|
|
26
|
+
|
|
27
|
+
inject_into_file 'app/views/application/_head.html.slim', after: /meta name="viewport".*\n/ do
|
|
28
|
+
optimize_indentation <<~SLIM
|
|
29
|
+
meta name="turbo-refresh-method" content="morph"
|
|
30
|
+
meta name="turbo-refresh-scroll" content="preserve"
|
|
31
|
+
SLIM
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def inject_head_outlet
|
|
36
|
+
say 'adding head outlet to head partial', :green
|
|
37
|
+
|
|
38
|
+
append_to_file 'app/views/application/_head.html.slim' do
|
|
39
|
+
optimize_indentation <<~SLIM
|
|
40
|
+
|
|
41
|
+
= yield :head
|
|
42
|
+
SLIM
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
static values = {
|
|
5
|
+
attributeName: String
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Use this method to prevent morphing of a specific attribute on specific elements. This is useful for attributes that may have changed due to user interaction
|
|
10
|
+
* NOTE: The "open" attribute is preserved by default in 'app/javascript/initializers/before_morph_handler.js' and does not require this controller to be used.
|
|
11
|
+
*
|
|
12
|
+
* Example:
|
|
13
|
+
* <details controller="prevent-morph" data-prevent-morph-attribute-name-value="open" data-action="turbo:before-morph-attribute->prevent-morph#onNamedAttribute">
|
|
14
|
+
*
|
|
15
|
+
* @param {import("@hotwired/turbo").TurboBeforeMorphAttributeEvent} event
|
|
16
|
+
*/
|
|
17
|
+
onNamedAttribute(event) {
|
|
18
|
+
if (event.detail.attributeName === this.attributeNameValue) {
|
|
19
|
+
event.preventDefault()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -8,7 +8,7 @@ module Rolemodel
|
|
|
8
8
|
def copy_navbar_files
|
|
9
9
|
say 'Copying Navbar files', :green
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
directory 'app/views'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def insert_navbar_before_content
|
|
@@ -17,7 +17,7 @@ module Rolemodel
|
|
|
17
17
|
insert_into_file 'app/views/layouts/application.html.slim', before: /\s+\.app__content/ do
|
|
18
18
|
optimize_indentation <<~SLIM, 4
|
|
19
19
|
|
|
20
|
-
= render '
|
|
20
|
+
= render 'navbar'
|
|
21
21
|
SLIM
|
|
22
22
|
end
|
|
23
23
|
end
|
|
@@ -25,29 +25,26 @@ module Rolemodel
|
|
|
25
25
|
def install_shoelace
|
|
26
26
|
say 'Installing Shoelace package', :green
|
|
27
27
|
|
|
28
|
+
ensure_yarn
|
|
28
29
|
run 'yarn add @shoelace-style/shoelace'
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def add_shoelace_javascript_imports
|
|
32
33
|
say 'Copying Shoelace JS imports', :green
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
append_to_file 'app/javascript/application.js'
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
JS
|
|
39
|
-
end
|
|
35
|
+
directory 'app/javascript/lib'
|
|
36
|
+
append_to_file 'app/javascript/application.js', <<~JS
|
|
37
|
+
import './lib/shoelace.js'
|
|
38
|
+
JS
|
|
40
39
|
end
|
|
41
40
|
|
|
42
41
|
def copy_shoelace_css_imports
|
|
43
42
|
say 'Copying Shoelace CSS imports', :green
|
|
44
43
|
|
|
45
|
-
copy_file 'app/assets/stylesheets/components/shoelace/index.
|
|
46
|
-
append_to_file
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
SCSS
|
|
50
|
-
end
|
|
44
|
+
copy_file 'app/assets/stylesheets/components/shoelace/index.css'
|
|
45
|
+
append_to_file application_stylesheet_path, <<~CSS
|
|
46
|
+
@import 'components/shoelace/index.css';
|
|
47
|
+
CSS
|
|
51
48
|
end
|
|
52
49
|
end
|
|
53
50
|
end
|
|
@@ -5,4 +5,5 @@
|
|
|
5
5
|
* Webpack v5
|
|
6
6
|
* Uses `esbuild-loader` instead of Babel to transpile JS
|
|
7
7
|
* Uses PostCSS to compile CSS and SCSS
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
For error monitoring, run the `rolemodel:sentry` generator.
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import webpack from 'webpack'
|
|
3
|
-
import TerserPlugin from 'terser-webpack-plugin'
|
|
4
|
-
import HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack'
|
|
5
3
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
|
6
4
|
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'
|
|
7
5
|
|
|
@@ -17,7 +15,7 @@ export default {
|
|
|
17
15
|
entry: {
|
|
18
16
|
application: [
|
|
19
17
|
'./app/javascript/application.js',
|
|
20
|
-
'./app/assets/stylesheets/application.
|
|
18
|
+
'./app/assets/stylesheets/application.css'
|
|
21
19
|
]
|
|
22
20
|
},
|
|
23
21
|
output: {
|
|
@@ -62,9 +60,11 @@ export default {
|
|
|
62
60
|
{
|
|
63
61
|
loader: 'css-loader',
|
|
64
62
|
options: {
|
|
65
|
-
url: false
|
|
63
|
+
url: false,
|
|
64
|
+
importLoaders: 1
|
|
66
65
|
}
|
|
67
66
|
},
|
|
67
|
+
'strip-sourcemap-loader',
|
|
68
68
|
'postcss-loader'
|
|
69
69
|
]
|
|
70
70
|
}
|
|
@@ -73,7 +73,8 @@ export default {
|
|
|
73
73
|
optimization: {
|
|
74
74
|
minimize: mode === 'production',
|
|
75
75
|
minimizer: [
|
|
76
|
-
|
|
76
|
+
// '...' keeps webpack 5's built-in JS minimizer (terser)
|
|
77
|
+
'...',
|
|
77
78
|
new CssMinimizerPlugin()
|
|
78
79
|
]
|
|
79
80
|
},
|
|
@@ -88,17 +89,8 @@ export default {
|
|
|
88
89
|
|
|
89
90
|
// Replace ENV variables at build time
|
|
90
91
|
new webpack.DefinePlugin({
|
|
91
|
-
'process.env.HONEYBADGER_API_KEY': JSON.stringify(process.env.HONEYBADGER_API_KEY),
|
|
92
|
-
'process.env.HONEYBADGER_ENV': JSON.stringify(process.env.HONEYBADGER_ENV),
|
|
93
92
|
'process.env.RAILS_ENV': JSON.stringify(process.env.RAILS_ENV),
|
|
94
93
|
'process.env.SOURCE_VERSION': JSON.stringify(process.env.SOURCE_VERSION)
|
|
95
|
-
}),
|
|
96
|
-
|
|
97
|
-
// Send source maps to HoneyBadger in production for easier debugging
|
|
98
|
-
(mode === 'production' && !process.env.CI) && new HoneybadgerSourceMapPlugin({
|
|
99
|
-
apiKey: process.env.HONEYBADGER_API_KEY,
|
|
100
|
-
assetsUrl: process.env.ASSETS_URL,
|
|
101
|
-
revision: process.env.SOURCE_VERSION
|
|
102
94
|
})
|
|
103
95
|
].filter(Boolean)
|
|
104
96
|
}
|
|
@@ -3,8 +3,6 @@ module Rolemodel
|
|
|
3
3
|
source_root File.expand_path('templates', __dir__)
|
|
4
4
|
|
|
5
5
|
DEV_DEPS = %w[
|
|
6
|
-
@honeybadger-io/webpack
|
|
7
|
-
@honeybadger-io/js
|
|
8
6
|
esbuild
|
|
9
7
|
esbuild-loader
|
|
10
8
|
webpack
|
|
@@ -25,12 +23,30 @@ module Rolemodel
|
|
|
25
23
|
mini-css-extract-plugin
|
|
26
24
|
]
|
|
27
25
|
|
|
26
|
+
def ensure_no_importmap
|
|
27
|
+
return unless Rails.root.join(destination_root, 'config/importmap.rb').exist?
|
|
28
|
+
|
|
29
|
+
remove_file 'config/importmap.rb'
|
|
30
|
+
bundle_command 'remove importmap-rails'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def ensure_jsbundling
|
|
34
|
+
bundle_command 'add jsbundling-rails'
|
|
35
|
+
run_bundle
|
|
36
|
+
end
|
|
37
|
+
|
|
28
38
|
def ensure_node_version
|
|
29
39
|
say "Establish development environment Node version of #{set_color(NODE_VERSION, :yellow)}", :green
|
|
30
40
|
|
|
31
41
|
create_file '.node-version', NODE_VERSION, force: true
|
|
32
42
|
end
|
|
33
43
|
|
|
44
|
+
def enable_corepack_and_yarn
|
|
45
|
+
say 'Enabling Corepack and pinning the project to Yarn 4+', :green
|
|
46
|
+
|
|
47
|
+
ensure_yarn
|
|
48
|
+
end
|
|
49
|
+
|
|
34
50
|
def force_node_to_use_es_modules
|
|
35
51
|
say 'Configuring project to use ES Modules instead of CommonJS', :green
|
|
36
52
|
|
|
@@ -50,22 +66,6 @@ module Rolemodel
|
|
|
50
66
|
run "yarn add --dev #{dependencies.join(' ')}"
|
|
51
67
|
end
|
|
52
68
|
|
|
53
|
-
def honeybadger_setup
|
|
54
|
-
say 'Setting up Honeybadger for JS error reporting', :green
|
|
55
|
-
|
|
56
|
-
copy_file 'app/javascript/initializers/honeybadger.js'
|
|
57
|
-
append_to_file 'app/javascript/application.js', <<~JS
|
|
58
|
-
import './initializers/honeybadger'
|
|
59
|
-
JS
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def replace_css_entrypoint_with_scss
|
|
63
|
-
say 'Replacing CSS entrypoint file with SCSS version', :green
|
|
64
|
-
|
|
65
|
-
remove_file 'app/assets/stylesheets/application.css'
|
|
66
|
-
copy_file 'app/assets/stylesheets/application.scss'
|
|
67
|
-
end
|
|
68
|
-
|
|
69
69
|
def add_webpack_config
|
|
70
70
|
say 'Copying PostCSS & Webpack config files', :green
|
|
71
71
|
|
|
@@ -3,15 +3,30 @@
|
|
|
3
3
|
require 'rails/generators'
|
|
4
4
|
require 'rails/generators/bundle_helper'
|
|
5
5
|
require_relative 'replace_content_helper'
|
|
6
|
+
require 'rolemodel/yarn'
|
|
6
7
|
|
|
7
8
|
module Rolemodel
|
|
8
9
|
class GeneratorBase < ::Rails::Generators::Base
|
|
9
10
|
include ::Rails::Generators::BundleHelper, ReplaceContentHelper
|
|
10
11
|
|
|
12
|
+
|
|
11
13
|
private
|
|
12
14
|
# based on https://github.com/rails/rails/blob/main/railties/lib/rails/generators/app_base.rb#L713
|
|
13
15
|
def run_bundle
|
|
14
16
|
bundle_command("install --quiet", "BUNDLE_IGNORE_MESSAGES" => "1")
|
|
15
17
|
end
|
|
18
|
+
|
|
19
|
+
# Enable Corepack and pin the project to Yarn 4+ before running any `yarn`
|
|
20
|
+
# command. Empty args/opts are required: without them, Thor forwards this
|
|
21
|
+
# generator's own CLI args (e.g. the test harness's --skip-bundle
|
|
22
|
+
# --skip-bootsnap) into Rolemodel::Yarn#setup, which takes none and raises
|
|
23
|
+
# Thor::InvocationError.
|
|
24
|
+
def ensure_yarn
|
|
25
|
+
invoke 'rolemodel:yarn:setup', [], {}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def application_stylesheet_path
|
|
29
|
+
Dir.glob('app/assets/stylesheets/application.*').first
|
|
30
|
+
end
|
|
16
31
|
end
|
|
17
32
|
end
|
data/lib/rolemodel/version.rb
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'thor/actions'
|
|
3
|
+
|
|
4
|
+
module Rolemodel
|
|
5
|
+
class Yarn < ::Thor
|
|
6
|
+
include ::Thor::Actions
|
|
7
|
+
|
|
8
|
+
# Enable Corepack and pin the project to Yarn 4+ (instead of the classic
|
|
9
|
+
# Yarn 1.22). Idempotent, so any generator can call it before running a
|
|
10
|
+
# `yarn` command to guarantee the modern toolchain is in place.
|
|
11
|
+
desc 'setup', 'Set the current stable version of Yarn, enable corepack, and initialize a package.json file'
|
|
12
|
+
def setup
|
|
13
|
+
# Configure the node-modules linker so webpack, Playwright, and the Rails
|
|
14
|
+
# asset pipeline keep working (Yarn 4 defaults to Plug'n'Play otherwise).
|
|
15
|
+
# skip if exists? to avoid overwriting any other existing config
|
|
16
|
+
create_file '.yarnrc.yml', "nodeLinker: node-modules\n", skip: true
|
|
17
|
+
|
|
18
|
+
yes! 'yarn set version stable'
|
|
19
|
+
yes! 'corepack enable'
|
|
20
|
+
yes! 'yarn init'
|
|
21
|
+
|
|
22
|
+
ignore_yarn_install_state
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def ignore_yarn_install_state
|
|
28
|
+
gitignore = File.expand_path('.gitignore', destination_root)
|
|
29
|
+
return create_file '.gitignore', "/.yarn/install-state.gz\n" unless File.exist?(gitignore)
|
|
30
|
+
return if File.read(gitignore).include?('/.yarn/install-state.gz')
|
|
31
|
+
|
|
32
|
+
append_to_file '.gitignore', "\n/.yarn/install-state.gz\n"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def yes!(command)
|
|
36
|
+
Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
|
|
37
|
+
stdin.puts 'y'
|
|
38
|
+
stdin.close
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|