bundlebun 0.5.0.1.3.13-x86_64-linux-gnu
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 +7 -0
- data/CHANGELOG.md +69 -0
- data/LICENSE.txt +98 -0
- data/README.md +225 -0
- data/exe/bundlebun +27 -0
- data/lib/bundlebun/env_path.rb +54 -0
- data/lib/bundlebun/integrations/cssbundling.rb +50 -0
- data/lib/bundlebun/integrations/execjs.rb +46 -0
- data/lib/bundlebun/integrations/jsbundling.rb +50 -0
- data/lib/bundlebun/integrations/vite_ruby.rb +58 -0
- data/lib/bundlebun/integrations.rb +31 -0
- data/lib/bundlebun/platform.rb +19 -0
- data/lib/bundlebun/runner.rb +278 -0
- data/lib/bundlebun/vendor/bun/LICENSE.md +73 -0
- data/lib/bundlebun/vendor/bun/bun +0 -0
- data/lib/bundlebun/version.rb +12 -0
- data/lib/bundlebun.rb +130 -0
- data/lib/tasks/bun.rake +21 -0
- data/lib/tasks/install.rake +305 -0
- data/lib/templates/bundling-rails/bundlebun.rake +10 -0
- data/lib/templates/vite-ruby/bun-vite +13 -0
- data/lib/templates/vite-ruby/vite.json +16 -0
- data/sig/bundlebun/env_path.rbs +8 -0
- data/sig/bundlebun/integrations/cssbundling.rbs +12 -0
- data/sig/bundlebun/integrations/execjs.rbs +7 -0
- data/sig/bundlebun/integrations/jsbundling.rbs +12 -0
- data/sig/bundlebun/integrations/vite_ruby.rbs +12 -0
- data/sig/bundlebun/integrations.rbs +5 -0
- data/sig/bundlebun/platform.rbs +5 -0
- data/sig/bundlebun/runner.rbs +35 -0
- data/sig/bundlebun/version.rbs +3 -0
- data/sig/bundlebun.rbs +18 -0
- metadata +113 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundlebun
|
|
4
|
+
module Integrations
|
|
5
|
+
# An integration for [vite-ruby](https://github.com/ElMassimo/vite_ruby) and [vite-rails](https://vite-ruby.netlify.app).
|
|
6
|
+
#
|
|
7
|
+
# For that, we would need both to replace the vite binstub (as `bin/vite`
|
|
8
|
+
# exists by itself and does not really initialize this gem if it is installed),
|
|
9
|
+
# and redefine the {RunnerExtensions} for ViteRuby by calling this patch from
|
|
10
|
+
# a Rails initializer.
|
|
11
|
+
# This way, a typical `bin/dev` would work, as well as integration tests.
|
|
12
|
+
#
|
|
13
|
+
# @see https://github.com/ElMassimo/vite_ruby
|
|
14
|
+
# @see https://vite-ruby.netlify.app
|
|
15
|
+
module ViteRuby
|
|
16
|
+
# Patches the existing module.
|
|
17
|
+
#
|
|
18
|
+
# Call this after everything is loaded and required.
|
|
19
|
+
# For a Rails application, a good place is an initializer.
|
|
20
|
+
#
|
|
21
|
+
# See the documentation for more info on installation Rake tasks.
|
|
22
|
+
#
|
|
23
|
+
# @example
|
|
24
|
+
# Bundlebun::Integrations::ViteRuby.bun!
|
|
25
|
+
def self.bun!
|
|
26
|
+
return unless defined?(::ViteRuby::Runner)
|
|
27
|
+
|
|
28
|
+
::ViteRuby::Runner.prepend(self::RunnerExtensions)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# A monkey-patch for ViteRuby.
|
|
32
|
+
#
|
|
33
|
+
# @see https://github.com/ElMassimo/vite_ruby/blob/main/vite_ruby/lib/vite_ruby/runner.rb
|
|
34
|
+
module RunnerExtensions
|
|
35
|
+
# Internal: Resolves to an executable for Vite.
|
|
36
|
+
#
|
|
37
|
+
# We're overloading this to use with bundlebun.
|
|
38
|
+
def vite_executable(*exec_args)
|
|
39
|
+
# Should still allow a custom bin path/binstub
|
|
40
|
+
bin_path = config.vite_bin_path
|
|
41
|
+
return [bin_path] if bin_path && File.exist?(bin_path)
|
|
42
|
+
|
|
43
|
+
# Would be cleaner is to check `if config.package_manager == 'bun'`,
|
|
44
|
+
# but seems redundant since we're already bundling Bun,
|
|
45
|
+
# and putting `bun` as a package manager in their vite.json is just
|
|
46
|
+
# another step for the developer to do.
|
|
47
|
+
[bun_binstub_path, 'x --bun', *exec_args, 'vite']
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Use our binstub if it is installed in the project,
|
|
51
|
+
# otherwise just use the binary included with the gem.
|
|
52
|
+
def bun_binstub_path
|
|
53
|
+
Bundlebun::Runner.binstub_or_binary_path
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundlebun
|
|
4
|
+
# Bundlebun includes several integrations for frontend-related gems and frameworks.
|
|
5
|
+
#
|
|
6
|
+
# Usually you would need to run a provided Rake task (see the list at `rake -T bun`)
|
|
7
|
+
# to install any initializers or binstubs you might need.
|
|
8
|
+
# Then, the provided files will help you to initialize (patch) the code.
|
|
9
|
+
#
|
|
10
|
+
# Typically, to call an integration / patch the loaded code, you would need to call
|
|
11
|
+
# the `bun!` method, like `Bundlebun::Integrations::Foobar.bun!`.
|
|
12
|
+
#
|
|
13
|
+
# See the documentation to learn about the supported integrations.
|
|
14
|
+
module Integrations
|
|
15
|
+
# Loads and initializes all available integrations. See specific classes
|
|
16
|
+
# for implementation.
|
|
17
|
+
#
|
|
18
|
+
# @return [Array<Module>] List of initialized integrations
|
|
19
|
+
#
|
|
20
|
+
# @example
|
|
21
|
+
# Bundlebun::Integrations.bun! # => [Bundlebun::Integrations::Cssbundling, ...]
|
|
22
|
+
def self.bun!
|
|
23
|
+
integration_modules = constants.map { |const| const_get(const) }
|
|
24
|
+
.select { |const| const.is_a?(Module) }
|
|
25
|
+
|
|
26
|
+
integration_modules.select do |mod|
|
|
27
|
+
mod.respond_to?(:bun!) && mod.bun!
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundlebun
|
|
4
|
+
# Platform contains a set of helpers to deal with platform detection.
|
|
5
|
+
# Mostly, to see if we are running on Windows.
|
|
6
|
+
class Platform
|
|
7
|
+
class << self
|
|
8
|
+
# Are we running on Windows?
|
|
9
|
+
#
|
|
10
|
+
# @return [Boolean]
|
|
11
|
+
def windows?
|
|
12
|
+
return @windows if defined?(@windows)
|
|
13
|
+
|
|
14
|
+
@windows = defined?(RbConfig) && defined?(RbConfig::CONFIG) &&
|
|
15
|
+
RbConfig::CONFIG['host_os'].match?(/mswin|mingw|cygwin/)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'shellwords'
|
|
4
|
+
|
|
5
|
+
module Bundlebun
|
|
6
|
+
# {Runner} is the class that bundlebun uses to run the bundled Bun executable.
|
|
7
|
+
#
|
|
8
|
+
# bundlebun provides two ways to run Bun:
|
|
9
|
+
#
|
|
10
|
+
# - {.call} (also available as {.exec}): Replaces the current Ruby process with Bun. This is the default.
|
|
11
|
+
#
|
|
12
|
+
# - {.system}: Runs Bun as a subprocess and returns control to Ruby.
|
|
13
|
+
# Use this when you need to continue executing Ruby code after Bun finishes.
|
|
14
|
+
#
|
|
15
|
+
# @see Bundlebun
|
|
16
|
+
#
|
|
17
|
+
# @example Running Bun (replaces process, never returns)
|
|
18
|
+
# Bundlebun.('install')
|
|
19
|
+
# Bundlebun.call('outdated')
|
|
20
|
+
# Bundlebun.call(['add', 'postcss'])
|
|
21
|
+
#
|
|
22
|
+
# @example Running Bun as subprocess (returns to Ruby)
|
|
23
|
+
# if Bundlebun.system('install')
|
|
24
|
+
# puts 'Dependencies installed!'
|
|
25
|
+
# end
|
|
26
|
+
class Runner
|
|
27
|
+
BINSTUB_PATH = 'bin/bun'
|
|
28
|
+
RELATIVE_DIRECTORY = 'lib/bundlebun/vendor/bun'
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
# Replaces the current Ruby process with Bun.
|
|
32
|
+
#
|
|
33
|
+
# When `ActiveSupport::Notifications` is available, this method publishes an
|
|
34
|
+
# `exec.bundlebun` event before replacing the process. The payload contains
|
|
35
|
+
# `{ command: arguments }` where `arguments` is what was passed to the method.
|
|
36
|
+
#
|
|
37
|
+
# @param arguments [String, Array<String>] Command arguments to pass to Bun
|
|
38
|
+
# @return [void] This method never returns
|
|
39
|
+
#
|
|
40
|
+
# @example In a binstub (bin/bun)
|
|
41
|
+
# #!/usr/bin/env ruby
|
|
42
|
+
# require 'bundlebun'
|
|
43
|
+
# Bundlebun.exec(ARGV)
|
|
44
|
+
#
|
|
45
|
+
# @see .call
|
|
46
|
+
# @see .system
|
|
47
|
+
def exec(...)
|
|
48
|
+
new(...).exec
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Replaces the current Ruby process with Bun. Alias for {.exec}.
|
|
52
|
+
# Also available via the `.()` shorthand syntax.
|
|
53
|
+
#
|
|
54
|
+
# @param arguments [String, Array<String>] Command arguments to pass to Bun
|
|
55
|
+
# @return [void] This method never returns
|
|
56
|
+
#
|
|
57
|
+
# @example Basic usage
|
|
58
|
+
# Bundlebun.call('outdated')
|
|
59
|
+
# Bundlebun.call(['add', 'postcss'])
|
|
60
|
+
#
|
|
61
|
+
# @example Using the .() shorthand
|
|
62
|
+
# Bundlebun.('install')
|
|
63
|
+
#
|
|
64
|
+
# @see .exec
|
|
65
|
+
# @see .system
|
|
66
|
+
def call(...)
|
|
67
|
+
exec(...)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Runs Bun as a subprocess and returns control to Ruby.
|
|
71
|
+
#
|
|
72
|
+
# Unlike {.call} and {.exec}, this method does not replace the current process.
|
|
73
|
+
# Use this when you need to run Bun and then continue executing Ruby code.
|
|
74
|
+
#
|
|
75
|
+
# When `ActiveSupport::Notifications` is available, this method publishes a
|
|
76
|
+
# `system.bundlebun` event with timing information. The payload contains
|
|
77
|
+
# `{ command: arguments }` where `arguments` is what was passed to the method.
|
|
78
|
+
#
|
|
79
|
+
# @param arguments [String, Array<String>] Command arguments to pass to Bun
|
|
80
|
+
# @return [Boolean, nil] `true` if Bun exited successfully (status 0),
|
|
81
|
+
# `false` if it exited with an error, `nil` if execution failed
|
|
82
|
+
#
|
|
83
|
+
# @example Run install and check result
|
|
84
|
+
# if Bundlebun.system('install')
|
|
85
|
+
# puts 'Dependencies installed!'
|
|
86
|
+
# else
|
|
87
|
+
# puts 'Installation failed'
|
|
88
|
+
# end
|
|
89
|
+
#
|
|
90
|
+
# @see .call
|
|
91
|
+
# @see .exec
|
|
92
|
+
def system(...)
|
|
93
|
+
new(...).system
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# A relative path to binstub that bundlebun usually generates with installation Rake tasks.
|
|
97
|
+
#
|
|
98
|
+
# For Windows, the binstub path will return the `bun.cmd` wrapper.
|
|
99
|
+
#
|
|
100
|
+
# @return [String]
|
|
101
|
+
def binstub_path
|
|
102
|
+
return @binstub_path if defined?(@binstub_path)
|
|
103
|
+
|
|
104
|
+
@binstub_path = Bundlebun::Platform.windows? ? "#{BINSTUB_PATH}.cmd" : BINSTUB_PATH
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# A full path to binstub that bundlebun usually generates with installation Rake tasks.
|
|
108
|
+
#
|
|
109
|
+
# For Windows, that will use the `bun.cmd` wrapper.
|
|
110
|
+
#
|
|
111
|
+
# @return [String]
|
|
112
|
+
def full_binstub_path
|
|
113
|
+
return @full_binstub_path if defined?(@full_binstub_path)
|
|
114
|
+
|
|
115
|
+
@full_binstub_path = File.expand_path(binstub_path)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# A relative directory path to the bundled Bun executable from the root of the gem.
|
|
119
|
+
#
|
|
120
|
+
# @return [String]
|
|
121
|
+
def relative_directory
|
|
122
|
+
RELATIVE_DIRECTORY
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# A full directory path to the bundled Bun executable from the root of the gem.
|
|
126
|
+
#
|
|
127
|
+
# @return [String]
|
|
128
|
+
def full_directory
|
|
129
|
+
return @full_directory if defined?(@full_directory)
|
|
130
|
+
|
|
131
|
+
@full_directory = File.expand_path("../../#{relative_directory}", __dir__)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# A full path to the bundled Bun binary we run
|
|
135
|
+
# (includes `.exe` on Windows).
|
|
136
|
+
#
|
|
137
|
+
# @return [String]
|
|
138
|
+
def binary_path
|
|
139
|
+
return @binary_path if defined?(@binary_path)
|
|
140
|
+
|
|
141
|
+
executable = "bun#{".exe" if Bundlebun::Platform.windows?}"
|
|
142
|
+
@binary_path = File.join(full_directory, executable)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Does the bundled Bun binary exist?
|
|
146
|
+
#
|
|
147
|
+
# @return [Boolean]
|
|
148
|
+
def binary_path_exist?
|
|
149
|
+
File.exist?(binary_path)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Returns the preferred way to run Bun when bundlebun is installed.
|
|
153
|
+
#
|
|
154
|
+
# If the binstub is installed (see binstub_path), use the full path to binstub.
|
|
155
|
+
# If not, use the full binary path for the bundled executable (binary_path).
|
|
156
|
+
#
|
|
157
|
+
# @return [String]
|
|
158
|
+
def binstub_or_binary_path
|
|
159
|
+
binstub_exist? ? full_binstub_path : binary_path
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Does the binstub exist?
|
|
163
|
+
#
|
|
164
|
+
# @return [Boolean]
|
|
165
|
+
def binstub_exist?
|
|
166
|
+
File.exist?(binstub_path)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Initialize the {Runner} with arguments to run the Bun runtime later.
|
|
171
|
+
#
|
|
172
|
+
# @param arguments [String, Array<String>] Command arguments to pass to Bun
|
|
173
|
+
#
|
|
174
|
+
# @example String as an argument
|
|
175
|
+
# Bundlebun::Runner.new('--version')
|
|
176
|
+
#
|
|
177
|
+
# @example Array of strings as an argument
|
|
178
|
+
# Bundlebun::Runner.new(['add', 'postcss'])
|
|
179
|
+
#
|
|
180
|
+
# @see #system
|
|
181
|
+
# @see #exec
|
|
182
|
+
def initialize(arguments)
|
|
183
|
+
@arguments = arguments
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Replaces the current Ruby process with Bun.
|
|
187
|
+
# This is the default behavior.
|
|
188
|
+
#
|
|
189
|
+
# When `ActiveSupport::Notifications` is available, this method publishes an
|
|
190
|
+
# `exec.bundlebun` event before replacing the process. The payload contains
|
|
191
|
+
# `{ command: arguments }` where `arguments` is what was passed to the runner.
|
|
192
|
+
#
|
|
193
|
+
# @return [void] This method never returns
|
|
194
|
+
#
|
|
195
|
+
# @example
|
|
196
|
+
# runner = Bundlebun::Runner.new(ARGV)
|
|
197
|
+
# runner.exec # Ruby process ends here, Bun takes over
|
|
198
|
+
#
|
|
199
|
+
# @see #system
|
|
200
|
+
def exec
|
|
201
|
+
check_executable!
|
|
202
|
+
instrument('exec.bundlebun')
|
|
203
|
+
Kernel.exec(*command)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Replaces the current Ruby process with Bun. Alias for {#exec}.
|
|
207
|
+
#
|
|
208
|
+
# @return [void] This method never returns
|
|
209
|
+
#
|
|
210
|
+
# @see #exec
|
|
211
|
+
def call
|
|
212
|
+
exec
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Runs Bun as a subprocess and returns control to Ruby.
|
|
216
|
+
#
|
|
217
|
+
# Unlike {#call} and {#exec}, this method does not replace the current process.
|
|
218
|
+
# Use this when you need to run Bun and then continue executing Ruby code.
|
|
219
|
+
#
|
|
220
|
+
# When `ActiveSupport::Notifications` is available, this method publishes a
|
|
221
|
+
# `system.bundlebun` event with timing information. The payload contains
|
|
222
|
+
# `{ command: arguments }` where `arguments` is what was passed to the runner.
|
|
223
|
+
#
|
|
224
|
+
# @return [Boolean, nil] `true` if Bun exited successfully (status 0),
|
|
225
|
+
# `false` if it exited with an error, `nil` if execution failed
|
|
226
|
+
#
|
|
227
|
+
# @example
|
|
228
|
+
# runner = Bundlebun::Runner.new('install')
|
|
229
|
+
# if runner.system
|
|
230
|
+
# puts 'Dependencies installed!'
|
|
231
|
+
# end
|
|
232
|
+
#
|
|
233
|
+
# @see #exec
|
|
234
|
+
def system
|
|
235
|
+
check_executable!
|
|
236
|
+
instrument('system.bundlebun') do
|
|
237
|
+
Kernel.system(*command)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
private
|
|
242
|
+
|
|
243
|
+
attr_reader :arguments
|
|
244
|
+
|
|
245
|
+
def instrument(event, &block)
|
|
246
|
+
return block&.call unless defined?(ActiveSupport::Notifications)
|
|
247
|
+
|
|
248
|
+
payload = {command: arguments}
|
|
249
|
+
if block
|
|
250
|
+
ActiveSupport::Notifications.instrument(event, payload, &block)
|
|
251
|
+
else
|
|
252
|
+
ActiveSupport::Notifications.instrument(event, payload)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def check_executable!
|
|
257
|
+
return if self.class.binary_path_exist?
|
|
258
|
+
|
|
259
|
+
Kernel.warn "Unable to run Bun: executable not found at #{self.class.binary_path}"
|
|
260
|
+
Kernel.exit 127
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def command
|
|
264
|
+
[self.class.binary_path, *command_arguments]
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def command_arguments
|
|
268
|
+
case arguments
|
|
269
|
+
when Array
|
|
270
|
+
arguments.flatten.compact.map(&:to_s)
|
|
271
|
+
when nil
|
|
272
|
+
[]
|
|
273
|
+
else
|
|
274
|
+
Shellwords.split(arguments.to_s)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Bun itself is MIT-licensed.
|
|
2
|
+
|
|
3
|
+
## JavaScriptCore
|
|
4
|
+
|
|
5
|
+
Bun statically links JavaScriptCore (and WebKit) which is LGPL-2 licensed. WebCore files from WebKit are also licensed under LGPL2. Per LGPL2:
|
|
6
|
+
|
|
7
|
+
> (1) If you statically link against an LGPL’d library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.
|
|
8
|
+
|
|
9
|
+
You can find the patched version of WebKit used by Bun here: <https://github.com/oven-sh/webkit>. If you would like to relink Bun with changes:
|
|
10
|
+
|
|
11
|
+
- `git submodule update --init --recursive`
|
|
12
|
+
- `make jsc`
|
|
13
|
+
- `zig build`
|
|
14
|
+
|
|
15
|
+
This compiles JavaScriptCore, compiles Bun’s `.cpp` bindings for JavaScriptCore (which are the object files using JavaScriptCore) and outputs a new `bun` binary with your changes.
|
|
16
|
+
|
|
17
|
+
## Linked libraries
|
|
18
|
+
|
|
19
|
+
Bun statically links these libraries:
|
|
20
|
+
|
|
21
|
+
| Library | License |
|
|
22
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
|
|
23
|
+
| [`boringssl`](https://boringssl.googlesource.com/boringssl/) | [several licenses](https://boringssl.googlesource.com/boringssl/+/refs/heads/master/LICENSE) |
|
|
24
|
+
| [`brotli`](https://github.com/google/brotli) | MIT |
|
|
25
|
+
| [`libarchive`](https://github.com/libarchive/libarchive) | [several licenses](https://github.com/libarchive/libarchive/blob/master/COPYING) |
|
|
26
|
+
| [`lol-html`](https://github.com/cloudflare/lol-html/tree/master/c-api) | BSD 3-Clause |
|
|
27
|
+
| [`mimalloc`](https://github.com/microsoft/mimalloc) | MIT |
|
|
28
|
+
| [`picohttp`](https://github.com/h2o/picohttpparser) | dual-licensed under the Perl License or the MIT License |
|
|
29
|
+
| [`zstd`](https://github.com/facebook/zstd) | dual-licensed under the BSD License or GPLv2 license |
|
|
30
|
+
| [`simdutf`](https://github.com/simdutf/simdutf) | Apache 2.0 |
|
|
31
|
+
| [`tinycc`](https://github.com/tinycc/tinycc) | LGPL v2.1 |
|
|
32
|
+
| [`uSockets`](https://github.com/uNetworking/uSockets) | Apache 2.0 |
|
|
33
|
+
| [`zlib-cloudflare`](https://github.com/cloudflare/zlib) | zlib |
|
|
34
|
+
| [`c-ares`](https://github.com/c-ares/c-ares) | MIT licensed |
|
|
35
|
+
| [`libicu`](https://github.com/unicode-org/icu) 72 | [license here](https://github.com/unicode-org/icu/blob/main/icu4c/LICENSE) |
|
|
36
|
+
| [`libbase64`](https://github.com/aklomp/base64/blob/master/LICENSE) | BSD 2-Clause |
|
|
37
|
+
| [`libuv`](https://github.com/libuv/libuv) (on Windows) | MIT |
|
|
38
|
+
| [`libdeflate`](https://github.com/ebiggers/libdeflate) | MIT |
|
|
39
|
+
| A fork of [`uWebsockets`](https://github.com/jarred-sumner/uwebsockets) | Apache 2.0 licensed |
|
|
40
|
+
| Parts of [Tigerbeetle's IO code](https://github.com/tigerbeetle/tigerbeetle/blob/532c8b70b9142c17e07737ab6d3da68d7500cbca/src/io/windows.zig#L1) | Apache 2.0 licensed |
|
|
41
|
+
|
|
42
|
+
## Polyfills
|
|
43
|
+
|
|
44
|
+
For compatibility reasons, the following packages are embedded into Bun's binary and injected if imported.
|
|
45
|
+
|
|
46
|
+
| Package | License |
|
|
47
|
+
| ------------------------------------------------------------------------ | ------- |
|
|
48
|
+
| [`assert`](https://npmjs.com/package/assert) | MIT |
|
|
49
|
+
| [`browserify-zlib`](https://npmjs.com/package/browserify-zlib) | MIT |
|
|
50
|
+
| [`buffer`](https://npmjs.com/package/buffer) | MIT |
|
|
51
|
+
| [`constants-browserify`](https://npmjs.com/package/constants-browserify) | MIT |
|
|
52
|
+
| [`crypto-browserify`](https://npmjs.com/package/crypto-browserify) | MIT |
|
|
53
|
+
| [`domain-browser`](https://npmjs.com/package/domain-browser) | MIT |
|
|
54
|
+
| [`events`](https://npmjs.com/package/events) | MIT |
|
|
55
|
+
| [`https-browserify`](https://npmjs.com/package/https-browserify) | MIT |
|
|
56
|
+
| [`os-browserify`](https://npmjs.com/package/os-browserify) | MIT |
|
|
57
|
+
| [`path-browserify`](https://npmjs.com/package/path-browserify) | MIT |
|
|
58
|
+
| [`process`](https://npmjs.com/package/process) | MIT |
|
|
59
|
+
| [`punycode`](https://npmjs.com/package/punycode) | MIT |
|
|
60
|
+
| [`querystring-es3`](https://npmjs.com/package/querystring-es3) | MIT |
|
|
61
|
+
| [`stream-browserify`](https://npmjs.com/package/stream-browserify) | MIT |
|
|
62
|
+
| [`stream-http`](https://npmjs.com/package/stream-http) | MIT |
|
|
63
|
+
| [`string_decoder`](https://npmjs.com/package/string_decoder) | MIT |
|
|
64
|
+
| [`timers-browserify`](https://npmjs.com/package/timers-browserify) | MIT |
|
|
65
|
+
| [`tty-browserify`](https://npmjs.com/package/tty-browserify) | MIT |
|
|
66
|
+
| [`url`](https://npmjs.com/package/url) | MIT |
|
|
67
|
+
| [`util`](https://npmjs.com/package/util) | MIT |
|
|
68
|
+
| [`vm-browserify`](https://npmjs.com/package/vm-browserify) | MIT |
|
|
69
|
+
|
|
70
|
+
## Additional credits
|
|
71
|
+
|
|
72
|
+
- Bun's JS transpiler, CSS lexer, and Node.js module resolver source code is a Zig port of [@evanw](https://github.com/evanw)’s [esbuild](https://github.com/evanw/esbuild) project.
|
|
73
|
+
- Credit to [@kipply](https://github.com/kipply) for the name "Bun"!
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundlebun
|
|
4
|
+
# bundlebun uses the `#{bundlebun.version}.#{bun.version}`
|
|
5
|
+
# versioning scheme.
|
|
6
|
+
# gem bundlebun version `0.1.0.1.1.38` is a distribution
|
|
7
|
+
# that includes a gem with its own code version `0.1.0` and
|
|
8
|
+
# a Bun runtime with version `1.1.38`.
|
|
9
|
+
#
|
|
10
|
+
# This constant always points to the "own" version of the gem.
|
|
11
|
+
VERSION = '0.5.0'
|
|
12
|
+
end
|
data/lib/bundlebun.rb
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'zeitwerk'
|
|
4
|
+
|
|
5
|
+
# bundlebun bundles [Bun](https://bun.sh), a fast JavaScript runtime, package manager
|
|
6
|
+
# and builder, with your Ruby and Rails applications.
|
|
7
|
+
# No Docker, devcontainers, `curl | sh`, or `brew` needed.
|
|
8
|
+
#
|
|
9
|
+
# bundlebun includes binary distributions of Bun for each of the supported
|
|
10
|
+
# platforms (macOS, Linux, Windows) and architectures.
|
|
11
|
+
#
|
|
12
|
+
# bundlebun provides two ways to run Bun:
|
|
13
|
+
#
|
|
14
|
+
# - {.call} (also available as {.exec}): Replaces the current Ruby process with Bun. The default.
|
|
15
|
+
#
|
|
16
|
+
# - {.system}: Runs Bun as a subprocess and returns control to Ruby.
|
|
17
|
+
# Use this when you need to continue executing Ruby code after Bun finishes.
|
|
18
|
+
#
|
|
19
|
+
# @see Bundlebun::Runner
|
|
20
|
+
# @see Bundlebun::Integrations
|
|
21
|
+
#
|
|
22
|
+
# @example Running Bun (replaces process, never returns)
|
|
23
|
+
# Bundlebun.('install') # .() shorthand syntax
|
|
24
|
+
# Bundlebun.call('outdated')
|
|
25
|
+
# Bundlebun.call(['add', 'postcss'])
|
|
26
|
+
#
|
|
27
|
+
# @example Running Bun as subprocess (returns to Ruby)
|
|
28
|
+
# if Bundlebun.system('install')
|
|
29
|
+
# puts 'Dependencies installed!'
|
|
30
|
+
# end
|
|
31
|
+
module Bundlebun
|
|
32
|
+
class << self
|
|
33
|
+
# Replaces the current Ruby process with Bun.
|
|
34
|
+
#
|
|
35
|
+
# This is the default way to run Bun. The Ruby process is replaced by Bun
|
|
36
|
+
# and never returns. Also available via the `.()` shorthand syntax.
|
|
37
|
+
#
|
|
38
|
+
# @param arguments [String, Array<String>] Command arguments to pass to Bun
|
|
39
|
+
# @return [void] This method never returns
|
|
40
|
+
#
|
|
41
|
+
# @example Basic usage
|
|
42
|
+
# Bundlebun.call('outdated')
|
|
43
|
+
# Bundlebun.call(['add', 'postcss'])
|
|
44
|
+
#
|
|
45
|
+
# @example Using the .() shorthand
|
|
46
|
+
# Bundlebun.('install')
|
|
47
|
+
# Bundlebun.(ARGV)
|
|
48
|
+
#
|
|
49
|
+
# @see .exec
|
|
50
|
+
# @see .system
|
|
51
|
+
# @see Bundlebun::Runner.call
|
|
52
|
+
def call(...)
|
|
53
|
+
Runner.call(...)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Replaces the current Ruby process with Bun. Same as {.call}.
|
|
57
|
+
#
|
|
58
|
+
# @param arguments [String, Array<String>] Command arguments to pass to Bun
|
|
59
|
+
# @return [void] This method never returns
|
|
60
|
+
#
|
|
61
|
+
# @see .call
|
|
62
|
+
# @see Bundlebun::Runner.exec
|
|
63
|
+
def exec(...)
|
|
64
|
+
Runner.exec(...)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Runs Bun as a subprocess and returns control to Ruby.
|
|
68
|
+
#
|
|
69
|
+
# Unlike {.call} and {.exec}, this method does not replace the current process.
|
|
70
|
+
# Use this when you need to run Bun and then continue executing Ruby code.
|
|
71
|
+
#
|
|
72
|
+
# @param arguments [String, Array<String>] Command arguments to pass to Bun
|
|
73
|
+
# @return [Boolean, nil] `true` if Bun exited successfully (status 0),
|
|
74
|
+
# `false` if it exited with an error, `nil` if execution failed
|
|
75
|
+
#
|
|
76
|
+
# @example Run install and check result
|
|
77
|
+
# if Bundlebun.system('install')
|
|
78
|
+
# puts 'Dependencies installed!'
|
|
79
|
+
# else
|
|
80
|
+
# puts 'Installation failed'
|
|
81
|
+
# end
|
|
82
|
+
#
|
|
83
|
+
# @see .call
|
|
84
|
+
# @see .exec
|
|
85
|
+
# @see Bundlebun::Runner.system
|
|
86
|
+
def system(...)
|
|
87
|
+
Runner.system(...)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def loader # @private
|
|
91
|
+
@loader ||= Zeitwerk::Loader.for_gem.tap do |loader|
|
|
92
|
+
loader.ignore("#{__dir__}/tasks")
|
|
93
|
+
loader.ignore("#{__dir__}/bundlebun/vendor")
|
|
94
|
+
loader.ignore("#{__dir__}/templates")
|
|
95
|
+
|
|
96
|
+
loader.inflector.inflect('execjs' => 'ExecJS')
|
|
97
|
+
|
|
98
|
+
loader.setup
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Prepend the path to the bundled Bun executable to `PATH`.
|
|
103
|
+
#
|
|
104
|
+
# @see Bundlebun::Runner.full_directory
|
|
105
|
+
def prepend_to_path
|
|
106
|
+
EnvPath.prepend(Runner.full_directory)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Load included Rake tasks (like `bun:install`).
|
|
110
|
+
def load_tasks
|
|
111
|
+
Dir[File.expand_path('tasks/*.rake', __dir__)].each { |task| load task }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Detect and load all integrations (monkey-patches).
|
|
115
|
+
#
|
|
116
|
+
# @see Bundlebun::Integrations
|
|
117
|
+
def load_integrations
|
|
118
|
+
Integrations.bun!
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def bun = 'Bun'
|
|
122
|
+
alias_method :bun?, :bun
|
|
123
|
+
alias_method :bun!, :bun
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
Bundlebun.loader
|
|
128
|
+
Bundlebun.prepend_to_path
|
|
129
|
+
Bundlebun.load_tasks if defined?(Rake)
|
|
130
|
+
Bundlebun.load_integrations
|
data/lib/tasks/bun.rake
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rake'
|
|
4
|
+
|
|
5
|
+
# Rake command/parameter handling is limited, so we
|
|
6
|
+
# need to use the <tt>[]</tt>-syntax.
|
|
7
|
+
#
|
|
8
|
+
# Even when using <tt>--</tt> with something like
|
|
9
|
+
# <tt>rake bun -- -e 'console.log(1)'</tt>, Rack thinks that
|
|
10
|
+
# <tt>console.log...</tt> is a task it needs to run, warns about an
|
|
11
|
+
# error (although still executes known tasks).
|
|
12
|
+
#
|
|
13
|
+
# Example:
|
|
14
|
+
#
|
|
15
|
+
# rake "bun[-e 'console.log(2+2)']"
|
|
16
|
+
#
|
|
17
|
+
desc 'Run bundled Bun with parameters. Example: rake "bun[build]"'
|
|
18
|
+
task :bun, [:command] do |_t, args|
|
|
19
|
+
command = args[:command] || ''
|
|
20
|
+
Bundlebun.call(command)
|
|
21
|
+
end
|