opal-rails 2.0.4 → 3.0.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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +39 -4
  3. data/.gitignore +2 -0
  4. data/Appraisals +20 -21
  5. data/CHANGELOG.md +30 -0
  6. data/Gemfile +2 -2
  7. data/PORTING.md +140 -0
  8. data/README.md +150 -87
  9. data/Rakefile +16 -2
  10. data/app/helpers/opal_helper.rb +9 -28
  11. data/bin/sandbox +3 -2
  12. data/bin/sandbox-setup +2 -0
  13. data/gemfiles/{rails_7_0_opal_1_0.gemfile → rails_7_0_opal_1_8.gemfile} +2 -2
  14. data/gemfiles/{rails_7_0_opal_1_3.gemfile → rails_7_0_opal_master.gemfile} +2 -2
  15. data/gemfiles/{rails_6_0_opal_1_0.gemfile → rails_8_0_opal_1_8.gemfile} +3 -3
  16. data/gemfiles/rails_8_0_opal_master.gemfile +10 -0
  17. data/gemfiles/{rails_6_1_opal_1_0.gemfile → rails_8_1_opal_1_8.gemfile} +3 -3
  18. data/gemfiles/rails_8_1_opal_master.gemfile +10 -0
  19. data/lib/generators/opal/assets/assets_generator.rb +11 -1
  20. data/lib/generators/opal/assets/templates/{javascript.js.rb → asset.rb.tt} +3 -6
  21. data/lib/generators/opal/install/install_generator.rb +160 -9
  22. data/lib/generators/opal/install/templates/{application.js.rb → application.rb} +4 -4
  23. data/lib/generators/opal/install/templates/dev.tt +8 -0
  24. data/lib/generators/opal/install/templates/{initializer.rb → initializer.rb.tt} +8 -0
  25. data/lib/opal/rails/builder_runner.rb +126 -0
  26. data/lib/opal/rails/engine.rb +11 -9
  27. data/lib/opal/rails/entrypoints_resolver.rb +81 -0
  28. data/lib/opal/rails/errors.rb +11 -0
  29. data/lib/opal/rails/file_watcher.rb +58 -0
  30. data/lib/opal/rails/haml6_filter.rb +6 -6
  31. data/lib/opal/rails/haml_filter.rb +3 -6
  32. data/lib/opal/rails/legacy_upgrade_warning.rb +95 -0
  33. data/lib/opal/rails/outputs_manifest.rb +82 -0
  34. data/lib/opal/rails/path_setup.rb +28 -0
  35. data/lib/opal/rails/task_hooks.rb +49 -0
  36. data/lib/opal/rails/version.rb +1 -1
  37. data/lib/opal/rails/watch_runner.rb +173 -0
  38. data/lib/opal/rails.rb +7 -0
  39. data/lib/tasks/opal.rake +48 -0
  40. data/opal-rails.gemspec +23 -14
  41. data/spec/end_to_end/full_lifecycle_spec.rb +377 -0
  42. data/spec/helpers/opal_helper_spec.rb +27 -34
  43. data/spec/integration/source_map_spec.rb +6 -8
  44. data/spec/opal/assets_generator_spec.rb +31 -0
  45. data/spec/opal/install_generator_spec.rb +140 -0
  46. data/spec/opal/rails/build_task_spec.rb +116 -0
  47. data/spec/opal/rails/builder_runner_spec.rb +151 -0
  48. data/spec/opal/rails/clobber_task_spec.rb +55 -0
  49. data/spec/opal/rails/entrypoints_resolver_spec.rb +50 -0
  50. data/spec/opal/rails/haml_filter_spec.rb +41 -0
  51. data/spec/opal/rails/legacy_upgrade_warning_spec.rb +94 -0
  52. data/spec/opal/rails/outputs_manifest_spec.rb +44 -0
  53. data/spec/opal/rails/path_setup_spec.rb +71 -0
  54. data/spec/opal/rails/task_hooks_spec.rb +61 -0
  55. data/spec/opal/rails/watch_runner_spec.rb +283 -0
  56. data/spec/opal/rails/watch_task_spec.rb +23 -0
  57. data/spec/spec_helper.rb +16 -7
  58. data/spec/support/browser_support_spec.rb +36 -0
  59. data/spec/support/capybara.rb +61 -0
  60. data/spec/support/reset_assets_cache.rb +9 -1
  61. data/spec/support/test_app.rb +23 -2
  62. data/test_apps/app/application_controller.rb +23 -32
  63. data/test_apps/app/assets/builds/.keep +0 -0
  64. data/test_apps/app/assets/config/manifest.js +3 -1
  65. data/test_apps/app/assets/images/.keep +0 -0
  66. data/test_apps/app/opal/application.rb +5 -0
  67. data/test_apps/app/{assets/javascripts/source_map_example.js.rb → opal/source_map_example.rb} +1 -2
  68. data/test_apps/app/opal/with_assignments.js.rb +8 -0
  69. data/test_apps/rails.rb +19 -5
  70. metadata +196 -50
  71. data/gemfiles/rails_6_0_opal_1_1.gemfile +0 -9
  72. data/gemfiles/rails_6_0_opal_1_3.gemfile +0 -10
  73. data/gemfiles/rails_6_0_opal_1_7.gemfile +0 -10
  74. data/gemfiles/rails_6_1_opal_1_1.gemfile +0 -9
  75. data/gemfiles/rails_6_1_opal_1_3.gemfile +0 -10
  76. data/gemfiles/rails_6_1_opal_1_7.gemfile +0 -10
  77. data/gemfiles/rails_7_0_opal_1_7.gemfile +0 -10
  78. data/lib/opal/rails/haml5_filter.rb +0 -28
  79. data/test_apps/app/assets/javascripts/application.js.rb +0 -7
  80. data/test_apps/app/assets/javascripts/bar.rb +0 -3
  81. data/test_apps/app/assets/javascripts/foo.js.rb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e906bb39e61bd1c76e195bcb8a26ea06864ea268564bae806fde7e516b7dea4b
