shakapacker 8.4.0 → 9.7.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 (265) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/address-review.md +206 -0
  3. data/.claude/commands/update-changelog.md +354 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +6 -9
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +6 -8
  6. data/.github/STATUS.md +1 -0
  7. data/.github/actionlint-matcher.json +17 -0
  8. data/.github/workflows/claude-code-review.yml +45 -0
  9. data/.github/workflows/claude.yml +55 -0
  10. data/.github/workflows/dummy.yml +18 -5
  11. data/.github/workflows/eslint-validation.yml +46 -0
  12. data/.github/workflows/generator.yml +38 -22
  13. data/.github/workflows/node.yml +116 -2
  14. data/.github/workflows/ruby.yml +57 -15
  15. data/.github/workflows/test-bundlers.yml +180 -0
  16. data/.gitignore +27 -0
  17. data/.husky/pre-commit +2 -0
  18. data/.npmignore +56 -0
  19. data/.prettierignore +7 -0
  20. data/.rubocop.yml +2 -0
  21. data/.yalcignore +26 -0
  22. data/CHANGELOG.md +487 -19
  23. data/CLAUDE.md +63 -0
  24. data/CONTRIBUTING.md +268 -21
  25. data/ESLINT_TECHNICAL_DEBT.md +165 -0
  26. data/README.md +497 -137
  27. data/Rakefile +44 -4
  28. data/TODO.md +58 -0
  29. data/TODO_v9.md +97 -0
  30. data/bin/conductor-exec +24 -0
  31. data/bin/shakapacker-config +11 -0
  32. data/conductor-setup.sh +147 -0
  33. data/conductor.json +9 -0
  34. data/docs/api-reference.md +519 -0
  35. data/docs/cdn_setup.md +384 -0
  36. data/docs/common-upgrades.md +695 -0
  37. data/docs/configuration.md +845 -0
  38. data/docs/css-modules-export-mode.md +566 -0
  39. data/docs/customizing_babel_config.md +16 -16
  40. data/docs/deployment.md +78 -7
  41. data/docs/developing_shakapacker.md +6 -0
  42. data/docs/early_hints.md +433 -0
  43. data/docs/early_hints_manual_api.md +454 -0
  44. data/docs/feature_testing.md +492 -0
  45. data/docs/node_package_api.md +70 -0
  46. data/docs/optional-peer-dependencies.md +203 -0
  47. data/docs/peer-dependencies.md +71 -0
  48. data/docs/precompile_hook.md +486 -0
  49. data/docs/preventing_fouc.md +132 -0
  50. data/docs/react.md +58 -48
  51. data/docs/releasing.md +288 -0
  52. data/docs/rspack.md +218 -0
  53. data/docs/rspack_migration_guide.md +862 -0
  54. data/docs/sprockets.md +1 -0
  55. data/docs/style_loader_vs_mini_css.md +12 -12
  56. data/docs/subresource_integrity.md +13 -7
  57. data/docs/transpiler-migration.md +212 -0
  58. data/docs/transpiler-performance.md +200 -0
  59. data/docs/troubleshooting.md +272 -24
  60. data/docs/typescript-migration.md +388 -0
  61. data/docs/typescript.md +103 -0
  62. data/docs/using_esbuild_loader.md +12 -12
  63. data/docs/using_swc_loader.md +121 -16
  64. data/docs/v6_upgrade.md +42 -19
  65. data/docs/v7_upgrade.md +8 -6
  66. data/docs/v8_upgrade.md +13 -12
  67. data/docs/v9_upgrade.md +616 -0
  68. data/eslint.config.fast.js +254 -0
  69. data/eslint.config.js +309 -0
  70. data/jest.config.js +8 -1
  71. data/knip.ts +61 -0
  72. data/lib/install/bin/shakapacker +4 -6
  73. data/lib/install/bin/shakapacker-config +11 -0
  74. data/lib/install/bin/shakapacker-dev-server +1 -1
  75. data/lib/install/binstubs.rb +6 -2
  76. data/lib/install/config/rspack/rspack.config.js +6 -0
  77. data/lib/install/config/rspack/rspack.config.ts +7 -0
  78. data/lib/install/config/shakapacker.yml +75 -12
  79. data/lib/install/config/webpack/webpack.config.ts +7 -0
  80. data/lib/install/package.json +38 -0
  81. data/lib/install/template.rb +207 -45
  82. data/lib/shakapacker/build_config_loader.rb +147 -0
  83. data/lib/shakapacker/bundler_switcher.rb +415 -0
  84. data/lib/shakapacker/compiler.rb +87 -0
  85. data/lib/shakapacker/configuration.rb +475 -6
  86. data/lib/shakapacker/dev_server.rb +88 -1
  87. data/lib/shakapacker/dev_server_runner.rb +240 -6
  88. data/lib/shakapacker/doctor.rb +1191 -0
  89. data/lib/shakapacker/env.rb +19 -3
  90. data/lib/shakapacker/helper.rb +411 -14
  91. data/lib/shakapacker/install/env.rb +33 -0
  92. data/lib/shakapacker/instance.rb +93 -4
  93. data/lib/shakapacker/manifest.rb +167 -30
  94. data/lib/shakapacker/railtie.rb +4 -0
  95. data/lib/shakapacker/rspack_runner.rb +19 -0
  96. data/lib/shakapacker/runner.rb +668 -9
  97. data/lib/shakapacker/swc_migrator.rb +384 -0
  98. data/lib/shakapacker/utils/manager.rb +2 -0
  99. data/lib/shakapacker/utils/version_syntax_converter.rb +1 -1
  100. data/lib/shakapacker/version.rb +1 -1
  101. data/lib/shakapacker/version_checker.rb +1 -1
  102. data/lib/shakapacker/webpack_runner.rb +4 -42
  103. data/lib/shakapacker.rb +159 -1
  104. data/lib/tasks/shakapacker/binstubs.rake +4 -2
  105. data/lib/tasks/shakapacker/check_binstubs.rake +2 -2
  106. data/lib/tasks/shakapacker/doctor.rake +48 -0
  107. data/lib/tasks/shakapacker/export_bundler_config.rake +68 -0
  108. data/lib/tasks/shakapacker/install.rake +16 -4
  109. data/lib/tasks/shakapacker/migrate_to_swc.rake +13 -0
  110. data/lib/tasks/shakapacker/switch_bundler.rake +72 -0
  111. data/lib/tasks/shakapacker.rake +2 -0
  112. data/package/.npmignore +4 -0
  113. data/package/babel/preset.ts +59 -0
  114. data/package/config.ts +189 -0
  115. data/package/configExporter/buildValidator.ts +906 -0
  116. data/package/configExporter/cli.ts +1748 -0
  117. data/package/configExporter/configDocs.ts +102 -0
  118. data/package/configExporter/configFile.ts +663 -0
  119. data/package/configExporter/fileWriter.ts +112 -0
  120. data/package/configExporter/index.ts +15 -0
  121. data/package/configExporter/types.ts +159 -0
  122. data/package/configExporter/yamlSerializer.ts +391 -0
  123. data/package/dev_server.ts +27 -0
  124. data/package/env.ts +92 -0
  125. data/package/environments/__type-tests__/rspack-plugin-compatibility.ts +36 -0
  126. data/package/environments/base.ts +147 -0
  127. data/package/environments/development.ts +88 -0
  128. data/package/environments/production.ts +82 -0
  129. data/package/environments/test.ts +55 -0
  130. data/package/environments/types.ts +98 -0
  131. data/package/esbuild/index.ts +40 -0
  132. data/package/index.d.ts +68 -93
  133. data/package/index.d.ts.template +72 -0
  134. data/package/index.ts +104 -0
  135. data/package/loaders.d.ts +28 -0
  136. data/package/optimization/rspack.ts +36 -0
  137. data/package/optimization/webpack.ts +55 -0
  138. data/package/plugins/envFilter.ts +82 -0
  139. data/package/plugins/rspack.ts +119 -0
  140. data/package/plugins/webpack.ts +82 -0
  141. data/package/rspack/index.ts +91 -0
  142. data/package/rules/{babel.js → babel.ts} +2 -2
  143. data/package/rules/{coffee.js → coffee.ts} +1 -1
  144. data/package/rules/css.ts +3 -0
  145. data/package/rules/{erb.js → erb.ts} +1 -1
  146. data/package/rules/esbuild.ts +10 -0
  147. data/package/rules/file.ts +41 -0
  148. data/package/rules/{jscommon.js → jscommon.ts} +5 -4
  149. data/package/rules/{less.js → less.ts} +4 -4
  150. data/package/rules/raw.ts +28 -0
  151. data/package/rules/rspack.ts +174 -0
  152. data/package/rules/sass.ts +21 -0
  153. data/package/rules/{stylus.js → stylus.ts} +4 -8
  154. data/package/rules/swc.ts +10 -0
  155. data/package/rules/{index.js → webpack.ts} +1 -2
  156. data/package/swc/index.ts +54 -0
  157. data/package/types/README.md +90 -0
  158. data/package/types/index.ts +69 -0
  159. data/package/types.ts +105 -0
  160. data/package/utils/bundlerUtils.ts +232 -0
  161. data/package/utils/configPath.ts +6 -0
  162. data/package/utils/debug.ts +45 -0
  163. data/package/utils/defaultConfigPath.ts +7 -0
  164. data/package/utils/ensureManifestExists.ts +17 -0
  165. data/package/utils/errorCodes.ts +249 -0
  166. data/package/utils/errorHelpers.ts +152 -0
  167. data/package/utils/getStyleRule.ts +75 -0
  168. data/package/utils/helpers.ts +99 -0
  169. data/package/utils/{inliningCss.js → inliningCss.ts} +3 -3
  170. data/package/utils/pathValidation.ts +207 -0
  171. data/package/utils/requireOrError.ts +24 -0
  172. data/package/utils/snakeToCamelCase.ts +5 -0
  173. data/package/utils/typeGuards.ts +388 -0
  174. data/package/utils/validateDependencies.ts +61 -0
  175. data/package/webpack-types.d.ts +33 -0
  176. data/package/webpackDevServerConfig.ts +130 -0
  177. data/package.json +157 -18
  178. data/scripts/remove-use-strict.js +44 -0
  179. data/scripts/type-check-no-emit.js +27 -0
  180. data/shakapacker.gemspec +4 -2
  181. data/sig/shakapacker/commands.rbs +35 -0
  182. data/sig/shakapacker/compiler.rbs +65 -0
  183. data/sig/shakapacker/compiler_strategy.rbs +41 -0
  184. data/sig/shakapacker/configuration.rbs +140 -0
  185. data/sig/shakapacker/dev_server.rbs +56 -0
  186. data/sig/shakapacker/env.rbs +25 -0
  187. data/sig/shakapacker/helper.rbs +98 -0
  188. data/sig/shakapacker/instance.rbs +46 -0
  189. data/sig/shakapacker/manifest.rbs +69 -0
  190. data/sig/shakapacker/version.rbs +4 -0
  191. data/sig/shakapacker.rbs +66 -0
  192. data/test/configExporter/buildValidator.test.js +1295 -0
  193. data/test/configExporter/configFile.test.js +393 -0
  194. data/test/configExporter/integration.test.js +262 -0
  195. data/test/helpers.js +1 -1
  196. data/test/package/bundlerUtils.rspack.test.js +145 -0
  197. data/test/package/bundlerUtils.test.js +97 -0
  198. data/test/package/config.test.js +14 -0
  199. data/test/package/configExporter/cli.test.js +440 -0
  200. data/test/package/configExporter/types.test.js +163 -0
  201. data/test/package/configExporter.test.js +491 -0
  202. data/test/package/env.test.js +42 -7
  203. data/test/package/environments/base.test.js +14 -4
  204. data/test/package/helpers.test.js +2 -2
  205. data/test/package/plugins/envFiltering.test.js +453 -0
  206. data/test/package/plugins/webpackSubresourceIntegrity.test.js +89 -0
  207. data/test/package/rspack/index.test.js +293 -0
  208. data/test/package/rspack/optimization.test.js +86 -0
  209. data/test/package/rspack/plugins.test.js +185 -0
  210. data/test/package/rspack/rules.test.js +229 -0
  211. data/test/package/rules/babel.test.js +65 -38
  212. data/test/package/rules/esbuild.test.js +13 -4
  213. data/test/package/rules/file.test.js +7 -1
  214. data/test/package/rules/raw.test.js +40 -7
  215. data/test/package/rules/sass-version-parsing.test.js +71 -0
  216. data/test/package/rules/sass.test.js +11 -6
  217. data/test/package/rules/sass1.test.js +8 -5
  218. data/test/package/rules/sass16.test.js +24 -0
  219. data/test/package/rules/swc.test.js +50 -39
  220. data/test/package/rules/webpack.test.js +35 -0
  221. data/test/package/staging.test.js +4 -3
  222. data/test/package/transpiler-defaults.test.js +169 -0
  223. data/test/package/utils/ensureManifestExists.test.js +51 -0
  224. data/test/package/yamlSerializer.test.js +204 -0
  225. data/test/peer-dependencies.sh +85 -0
  226. data/test/resolver.js +34 -3
  227. data/test/scripts/remove-use-strict.test.js +125 -0
  228. data/test/typescript/build.test.js +118 -0
  229. data/test/typescript/environments.test.js +107 -0
  230. data/test/typescript/pathValidation.test.js +186 -0
  231. data/test/typescript/requireOrError.test.js +49 -0
  232. data/test/typescript/securityValidation.test.js +182 -0
  233. data/tools/README.md +134 -0
  234. data/tools/css-modules-v9-codemod.js +179 -0
  235. data/tsconfig.eslint.json +9 -0
  236. data/tsconfig.json +38 -0
  237. data/yarn.lock +3202 -1097
  238. metadata +212 -44
  239. data/.eslintignore +0 -4
  240. data/.eslintrc.js +0 -36
  241. data/Gemfile.lock +0 -251
  242. data/package/babel/preset.js +0 -48
  243. data/package/config.js +0 -56
  244. data/package/dev_server.js +0 -23
  245. data/package/env.js +0 -48
  246. data/package/environments/base.js +0 -171
  247. data/package/environments/development.js +0 -13
  248. data/package/environments/production.js +0 -88
  249. data/package/environments/test.js +0 -3
  250. data/package/esbuild/index.js +0 -40
  251. data/package/index.js +0 -40
  252. data/package/rules/css.js +0 -3
  253. data/package/rules/esbuild.js +0 -10
  254. data/package/rules/file.js +0 -29
  255. data/package/rules/raw.js +0 -5
  256. data/package/rules/sass.js +0 -18
  257. data/package/rules/swc.js +0 -10
  258. data/package/swc/index.js +0 -50
  259. data/package/utils/configPath.js +0 -4
  260. data/package/utils/defaultConfigPath.js +0 -2
  261. data/package/utils/getStyleRule.js +0 -40
  262. data/package/utils/helpers.js +0 -62
  263. data/package/utils/snakeToCamelCase.js +0 -5
  264. data/package/webpackDevServerConfig.js +0 -71
  265. data/test/package/rules/index.test.js +0 -16
