railpack 1.3.0 → 1.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b714e261e3a676ca82d2ea8b33bb47cdf23de847ab367c50edd500883ce1d5a
4
- data.tar.gz: c12f5f2c37108aba8bc3f565ce80a3441895b2eada01a127f33129f15ec28f4f
3
+ metadata.gz: a06a90b1e32f31cb61a8e4195377b2fa0c75644e12334d66da498d0e6263e1cd
4
+ data.tar.gz: 7b6f6024e1e816fe4041db5fd5f381b4aa58817cdcae6bf9b640a23ee02f1471
5
5
  SHA512:
6
- metadata.gz: 364d8756b8fe2139b37fecc94196e44f56e05a238bedfca6618d8485ceb1f0e1bed9bf5ae08dc0f424055f431146a68d2406b34e65ba84e1f88a671507cd6841
7
- data.tar.gz: bd7b094432e4a15707f1878a1c5045187892247ae38a1f41cbf42823a4681b2ff217d220e02fff73528213fcf15d1973f5b3aebfddf6f13d721639be45aa1098
6
+ metadata.gz: 7b104f484834edc82f3cf5c65e302a06d50da641b9aea37365db6026ab98259a0f09d2686c62c610322b08ba435e4e94505ff6a438d7dbde6499cf7682de3774
7
+ data.tar.gz: 616276fbd54eb9102a70b21c3fe26c8ee2ef06ad4136f6dfcf461f88668e9a1cc1dd0dc9bd10a7e35341e7eb53358a3a5f9413bac886c5d5d3ee3b59ffc87aaa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.2] - 2026-01-26
4
+
5
+ This patch release includes the final dependency fix.
6
+
7
+ ### Changes
8
+
9
+ - **Dependencies**: Added missing `require 'fileutils'` for proper FileUtils usage
10
+
11
+ ## [1.3.1] - 2026-01-26
12
+
13
+ This patch release includes final polish and documentation improvements.
14
+
15
+ ### Changes
16
+
17
+ - **Code style**: Properly indented private methods and removed duplicate `private` keyword
18
+ - **Pre-build validation**: Added `FileUtils.mkdir_p(outdir)` to ensure output directories exist before build
19
+ - **Documentation**: Added comprehensive examples for `analyze_bundle` (gzip output), build hooks (payload details), and manifest delegation
20
+
3
21
  ## [1.3.0] - 2026-01-26
4
22
 
5
23
  ### 🚀 **Major Architecture Refactoring**
data/README.md CHANGED
@@ -43,6 +43,7 @@ default:
43
43
  sourcemap: false
44
44
  entrypoint: "./app/javascript/application.js"
45
45
  outdir: "app/assets/builds"
46
+ analyze_bundle: false # Enable for gzip size reporting
46
47
 
47
48
  # Bundler-specific config
48
49
  bun:
@@ -52,9 +53,11 @@ bun:
52
53
  # Environment overrides
53
54
  development:
54
55
  sourcemap: true
56
+ analyze_bundle: true # Show gzip sizes in dev
55
57
 
56
58
  production:
57
59
  minify: true
60
+ analyze_bundle: true # Production bundle analysis
58
61
  ```
59
62
 
60
63
  ## Usage
@@ -111,6 +114,61 @@ Railpack.on_build_complete do |result|
111
114
  end
112
115
  ```
113
116
 
117
+ ### Advanced Usage
118
+
119
+ #### Bundle Analysis with Gzip
120
+
121
+ Enable `analyze_bundle: true` to see both uncompressed and gzipped bundle sizes:
122
+
123
+ ```yaml
124
+ # config/railpack.yml
125
+ default:
126
+ analyze_bundle: true
127
+ ```
128
+
129
+ Output example:
130
+ ```
131
+ ✅ Build completed successfully in 45.23ms (1.23 MB (0.45 MB gzipped))
132
+ ```
133
+
134
+ #### Build Hooks with Payload Details
135
+
136
+ Hook payloads provide detailed information about build results:
137
+
138
+ ```ruby
139
+ # config/initializers/railpack.rb
140
+ Railpack.on_build_complete do |payload|
141
+ if payload[:success]
142
+ # Success payload: { success: true, config: {...}, duration: 45.23, bundle_size: "1.23 MB" }
143
+ Rails.logger.info "Build succeeded in #{payload[:duration]}ms - #{payload[:bundle_size]}"
144
+ else
145
+ # Error payload: { success: false, error: #<Error>, config: {...}, duration: 12.34 }
146
+ Rails.logger.error "Build failed after #{payload[:duration]}ms: #{payload[:error].message}"
147
+ end
148
+ end
149
+
150
+ Railpack.on_build_start do |config|
151
+ # Config hash contains all current settings
152
+ Rails.logger.info "Starting #{config['bundler']} build for #{Rails.env}"
153
+ end
154
+ ```
155
+
156
+ #### Manifest Generation
157
+
158
+ Railpack automatically detects your asset pipeline and generates appropriate manifests:
159
+
160
+ ```ruby
161
+ # For Propshaft (Rails 7+ default)
162
+ # Generates: app/assets/builds/.manifest.json
163
+ Railpack::Manifest::Propshaft.generate(config)
164
+
165
+ # For Sprockets (Rails < 7)
166
+ # Generates: app/assets/builds/.sprockets-manifest-*.json
167
+ Railpack::Manifest::Sprockets.generate(config)
168
+ ```
169
+
170
+ The manifest generation is handled automatically after each build, but you can trigger it manually if needed.
171
+
114
172
  ## Supported Bundlers
