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 +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +58 -0
- data/lib/railpack/manager.rb +83 -82
- data/lib/railpack/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a06a90b1e32f31cb61a8e4195377b2fa0c75644e12334d66da498d0e6263e1cd
|
|
4
|
+
data.tar.gz: 7b6f6024e1e816fe4041db5fd5f381b4aa58817cdcae6bf9b640a23ee02f1471
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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)
|
data/lib/railpack/manager.rb
CHANGED
|
@@ -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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
def create_bundler
|
|
137
|
+
bundler_name = Railpack.config.bundler
|
|
138
|
+
bundler_class = BUNDLERS[bundler_name]
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
unless bundler_class
|
|
141
|
+
raise Error, "Unsupported bundler: #{bundler_name}. Available: #{BUNDLERS.keys.join(', ')}"
|
|
142
|
+
end
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
bundler_class.new(Railpack.config)
|
|
145
|
+
end
|
|
145
146
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
def generate_asset_manifest(config)
|
|
191
|
+
outdir = config['outdir']
|
|
192
|
+
return unless outdir && Dir.exist?(outdir)
|
|
192
193
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
210
|
-
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
|
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
|
data/lib/railpack/version.rb
CHANGED