data/Rakefile CHANGED
@@ -2,6 +2,11 @@
2
2
  require "bundler/gem_tasks"
3
3
  require "pathname"
4
4
 
5
+ # Remove Bundler's default `release` task — it bypasses the custom release flow
6
+ # (CHANGELOG version detection, npm publish, GitHub release sync, etc.).
7
+ # The custom `release` task in rakelib/release.rake replaces it.
8
+ Rake::Task[:release].clear
9
+
5
10
  desc "Run all specs"
6
11
  task test: ["run_spec:all_specs"]
7
12
 
@@ -14,16 +19,51 @@ namespace :run_spec do
14
19
  sh("bundle exec rspec spec/shakapacker/*_spec.rb")
15
20
  end
16
21
 
17
- desc "Run specs in the dummy app"
22
+ desc "Run specs in the dummy app with webpack"
18
23
  task :dummy do
19
- puts "Running dummy app specs"
24
+ puts "Running dummy app specs with webpack"
25
+ spec_dummy_dir = Pathname.new(File.join("spec", "dummy")).realpath
26
+ Bundler.with_unbundled_env do
27
+ sh_in_dir(".", "yalc publish")
28
+ sh_in_dir(spec_dummy_dir, [
29
+ "bundle install",
30
+ "yalc link shakapacker",
31
+ "npm install",
32
+ "bin/test-bundler webpack",
33
+ "NODE_ENV=test RAILS_ENV=test bin/shakapacker",
34
+ "bundle exec rspec"
35
+ ])
36
+ end
37
+ end
38
+
39
+ desc "Run specs in the dummy app with rspack"
40
+ task :dummy_with_rspack do
41
+ puts "Running dummy app specs with rspack"
20
42
  spec_dummy_dir = Pathname.new(File.join("spec", "dummy")).realpath