115
173
 
116
174
  ### Bun (Default)
@@ -1,4 +1,5 @@
1
1
  require 'digest'
2
+ require 'fileutils'
2
3
  require 'pathname'
3
4
  require 'zlib'
4
5
 
@@ -132,107 +133,107 @@ module Railpack
132
133
 
133
134
  private
134
135
 
135
- def create_bundler
136
- bundler_name = Railpack.config.bundler
137
- bundler_class = BUNDLERS[bundler_name]
136
+ def create_bundler
137
+ bundler_name = Railpack.config.bundler
138
+ bundler_class = BUNDLERS[bundler_name]
138
139
 
139
- unless bundler_class
140
- raise Error, "Unsupported bundler: #{bundler_name}. Available: #{BUNDLERS.keys.join(', ')}"
141
- end
140
+ unless bundler_class
141
+ raise Error, "Unsupported bundler: #{bundler_name}. Available: #{BUNDLERS.keys.join(', ')}"
142
+ end
142
143
 
143
- bundler_class.new(Railpack.config)
144
- end
144
+ bundler_class.new(Railpack.config)
145
+ end
145
146
 
146
- # Calculate human-readable bundle size with optional gzip compression
147
- def calculate_bundle_size(config)
148
- outdir = config['outdir']
149
- return 'unknown' unless outdir && Dir.exist?(outdir)
147
+ # Calculate human-readable bundle size with optional gzip compression
148
+ def calculate_bundle_size(config)
149
+ outdir = config['outdir']
150
+ return 'unknown' unless outdir && Dir.exist?(outdir)
150
151
 
151
- total_size = 0
152
- Dir.glob("#{outdir}/**/*.{js,css,map}").each do |file|
153
- total_size += File.size(file) if File.file?(file)
154
- end
152
+ total_size = 0
153
+ Dir.glob("#{outdir}/**/*.{js,css,map}").each do |file|
154
+ total_size += File.size(file) if File.file?(file)
155
+ end
155
156
 
156
- # Include gzip size if analyze_bundle is enabled
157
- if config['analyze_bundle']
158
- gzip_size = calculate_gzip_size(outdir)
159
- "#{human_size(total_size)} (#{human_size(gzip_size)} gzipped)"
160
- else
161
- human_size(total_size)
157
+ # Include gzip size if analyze_bundle is enabled
158
+ if config['analyze_bundle']
159
+ gzip_size = calculate_gzip_size(outdir)
160
+ "#{human_size(total_size)} (#{human_size(gzip_size)} gzipped)"
161
+ else
162
+ human_size(total_size)
163
+ end
164
+ rescue => error
165
+ Railpack.logger.debug "Bundle size calculation failed: #{error.message}"
166
+ 'unknown'
162
167
  end
163
- rescue => error
164
- Railpack.logger.debug "Bundle size calculation failed: #{error.message}"
165
- 'unknown'
166
- end
167
168
 
168
- # Calculate total gzip-compressed size of assets
169
- def calculate_gzip_size(outdir)
170
- Dir.glob("#{outdir}/**/*.{js,css}").sum do |file|
171
- next 0 unless File.file?(file)
172
- Zlib::Deflate.deflate(File.read(file)).bytesize
169
+ # Calculate total gzip-compressed size of assets
170
+ def calculate_gzip_size(outdir)
171
+ Dir.glob("#{outdir}/**/*.{js,css}").sum do |file|
172
+ next 0 unless File.file?(file)
173
+ Zlib::Deflate.deflate(File.read(file)).bytesize
174
+ end
175
+ rescue => error
176
+ Railpack.logger.debug "Gzip size calculation failed: #{error.message}"
177
+ 0
173
178
  end
174
- rescue => error
175
- Railpack.logger.debug "Gzip size calculation failed: #{error.message}"
176
- 0
177
- end
178
179
 