4
- data.tar.gz: 78d2469ab085763e2d5f9e35ad78544907dc44842bd4e173cfbb356811b9dcfc
3
+ metadata.gz: ba1f394cc2bbf7116233984024e784413beafbaf854ecec344dd4ac82b3399c5
4
+ data.tar.gz: aeb984c344f373496ee3ab1ec65b25b98941a8f3abd8cb90f2798f0f76557bdb
5
5
  SHA512:
6
- metadata.gz: 07a8fb5f8d174eb6ea19489d6c758f1f0356b70312b5f7fed2958206fe12fbe18c8833dce05b403fde12b81d169fefdead8dc1c7e867e4f1fbace13f197f4b0c
7
- data.tar.gz: 33049701172699ca92284856854600b89b6ae307088d79f4e4fc1c7a8d61aed3138ca05ed3608835dec86b37669fa97fa5225722e6810c27935dd8ed8e7731c5
6
+ metadata.gz: f1c3651233c6b59f85c924cfca5eae702ff796ac152328e2166407e3cacfcb911b5b2485149832f8a906744c3c979b86ee72ef217922efb40cbd2d4ffe3096b7
7
+ data.tar.gz: 143ec8db4639e589f5d4cda0c9b8b4fa9ee93ab26fcb9e5909918093f0be5f26b3b9152be48492a43500d2454d459a35af6d8a734a08913b5e82d3c839b83f37
@@ -13,9 +13,43 @@ jobs:
13
13
  strategy:
14
14
  fail-fast: false
15
15
  matrix:
16
- ruby: ['3.0', '3.1', '3.2']
17
- rails: ['rails_6_0', 'rails_6_1', 'rails_7_0']
18
- opal: ['opal_1_0', 'opal_1_3', 'opal_1_7']
16
+ include:
17
+ - ruby: '3.2'
18
+ rails: 'rails_7_0'
19
+ opal: 'opal_1_8'
20
+ - ruby: '3.2'
21
+ rails: 'rails_7_0'
22
+ opal: 'opal_master'
23
+ - ruby: '4.0'
24
+ rails: 'rails_7_0'
25
+ opal: 'opal_1_8'
26
+ - ruby: '4.0'
27
+ rails: 'rails_7_0'
28
+ opal: 'opal_master'
29
+ - ruby: '3.2'
30
+ rails: 'rails_8_0'
31
+ opal: 'opal_1_8'
32
+ - ruby: '3.2'
33
+ rails: 'rails_8_0'
34
+ opal: 'opal_master'
35
+ - ruby: '4.0'
36
+ rails: 'rails_8_0'
37
+ opal: 'opal_1_8'
38
+ - ruby: '4.0'
39
+ rails: 'rails_8_0'
40
+ opal: 'opal_master'
41
+ - ruby: '3.2'
42
+ rails: 'rails_8_1'
43
+ opal: 'opal_1_8'
44
+ - ruby: '3.2'
45
+ rails: 'rails_8_1'
46
+ opal: 'opal_master'
47
+ - ruby: '4.0'
48
+ rails: 'rails_8_1'
49
+ opal: 'opal_1_8'
50
+ - ruby: '4.0'
51
+ rails: 'rails_8_1'
52
+ opal: 'opal_master'
19
53
  runs-on: ubuntu-latest