21
43
  Bundler.with_unbundled_env do
22
44
  sh_in_dir(".", "yalc publish")
23
45
  sh_in_dir(spec_dummy_dir, [
24
46
  "bundle install",
25
47
  "yalc link shakapacker",
26
- "yarn install",
48
+ "npm install",
49
+ "bin/test-bundler rspack",
50
+ "NODE_ENV=test RAILS_ENV=test bin/shakapacker",
51
+ "bundle exec rspec"
52
+ ])
53
+ end
54
+ end
55
+
56
+ desc "Run specs in the dummy-rspack app"
57
+ task :dummy_rspack do
58
+ puts "Running dummy-rspack app specs"
59
+ spec_dummy_dir = Pathname.new(File.join("spec", "dummy-rspack")).realpath
60
+ Bundler.with_unbundled_env do
61
+ sh_in_dir(".", "yalc publish")
62
+ sh_in_dir(spec_dummy_dir, [
63
+ "bundle install",
64
+ "yalc link shakapacker",
65
+ "npm install",
66
+ "NODE_ENV=test RAILS_ENV=test npm exec --no -- rspack build --config config/rspack/rspack.config.js",
27
67
  "bundle exec rspec"
28
68
  ])
29
69
  end
@@ -35,7 +75,7 @@ namespace :run_spec do
35
75
  end
