bundlebun 0.5.0.1.3.13-aarch64-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.
@@ -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
@@ -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