179
- # Convert bytes to human-readable format (B, KB, MB, GB)
180
- def human_size(bytes)
181
- units = %w[B KB MB GB]
182
- size = bytes.to_f
183
- units.each do |unit|
184
- return "#{(size).round(2)} #{unit}" if size < 1024
185
- size /= 1024
180
+ # Convert bytes to human-readable format (B, KB, MB, GB)
181
+ def human_size(bytes)
182
+ units = %w[B KB MB GB]
183
+ size = bytes.to_f
184
+ units.each do |unit|
185
+ return "#{(size).round(2)} #{unit}" if size < 1024
186
+ size /= 1024
187
+ end
186
188
  end
187
- end
188
189
 
189
- def generate_asset_manifest(config)
190
- outdir = config['outdir']
191
- return unless outdir && Dir.exist?(outdir)
190
+ def generate_asset_manifest(config)
191
+ outdir = config['outdir']
192
+ return unless outdir && Dir.exist?(outdir)
192
193
 
193
- # Detect asset pipeline type and delegate to appropriate manifest generator
194
- pipeline_type = detect_asset_pipeline
195
- manifest_class = Railpack::Manifest.const_get(pipeline_type.capitalize)
194
+ # Detect asset pipeline type and delegate to appropriate manifest generator
195
+ pipeline_type = detect_asset_pipeline
196
+ manifest_class = Railpack::Manifest.const_get(pipeline_type.capitalize)
196
197
 
197
- manifest_class.generate(config)
198
- rescue => error
199
- # Enhanced error logging with context
200
- asset_files = Dir.glob("#{outdir}/**/*.{js,css}").length rescue 0
201
- Railpack.logger.warn "⚠️ Failed to generate #{pipeline_type} asset manifest for #{outdir} (#{asset_files} assets): #{error.message}"
202
- end
198
+ manifest_class.generate(config)
199
+ rescue => error
200
+ # Enhanced error logging with context
201
+ asset_files = Dir.glob("#{outdir}/**/*.{js,css}").length rescue 0
202
+ Railpack.logger.warn "⚠️ Failed to generate #{pipeline_type} asset manifest for #{outdir} (#{asset_files} assets): #{error.message}"
203
+ end
203
204
 
204
- # Validate output directory exists and is writable before build
205
- def validate_output_directory(config)
206
- outdir = config['outdir']
207
- return unless outdir
205
+ # Validate output directory exists and is writable before build
206
+ def validate_output_directory(config)
207
+ outdir = config['outdir']
208
+ return unless outdir
208
209
 
209
- unless Dir.exist?(outdir)
210
- Railpack.logger.warn "⚠️ Output directory #{outdir} does not exist - assets will be created on first build"
210
+ unless Dir.exist?(outdir)
211
+ Railpack.logger.warn "⚠️ Output directory #{outdir} does not exist - assets will be created on first build"
212
+ # Ensure directory exists to prevent early build failures
213
+ FileUtils.mkdir_p(outdir)
214
+ end
211
215
  end
212
- end
213
216
 
214
- def detect_asset_pipeline
215
- # Check Rails.application.config.assets class directly (more reliable)
216
- if defined?(Rails) && Rails.respond_to?(:application) && Rails.application
217
- assets_config = Rails.application.config.assets
218
- if assets_config.is_a?(Propshaft::Assembler) || defined?(Propshaft::Assembler)
217
+ def detect_asset_pipeline
218
+ # Check Rails.application.config.assets class directly (more reliable)
219
+ if defined?(Rails) && Rails.respond_to?(:application) && Rails.application
220
+ assets_config = Rails.application.config.assets
221
+ if assets_config.is_a?(Propshaft::Assembler) || defined?(Propshaft::Assembler)
222
+ :propshaft
223
+ elsif defined?(Sprockets::Manifest)
224
+ :sprockets
225
+ end
226
+ end
227
+
228
+ # Fallback to version-based detection
229
+ if defined?(Rails) && Rails.version.to_f >= 7.0
219
230
  :propshaft
220
- elsif defined?(Sprockets::Manifest)
231
+ elsif defined?(Rails) && Rails.version.to_f < 7.0 && defined?(Sprockets)
221
232
  :sprockets
233
+ else
234
+ # Safe default for modern Rails
235
+ :propshaft
222
236
  end
223
237
  end
224
-
225
- # Fallback to version-based detection
226
- if defined?(Rails) && Rails.version.to_f >= 7.0
227
- :propshaft
228
- elsif defined?(Rails) && Rails.version.to_f < 7.0 && defined?(Sprockets)
229
- :sprockets
230
- else
231
- # Safe default for modern Rails
232
- :propshaft
233
- end
234
- end
235
-
236
-
237
238
  end
238
- end
239
+ end
@@ -1,3 +1,3 @@
1
1
  module Railpack
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - 21tycoons LLC