36
76
 
37
77
  desc "Run all specs"
38
- task all_specs: %i[gem dummy generator] do
78
+ task all_specs: %i[gem dummy dummy_with_rspack dummy_rspack generator] do
39
79
  puts "Completed all RSpec tests"
40
80
  end
41
81
  end
data/TODO.md ADDED
@@ -0,0 +1,58 @@
1
+ # TypeScript Migration Status
2
+
3
+ ## ✅ Completed (PR #602)
4
+
5
+ - Enhanced `package/index.d.ts` with comprehensive type definitions
6
+ - Added TypeScript type packages for better IDE support
7
+ - Improved Config and DevServerConfig interfaces
8
+ - Added missing properties (private_output_path, inline_css, env_prefix, etc.)
9
+ - All tests passing
10
+ - Zero JavaScript modifications (no whitespace changes)
11
+ - Full backward compatibility maintained
12
+
13
+ ## 📋 Next Steps (Issue #605)
14
+
15
+ ### Phase 2: Core Module Conversion
16
+
17
+ - [ ] Convert `package/config.js` to TypeScript
18
+ - [ ] Convert `package/env.js` to TypeScript
19
+ - [ ] Convert `package/index.js` to TypeScript
20
+ - [ ] Convert `package/utils/helpers.js` to TypeScript
21
+
22
+ ### Phase 3: Environment & Build System
23
+
24
+ - [ ] Convert environment files (base, development, production, test)
25
+ - [ ] Convert dev_server.js
26
+ - [ ] Convert webpackDevServerConfig.js
27
+
28
+ ### Phase 4: Rules & Loaders (PR #620) ✅
29
+
30
+ - [x] Convert all files in `package/rules/`
31
+ - [x] Convert all files in `package/plugins/`
32
+ - [x] Convert all files in `package/optimization/`
33
+
34
+ ### Phase 5: Framework-Specific Modules ✅
35
+
36
+ - [x] Convert rspack support files
37
+ - [x] Convert swc support files
38
+ - [x] Convert esbuild support files
39
+ - [x] Convert babel preset
40
+
41
+ ### Phase 6: Final Cleanup ✅
42
+
43
+ - [x] Add TypeScript linting with @typescript-eslint
44
+ - [x] Verify strict mode is enabled (already configured)
45
+ - [x] Update documentation
46
+
47
+ ## Why Gradual Migration?
48
+
49
+ - **Lower risk**: Each phase can be tested independently
50
+ - **Team learning**: Get familiar with TypeScript incrementally
51
+ - **Immediate value**: Type definitions already provide IDE benefits
52
+ - **No breaking changes**: Users unaffected during migration
53
+
54
+ ## Related Links
55
+
56
+ - Original issue: #200
57
+ - Initial PR: #602
58
+ - Next steps issue: #605
data/TODO_v9.md ADDED
@@ -0,0 +1,97 @@
1
+ # Shakapacker v9 TODO List
2
+
3
+ ## CSS Modules Configuration Alignment
4
+
5
+ ### Problem
6
+
7
+ Current CSS modules configuration causes TypeScript/webpack warnings because of default vs named export mismatch.
8
+
9
+ ### Current Behavior (v8)
10
+
11
+ - CSS modules use default export: `import styles from './styles.module.css'`
12
+ - This causes warnings but works at runtime
13
+ - Warning example: `export 'default' (imported as 'style') was not found in './HelloWorld.module.css'`
14
+
15
+ ### Proposed v9 Change
16
+
17
+ Align with Next.js and modern tooling by using named exports:
18
+
19
+ 1. **Update css-loader configuration:**
20
+
21
+ ```javascript
22
+ {
23
+ loader: 'css-loader',
24
+ options: {
25
+ modules: {
26
+ namedExport: true,
27
+ exportLocalsConvention: 'camelCaseOnly' // Must be 'camelCaseOnly' or 'dashesOnly' with namedExport: true
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ **Note:** Using `exportLocalsConvention: 'camelCase'` with `namedExport: true` will cause a build error.
34
+ css-loader only allows `'camelCaseOnly'` or `'dashesOnly'` when named exports are enabled.
35
+
36
+ 2. **Update TypeScript types:**
37
+
38
+ - Ensure proper typing for CSS modules with named exports
39
+ - May need to update or generate `.d.ts` files for CSS modules
40
+
41
+ 3. **Migration guide for users:**
42
+
43
+ - Document the breaking change
44
+ - Provide codemod or migration script to update imports from:
45
+ ```javascript
46
+ import styles from "./styles.module.css"
47
+ styles.className
48
+ ```
49
+ to:
50
+ ```javascript
51
+ import * as styles from "./styles.module.css"
52
+ // or
53
+ import { className } from "./styles.module.css"
54
+ ```
55
+
56
+ ### Benefits
57
+
58
+ - Eliminates webpack/TypeScript warnings
59
+ - Better tree-shaking potential
60
+ - More explicit about what CSS classes are being used
61
+ - Easier interoperability with frameworks that support named exports
62
+
63
+ ### Implementation Notes
64
+
65
+ - This is a BREAKING CHANGE and appropriate for major version bump
66
+ - Need to test with both webpack and rspack
67
+ - Consider providing a compatibility mode via configuration option
68
+
69
+ ---
70
+
71
+ ## Related Issues from PR #597
72
+
73
+ ### React Component Not Rendering (spec/dummy) - RESOLVED ✅
74
+
75
+ - **Issue**: React component was not rendering due to CSS module import mismatch
76
+ - **Symptoms**:
77
+ - Component wasn't rendering "Hello, Stranger!"
78
+ - Input field not rendered, making interactive test fail
79
+ - Only the static H1 "Hello, World!" was visible
80
+ - **Resolution**:
81
+ - Fixed CSS module import syntax from `import style from` to `import * as style from`
82
+ - This matched webpack's named exports configuration for CSS modules
83
+ - Tests now pass with both React 18.3.1 and webpack/rspack configurations
84
+ - **Root Cause**: CSS module import/export mismatch
85
+ - Webpack was configured to use named exports for CSS modules
86
+ - TypeScript code was using default import syntax
87
+ - This caused `style` to be undefined, breaking SSR and client rendering
88
+ - **Status**: FIXED
89
+ - All tests re-enabled and passing
90
+ - Both SSR and client-side rendering working
91
+ - Interactive functionality restored
92
+
93
+ ### Test Infrastructure
94
+
95
+ - Successfully implemented dual bundler support (webpack/rspack)
96
+ - test-bundler script working well with status command
97
+ - Consider adding more comprehensive tests for both bundlers
@@ -0,0 +1,24 @@
1
+ #!/bin/zsh
2
+ # Wrapper script to run commands in Conductor with proper tool versions
3
+ # Usage: bin/conductor-exec <command> [args...]
4
+ #
5
+ # This is needed because Conductor (and other non-interactive shells) don't
6
+ # source .zshrc, so version manager PATH configuration isn't active by default.
7
+ #
8
+ # - If mise is available: uses `mise exec` for correct tool versions
9
+ # - Otherwise: falls back to direct execution (for asdf/rbenv/nvm users)
10
+ #
11
+ # Examples:
12
+ # bin/conductor-exec ruby --version # Uses correct Ruby version
13
+ # bin/conductor-exec bundle exec rubocop # Correct Ruby for linting
14
+ # bin/conductor-exec git commit -m "msg" # Pre-commit hooks work correctly
15
+ # bin/conductor-exec yarn install # Uses correct Node version
16
+ #
17
+ # See: https://github.com/shakacode/react_on_rails-demos/issues/105
18
+
19
+ if command -v mise &> /dev/null; then
20
+ exec mise exec -- "$@"
21
+ else
22
+ # Fall back to direct execution for non-mise users
23
+ exec "$@"
24
+ fi
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Minimal shim - all logic is in the TypeScript module
4
+ const { run } = require("shakapacker/configExporter")
5
+
6
+ run(process.argv.slice(2))
7
+ .then((exitCode) => process.exit(exitCode))
8
+ .catch((error) => {
9
+ console.error(error.message)
10
+ process.exit(1)
11
+ })
@@ -0,0 +1,147 @@
1
+ #!/bin/zsh
2
+ set -euo pipefail
3
+
4
+ echo "🔧 Setting up Shakapacker workspace..."
5
+
6
+ # Detect and initialize version manager
7
+ # Supports: mise, asdf, or direct PATH (rbenv/nvm/nodenv already in PATH)
8
+ VERSION_MANAGER="none"
9
+
10
+ echo "📋 Detecting version manager..."
11
+
12
+ if command -v mise &> /dev/null; then
13
+ VERSION_MANAGER="mise"
14
+ echo "✅ Found mise"
15
+ # Trust mise config for current directory only
16
+ mise trust 2>/dev/null || true
17
+ elif [[ -f ~/.asdf/asdf.sh ]]; then
18
+ VERSION_MANAGER="asdf"
19
+ source ~/.asdf/asdf.sh
20
+ echo "✅ Found asdf (from ~/.asdf/asdf.sh)"
21
+ elif command -v asdf &> /dev/null; then
22
+ VERSION_MANAGER="asdf"
23
+ # For homebrew-installed asdf
24
+ if [[ -f /opt/homebrew/opt/asdf/libexec/asdf.sh ]]; then
25
+ source /opt/homebrew/opt/asdf/libexec/asdf.sh
26
+ fi
27
+ echo "✅ Found asdf"
28
+ else
29
+ echo "â„šī¸ No version manager detected, using system PATH"
30
+ echo " (Assuming rbenv/nvm/nodenv or system tools are already configured)"
31
+ fi
32
+
33
+ # Ensure version config exists for asdf/mise users
34
+ if [[ "$VERSION_MANAGER" != "none" ]] && [[ ! -f .tool-versions ]] && [[ ! -f .mise.toml ]]; then
35
+ echo "📝 Creating .tool-versions from project version files..."
36
+
37
+ # Read Ruby version from .ruby-version or use default
38
+ if [[ -f .ruby-version ]]; then
39
+ RUBY_VER=$(cat .ruby-version | tr -d '[:space:]')
40
+ else
41
+ RUBY_VER="3.3.4" # Default: recent stable Ruby
42
+ fi
43
+
44
+ # Read Node version from .node-version or use default
45
+ if [[ -f .node-version ]]; then
46
+ NODE_VER=$(cat .node-version | tr -d '[:space:]')
47
+ else
48
+ NODE_VER="20.18.0" # Default: LTS Node
49
+ fi
50
+
51
+ cat > .tool-versions << EOF
52
+ ruby $RUBY_VER
53
+ nodejs $NODE_VER
54
+ EOF
55
+ echo " Using Ruby $RUBY_VER, Node $NODE_VER"
56
+ fi
57
+
58
+ # Install tools via mise (after .tool-versions exists)
59
+ if [[ "$VERSION_MANAGER" == "mise" ]]; then
60
+ echo "đŸ“Ļ Installing tools via mise..."
61
+ mise install
62
+ fi
63
+
64
+ # Helper function to run commands with the detected version manager
65
+ run_cmd() {
66
+ if [[ "$VERSION_MANAGER" == "mise" ]] && [[ -x "bin/conductor-exec" ]]; then
67
+ bin/conductor-exec "$@"
68
+ else
69
+ "$@"
70
+ fi
71
+ }
72
+
73
+ # Check required tools
74
+ echo "📋 Checking required tools..."
75
+ run_cmd ruby --version >/dev/null 2>&1 || { echo "❌ Error: Ruby is not installed or not in PATH."; exit 1; }
76
+ run_cmd node --version >/dev/null 2>&1 || { echo "❌ Error: Node.js is not installed or not in PATH."; exit 1; }
77
+
78
+ # Check Ruby version
79
+ RUBY_VERSION=$(run_cmd ruby -v | awk '{print $2}')
80
+ MIN_RUBY_VERSION="2.7.0"
81
+ if [[ $(echo -e "$MIN_RUBY_VERSION\n$RUBY_VERSION" | sort -V | head -n1) != "$MIN_RUBY_VERSION" ]]; then
82
+ echo "❌ Error: Ruby version $RUBY_VERSION is too old. Shakapacker requires Ruby >= 2.7.0"
83
+ echo " Please upgrade Ruby using your version manager or system package manager."
84
+ exit 1
85
+ fi
86
+ echo "✅ Ruby version: $RUBY_VERSION"
87
+
88
+ # Check Node version
89
+ NODE_VERSION=$(run_cmd node -v | cut -d'v' -f2)
90
+ MIN_NODE_VERSION="14.0.0"
91
+ if [[ $(echo -e "$MIN_NODE_VERSION\n$NODE_VERSION" | sort -V | head -n1) != "$MIN_NODE_VERSION" ]]; then
92
+ echo "❌ Error: Node.js version v$NODE_VERSION is too old. Shakapacker requires Node.js >= 14.0.0"
93
+ echo " Please upgrade Node.js using your version manager or system package manager."
94
+ exit 1
95
+ fi
96
+ echo "✅ Node.js version: v$NODE_VERSION"
97
+
98
+ # Copy any environment files from root if they exist
99
+ if [ -n "${CONDUCTOR_ROOT_PATH:-}" ]; then
100
+ if [ -f "$CONDUCTOR_ROOT_PATH/.env" ]; then
101
+ echo "📝 Copying .env file..."
102
+ cp "$CONDUCTOR_ROOT_PATH/.env" .env
103
+ fi
104
+
105
+ if [ -f "$CONDUCTOR_ROOT_PATH/.env.local" ]; then
106
+ echo "📝 Copying .env.local file..."
107
+ cp "$CONDUCTOR_ROOT_PATH/.env.local" .env.local
108
+ fi
109
+ fi
110
+
111
+ # Install Ruby dependencies
112
+ echo "💎 Installing Ruby dependencies..."
113
+ run_cmd bundle install
114
+
115
+ # Install JavaScript dependencies
116
+ echo "đŸ“Ļ Installing JavaScript dependencies..."
117
+ run_cmd yarn install --frozen-lockfile
118
+
119
+ # Set up Husky git hooks
120
+ echo "đŸĒ Setting up Husky git hooks..."
121
+ run_cmd npx husky
122
+ if [ ! -f .husky/pre-commit ]; then
123
+ echo "Creating pre-commit hook..."
124
+ cat > .husky/pre-commit << 'EOF'
125
+ #!/usr/bin/env sh
126
+ npx lint-staged
127
+ EOF
128
+ chmod +x .husky/pre-commit
129
+ fi
130
+
131
+ # Verify linting tools are available
132
+ echo "✅ Verifying linting tools..."
133
+ run_cmd bundle exec rubocop --version
134
+
135
+ echo "✨ Workspace setup complete!"
136
+ echo ""
137
+ echo "📚 Key commands:"
138
+ echo " â€ĸ bundle exec rspec - Run Ruby tests"
139
+ echo " â€ĸ bundle exec rake run_spec:gem - Run gem-specific tests"
140
+ echo " â€ĸ yarn test - Run JavaScript tests"
141
+ echo " â€ĸ yarn lint - Run JavaScript linting"
142
+ echo " â€ĸ bundle exec rubocop - Run Ruby linting (required before commits)"
143
+ echo ""
144
+ if [[ "$VERSION_MANAGER" == "mise" ]]; then
145
+ echo "💡 Tip: Use 'bin/conductor-exec <command>' if tool versions aren't detected correctly."
146
+ fi
147
+ echo "âš ī¸ Remember: Always run 'bundle exec rubocop' before committing!"
data/conductor.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "scripts": {
3
+ "setup": "./conductor-setup.sh",
4
+ "run": "bin/conductor-exec bundle exec rspec",
5
+ "test": "bin/conductor-exec bundle exec rspec",
6
+ "lint": "bin/conductor-exec bundle exec rubocop && bin/conductor-exec yarn lint",
7
+ "archive": ""
8
+ }
9
+ }