20
54
 
21
55
  steps:
@@ -23,7 +57,8 @@ jobs:
23
57
  run: |
24
58
  sudo apt-get update
25
59
  sudo apt-get install -y sqlite3 libsqlite3-dev
26
- - uses: actions/checkout@v1
60
+ command -v google-chrome || command -v google-chrome-stable || command -v chromium-browser || command -v chromium || sudo apt-get install -y chromium-browser || sudo apt-get install -y chromium
61
+ - uses: actions/checkout@v4
27
62
  - name: Set up Ruby
28
63
  uses: ruby/setup-ruby@v1
29
64
  with:
data/.gitignore CHANGED
@@ -7,6 +7,8 @@
7
7
  /test_apps/log/*.log
8
8
  /test_apps/tmp/
9
9
  /test_apps/.sass-cache
10
+ /test_apps/app/assets/builds/*
11
+ !/test_apps/app/assets/builds/.keep
10
12
  Gemfile.lock
11
13
  *.gemfile.lock
12
14
 
data/Appraisals CHANGED
@@ -1,40 +1,39 @@
1
1
  current_ruby = Gem::Version.new(RUBY_VERSION)
2
- ruby_2_5_0 = Gem::Version.new('2.5.0')
3
2
  ruby_2_7_0 = Gem::Version.new('2.7.0')
3
+ ruby_3_2_0 = Gem::Version.new('3.2.0')
4
+
5
+ rails_7_sqlite3 = '~> 1.4'
6
+ rails_8_sqlite3 = '>= 2.1'
4
7
 
5
8
  ENV['OPAL_VERSION'] = nil # ensure the env is clean
6
9
 
7
10
  github = -> repo_name { "https://github.com/#{repo_name}.git" }
8
11
 
9
12
  {
10
- opal_1_7: -> gemfile do
11
- gemfile.gem 'opal', '~> 1.7.0'
12
- gemfile.gem 'opal-sprockets'
13
- end,
14
-
15
- opal_1_3: -> gemfile do
16
- gemfile.gem 'opal', '~> 1.3.0'
17
- gemfile.gem 'opal-sprockets'
13
+ opal_1_8: -> gemfile do
14
+ gemfile.gem 'opal', '~> 1.8.0'
18
15
  end,
19
16
 
20
- opal_1_0: -> gemfile do
21
- gemfile.gem 'opal', '~> 1.0.0'
22
- gemfile.gem 'opal-sprockets'
17
+ opal_master: -> gemfile do
18
+ gemfile.gem 'opal', git: github['opal/opal'], branch: :master
23
19
  end,
24
20
 
25
21
  }.each do |opal_version, gem_opal|
26
- appraise "rails_6_0_#{opal_version}" do
27
- gem "rails", "~> 6.0.0"
22
+ appraise "rails_7_0_#{opal_version}" do
23
+ gem "rails", "~> 7.0.0"
24
+ gem 'sqlite3', rails_7_sqlite3
28
25
  gem_opal[self]
29
- end if current_ruby >= ruby_2_5_0
26
+ end if current_ruby >= ruby_2_7_0
30
27
 
31
- appraise "rails_6_1_#{opal_version}" do
32
- gem "rails", "~> 6.1.0"
28
+ appraise "rails_8_0_#{opal_version}" do
29
+ gem "rails", "~> 8.0.0"
30
+ gem 'sqlite3', rails_8_sqlite3
33
31
  gem_opal[self]
34
- end if current_ruby >= ruby_2_5_0
32
+ end if current_ruby >= ruby_3_2_0
35
33
 
36
- appraise "rails_7_0_#{opal_version}" do
37
- gem "rails", "~> 7.0.0"
34
+ appraise "rails_8_1_#{opal_version}" do
35
+ gem "rails", "~> 8.1.0"
36
+ gem 'sqlite3', rails_8_sqlite3
38
37
  gem_opal[self]
39
- end if current_ruby >= ruby_2_7_0
38
+ end if current_ruby >= ruby_3_2_0
40
39
  end
data/CHANGELOG.md CHANGED
@@ -18,6 +18,36 @@ Whitespace conventions:
18
18
  - 1 spaces before normal text
19
19
  -->
20
20
 
21
+ ## [Unreleased]
22
+
23
+ ## [3.0.0](https://github.com/opal/opal-rails/compare/v2.0.4...v3.0.0) - 2026-04-09
24
+
25
+ ### Added
26
+
27
+ - Add build-based Opal compilation with `opal:build`.
28
+ - Add `opal:clobber` for Opal-owned build outputs.
29
+ - Add dependency-aware `opal:watch`.
30
+
31
+ ### Changed
32
+
33
+ - Rework `opal:install` for build-based apps and migration-friendly layouts.
34
+ - Make Sprockets optional at runtime.
35
+ - Make `opal:assets` generate `.rb` files in the active Opal source root.
36
+ - Update the sandbox flow to run an initial `opal:build`.
37
+ - Drop Rails 6.x support and require Ruby 2.7+.
38
+ - Add Rails 8.0 and 8.1 support.
39
+ - Require Opal 1.7+ and move the active matrix to Opal 1.8.
40
+ - Add Opal master coverage and focus CI on Ruby 3.2 and 4.0.
41
+ - Require Haml 6+ for the optional `:opal` filter.
42
+
43
+ ### Removed
44
+
45
+ - Remove helper-side Opal loader integration and Sprockets path injection.
46
+
47
+ ### Fixed
48
+
49
+ - Stabilize browser-driven specs on Ruby 4.
50
+
21
51
  ## [2.0.4](https://github.com/opal/opal-rails/compare/v2.0.3...v2.0.4) - 2024-12-06
22
52
 
23
53
  ### Added
data/Gemfile CHANGED
@@ -6,11 +6,11 @@ case ENV['OPAL_VERSION']
6
6
  when 'local'
7
7
  gem 'opal', path: '../opal'
8
8
  gem 'opal-rspec', path: '../opal-rspec'
9
- gem 'opal-sprockets', path: '../opal-sprockets'
10
9
  gem 'pry'
11
10
  when 'master'
12
11
  gem 'opal', git: github['opal/opal'], branch: :master
13
- gem 'opal-sprockets', git: github['opal/opal-sprockets'], branch: :master
14
12
  end
15
13
 
16
14
  gem 'net-smtp'
15
+
16
+ gem "gem-release", "~> 2.2"
data/PORTING.md ADDED
@@ -0,0 +1,140 @@
1
+ # Porting opal-rails 2.x to 3.x
2
+
3
+ `opal-rails` 3.x drops the old Sprockets-era Opal pipeline and moves Opal assets to an explicit build step.
4
+
5
+ ## What changes
6
+
7
+ - Opal source files are built into `app/assets/builds`
8
+ - `opal:build` replaces request-time Opal compilation
9
+ - `opal:watch` replaces the old edit-refresh flow for development
10
+ - `manifest.js` should link built assets, not raw Opal source files
11
+ - old `Opal.use_gem` / `Opal.append_path` setup in `config/initializers/assets.rb` should move to `config/initializers/opal.rb`
12
+
13
+ ## Fast path
14
+
15
+ For a fresh install, or for an app you are intentionally reshaping into the 3.x build layout in one pass, you can run:
16
+
17
+ ```bash
18
+ bin/rails g opal:install
19
+ ```
20
+
21
+ Do not treat that generator as a safe in-place upgrade for an existing 2.x app that already has legacy Opal assets wired in. In a real Rails 7 `2.0.4 -> 3.x` upgrade repro, it layered 3.x files on top of the old setup and still left the app in a broken state. For those apps, pin `opal-rails` to the `2.0` series until you can port deliberately, or follow the manual checklist below.
22
+
23
+ The generator now:
24
+
25
+ - creates `config/initializers/opal.rb` with build-based defaults
26
+ - creates `app/assets/builds/.keep`
27
+ - links `app/assets/builds` from `app/assets/config/manifest.js` when that file exists
28
+ - sets `config.assets.debug = true` in `config/environments/test.rb` when that file exists so tests prefer freshly rebuilt assets over stale checked-in digests
29
+ - creates or updates `Procfile.dev` with `opal: bin/rails opal:watch`
30
+ - creates `bin/dev` when missing, or replaces an existing `bin/dev` that does not reference `Procfile.dev` (Rails 8.1+ generates a `bin/dev` that just execs `rails server`); the generated launcher installs `foreman` if needed and runs `Procfile.dev`
31
+
32
+ ## Manual migration checklist
33
+
34
+ 1. Move your Opal entrypoints to either:
35
+ - `app/opal` for a greenfield-style layout, or
36
+ - `app/assets/opal` for a migration-friendly layout
37
+ 2. Configure Opal in `config/initializers/opal.rb`.
38
+
39
+ For a single entrypoint:
40
+
41
+ ```ruby
42
+ Rails.application.configure do
43
+ config.opal.source_path = Rails.root.join("app/opal")
44
+ config.opal.entrypoints_path = config.opal.source_path
45
+ config.opal.entrypoints = { "application" => "application.rb" }
46
+ config.opal.use_gems = []
47
+ end
48
+ ```
49
+
50
+ For multi-entrypoint apps that keep Opal files under `app/assets/opal`:
51
+
52
+ ```ruby
53
+ Rails.application.configure do
54
+ config.opal.source_path = Rails.root.join("app/assets/opal")
55
+ config.opal.entrypoints_path = config.opal.source_path
56
+ config.opal.entrypoints = :all
57
+ config.opal.use_gems = %w[some-gem]
58
+ end
59
+ ```
60
+
61
+ If you keep Opal sources under `app/assets/opal`, take care of asset serving explicitly: `opal-rails` no longer hides that directory from the host asset pipeline for you.
62
+
63
+ - Propshaft apps should add an exclusion when they would otherwise serve or fingerprint raw files from `app/assets/opal`:
64
+
65
+ ```ruby
66
+ config.assets.excluded_paths << Rails.root.join("app/assets/opal")
67
+ ```
68
+
69
+ - Sprockets apps should make sure `app/assets/config/manifest.js` links only `app/assets/builds`, and should remove old raw-source links such as `link_tree ../opal`, `link_directory ../opal`, `require_tree`, or other directives that expose `app/assets/opal` directly.
70
+
71
+ You only need that extra asset-pipeline care when you keep the migration-friendly `app/assets/opal` layout. The default `app/opal` layout stays outside the asset load path, so there is nothing extra to exclude.
72
+
73
+ 3. Remove old Opal load-path setup from `config/initializers/assets.rb`, such as:
74
+
75
+ ```ruby
76
+ Opal.use_gem "some-gem"
77
+ Opal.append_path Rails.root.join("app", "assets", "opal")
78
+ ```
79
+
80
+ and move it into `config.opal.use_gems` / `config.opal.append_paths`.
81
+
82
+ 4. Update `app/assets/config/manifest.js` to link built outputs instead of raw Opal source files:
83
+
84
+ ```js
85
+ //= link_directory ../builds .js
86
+ //= link_directory ../builds .map
87
+ ```
88
+
89
+ If you do not want production builds to generate and serve Opal source maps, disable them in `config/environments/production.rb`:
90
+
91
+ ```ruby
92
+ config.opal.source_map_enabled = false
93
+ ```
94
+
95
+ That keeps the shared manifest configuration intact while stopping `opal:build` / `assets:precompile` from emitting `app/assets/builds/*.js.map` in production.
96
+
97
+ 5. Build assets explicitly (one-off check):
98
+
99
+ ```bash
100
+ bin/rails opal:build
101
+ ```
102
+
103
+ In practice you rarely need to run this manually — `opal-rails` wires `opal:build` into the standard Rake lifecycle automatically (see below).
104
+
105
+ 6. Include the built asset in your layout with the normal Rails helper:
106
+
107
+ ```erb
108
+ <%= javascript_include_tag "application", "data-turbo-track": "reload" %>
109
+ ```
110
+
111
+ or use your own logical asset name if the app already has a different `application.js`.
112
+
113
+ ## Development and test
114
+
115
+ ### Development
116
+
117
+ The recommended flow is `bin/dev`, which uses Foreman to run both the Rails server and `opal:watch` together via `Procfile.dev`. If you prefer to run processes separately, start `bin/rails opal:watch` in a second terminal while editing Opal files.
118
+
119
+ ### Test
120
+
121
+ `opal-rails` hooks `opal:build` into these Rake tasks automatically:
122
+
123
+ | Trigger | How it works |
124
+ |---|---|
125
+ | `rake assets:precompile` | `opal:build` runs first (production deploys) |
126
+ | `rake assets:clobber` | `opal:clobber` cleans build outputs |
127
+ | `rake test` / `rake spec` | `test:prepare` (or `spec:prepare`) runs first, which triggers `opal:build` |
128
+ | `bin/rails test` | Rails' built-in `test:prepare` triggers `opal:build` |
129
+
130
+ This means `rake test` and `bin/rails test` both rebuild Opal assets before tests run. You should not need to run `opal:build` manually before running tests.
131
+
132
+ If your repo keeps old checked-in `public/assets` digests, set `config.assets.debug = true` in `config/environments/test.rb` so system tests resolve the rebuilt files from `app/assets/builds` instead of stale manifest entries.
133
+
134
+ ## What to remove from old 2.x apps
135
+
136
+ - request-time Opal compilation assumptions
137
+ - `app/assets/javascripts/*.js.rb` as the primary entrypoint pattern
138
+ - raw Opal source links in `manifest.js`
139
+ - helper-side Sprockets loader assumptions
140
+ - `opal-sprockets`-specific setup