boxwerk 0.1.0 β†’ 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 45cabb7d61d5029a494703a95c1b974f1af7ee1286001d457ea7aaf8b870496c
4
- data.tar.gz: fb14ec2556787d19618ee3599685a06a06a4d1ed40a3113c47f61420f84fb202
3
+ metadata.gz: 6fbe46b469b3c4c08b56abcf734d26d26edf383161e3c2bc7e345c930ec4db13
4
+ data.tar.gz: 69b8f826fa921007beae2b32b4fa2e053f2c9109a0095a5813431cb4cc6447e8
5
5
  SHA512:
6
- metadata.gz: 8e11bee2fd442bc29b537d4e7099e4380b19bed851f4f40bd42e119c35f139ee680866bd0f6189334e46652881c224559e10c6ab4dcf722c4d50c455fccdf16e
7
- data.tar.gz: 0c69bf3a342d8fd502d6e64d085edfa9d1a2864b60d8f3f683addc680080f5762246f9901926c81667c40ddad82fdae7ead6e939ea3f297c0f907c983e21622f
6
+ metadata.gz: 48649f22d3db03be484e78dbf42234b9a1bc13b6616d20a3dae31d0ea8e7542c559d315aa572e5f1f9ffca2cbc8639cf944e95569dc4e122028ccf3a87772702
7
+ data.tar.gz: 1a211414af0a486e1df289b1b12f84cc51eada906bad50fa047e3d9a38ef93c51a19871593844268a8ef14ab9fd36540698cb8ca7dafd57f42e6f6dc0ab844f4
data/CHANGELOG.md CHANGED
@@ -1,8 +1,31 @@
1
1
  # Changelog
2
2
 
3
- ## [0.1.0] - 2026-01-05
3
+ ## [Unreleased]
4
+
5
+ ## [v0.2.0] - 2026-01-06
6
+
7
+ ### Changed
8
+ - Simplified implementation (~370 lines removed)
9
+ - Consolidated cycle detection in Graph (removed redundant methods)
10
+ - Removed unused Loader methods
11
+ - Streamlined all module implementations
12
+ - Added class-level documentation to all modules
13
+ - Simplified example application
14
+
15
+ ### Removed
16
+ - Removed `Gemfile.lock` from git (library best practice)
17
+ - Removed `sig/boxwerk.rbs`
18
+ - Excluded `example/` from gem package
19
+
20
+ ### Tests
21
+ - Reduced test suite from 62 to 46 tests
22
+ - Removed redundant unit tests (275 lines)
23
+ - Maintained full integration test coverage
24
+
25
+ ## [v0.1.0] - 2026-01-05
4
26
 
5
27
  Initial release.
6
28
 
7
- [unreleased]: https://github.com/dtcristo/boxwerk/compare/v0.1.0...HEAD
8
- [0.1.0]: https://github.com/dtcristo/boxwerk/releases/tag/v0.1.0
29
+ [Unreleased]: https://github.com/dtcristo/boxwerk/compare/v0.2.0...HEAD
30
+ [v0.2.0]: https://github.com/dtcristo/boxwerk/releases/tag/v0.2.0
31
+ [v0.1.0]: https://github.com/dtcristo/boxwerk/releases/tag/v0.1.0
data/README.md CHANGED
@@ -1,24 +1,30 @@
1
- # Boxwerk
1
+ <div align="center">
2
+ <h1>
3
+ πŸ“¦ Boxwerk
4
+ </h1>
5
+ </div>
2
6
 
3
- Boxwerk is a runtime package system for Ruby with strict isolation of constants using Ruby 4.0's [`Ruby::Box`](https://docs.ruby-lang.org/en/master/Ruby/Box.html). It is used to organize code into packages with explicit dependency graphs and strict access to constants between packages. It is inspired by [Packwerk](https://github.com/Shopify/packwerk), a static package system.
7
+ Boxwerk is an **experimental** Ruby package system with Box-powered constant isolation. It is used at runtime to organize code into packages with explicit dependencies and strict constant access using [`Ruby::Box`](https://docs.ruby-lang.org/en/master/Ruby/Box.html). Inspired by [Packwerk](https://github.com/Shopify/packwerk).
4
8
 
5
9
  ## Features
6
10
 
7
- - **Strict Isolation**: Each package runs in its own `Ruby::Box`, preventing constants from leaking without explicit imports or exports.
8
- - **Explicit Dependencies**: Dependencies are declared in `package.yml` files, forming a validated DAG.
9
- - **Ergonomic Imports**: Flexible import strategies (namespaced, aliased, selective, renamed).
11
+ - **Strict Isolation**: Each package runs in its own `Ruby::Box`, preventing constant leakage
12
+ - **Explicit Dependencies**: Dependencies declared in `package.yml`, validated as a DAG
13
+ - **Controlled Exports**: Only declared constants are accessible to importers
14
+ - **Flexible Imports**: Multiple strategies (namespaced, aliased, selective, renamed)
15
+ - **Lazy Loading**: Exports loaded on-demand when imported
10
16
 
11
- ## Limtations
17
+ ## Current Limitations
12
18
 
13
- - There is no isolation of gems.
14
- - Gems are required to be eager loaded in the root box to be accessible in packages.
15
- - No support for reloading of constants.
16
- - Exported constants must follow Zeitwerk naming conventions for their source location.
19
+ - No gem isolationβ€”all gems are global across packages
20
+ - No constant reloading support
21
+ - Exported constants must follow [Zeitwerk naming conventions](https://github.com/fxn/zeitwerk#file-structure)
22
+ - Console runs in root box, not root package box (due to IRB loading issues)
23
+ - `Ruby::Box` itself is experimental in Ruby 4.0
17
24
 
18
25
  ## Requirements
19
26
 
20
- - Ruby 4.0+ with [`Ruby::Box`](https://docs.ruby-lang.org/en/master/Ruby/Box.html) support
21
- - `RUBY_BOX=1` environment variable must be set at process startup
27
+ - Ruby 4.0+ with `RUBY_BOX=1` environment variable set.
22
28
 
23
29
  ## Quick Start
24
30
 
@@ -26,14 +32,15 @@ Boxwerk is a runtime package system for Ruby with strict isolation of constants
26
32
 
27
33
  ```
28
34
  my_app/
29
- β”œβ”€β”€ Gemfile # Your gem dependencies
30
- β”œβ”€β”€ package.yml # Root package
35
+ β”œβ”€β”€ Gemfile
36
+ β”œβ”€β”€ package.yml # Root package manifest
31
37
  β”œβ”€β”€ app.rb # Your application entrypoint
32
38
  └── packages/
33
- └── billing/
39
+ └── finance/
34
40
  β”œβ”€β”€ package.yml # Package manifest
35
41
  └── lib/
36
- └── invoice.rb # Package code
42
+ β”œβ”€β”€ invoice.rb # Defines Invoice
43
+ └── tax_calculator.rb # Defines TaxCalculator
37
44
  ```
38
45
 
39
46
  ### 2. Define Your Gemfile
@@ -61,27 +68,6 @@ exports:
61
68
  - TaxCalculator
62
69
  ```
63
70
 
64
- **`packages/finance/lib/invoice.rb`:**
65
- ```ruby
66
- class Invoice
67
- def initialize(amount_cents)
68
- # Money gem is accessible because it's in the Gemfile
69
- @amount = Money.new(amount_cents, 'USD')
70
- end
71
-
72
- def total
73
- @amount
74
- end
75
- end
76
- ```
77
-
78
- **`packages/finance/lib/tax_calculator.rb`:**
79
- ```ruby
80
- class TaxCalculator
81
- # ...
82
- end
83
- ```
84
-
85
71
  ### 4. Use in Your Application
86
72
 
87
73
  **`app.rb`:**
@@ -97,40 +83,30 @@ puts invoice.total # => #<Money fractional:10000 currency:USD>
97
83
  RUBY_BOX=1 boxwerk run app.rb
98
84
  ```
99
85
 
100
- Boxwerk automatically:
101
- 1. Sets up Bundler
102
- 2. Requires all gems from your Gemfile in the root box
103
- 3. Loads and wires all packages
104
- 4. Executes your script in the root package context
86
+ Boxwerk handles Bundler setup, gem loading, package wiring, and script execution automatically.
105
87
 
106
- ## Usage
107
-
108
- ### Running Scripts
88
+ ## Example
109
89
 
110
- Execute a Ruby script in the root package context:
90
+ See the [example/](example/) directory for a working multi-package application:
111
91
 
112
92
  ```bash
113
- boxwerk run script.rb [args...]
93
+ cd example
94
+ RUBY_BOX=1 boxwerk run app.rb
114
95
  ```
115
96
 
116
- The script has access to:
117
- - All gems from your Gemfile (automatically required)
118
- - All imports defined in the root `package.yml`
119
-
120
- ### Interactive Console
97
+ ## CLI Usage
121
98
 
122
- TODO: This feature is currenly broken and will run IRB from the root box, not the root package as desired.
123
-
124
- Start an IRB session in the root package context:
99
+ **Run a script:**
100
+ ```bash
101
+ boxwerk run script.rb [args...]
102
+ ```
125
103
 
104
+ **Interactive console** (currently runs in root box, not root package):
126
105
  ```bash
127
106
  boxwerk console [irb-args...]
128
107
  ```
129
108
 
130
- All imports and gems are available for interactive exploration.
131
-
132
- ### Help
133
-
109
+ **Help:**
134
110
  ```bash
135
111
  boxwerk help
136
112
  ```
@@ -151,211 +127,79 @@ imports:
151
127
 
152
128
  ### Exports
153
129
 
154
- Constants that should be visible to packages that import this one.
130
+ Constants that should be visible to packages that import this one. Exports are lazily loaded during boot; only those actually imported by dependent packages are loaded.
155
131
 
156
132
  ### Imports
157
133
 
158
- Dependencies this package needs. **Note**: Dependencies are NOT transitive. If package A imports B, and B imports C, then A cannot access C unless it explicitly imports it.
134
+ Package dependencies that are wired as new constants in the importing package's box. Default and aliased namespace imports create a module to hold the exports. **Not transitive**: if A imports B and B imports C, A cannot access C without explicitly importing it.
159
135
 
160
136
  ## Import Strategies
161
137
 
162
- Boxwerk supports four import strategies in `package.yml`:
163
-
164
- ### 1. Default Namespace
165
-
166
- Import all exports under a module named after the package:
167
-
138
+ **Default namespace** (all exports under package name):
168
139
  ```yaml
169
140
  imports:
170
141
  - packages/finance
142
+ # Result: Finance::Invoice, Finance::TaxCalculator
171
143
  ```
172
144
 
173
- Result: `Finance::Invoice`, `Finance::TaxCalculator`
174
-
175
- ### 2. Aliased Namespace
176
-
177
- Import under a custom module name:
178
-
145
+ **Aliased namespace** (custom module name):
179
146
  ```yaml
180
147
  imports:
181
148
  - packages/finance: Billing
149
+ # Result: Billing::Invoice, Billing::TaxCalculator
182
150
  ```
151
+ *Note: Single exports import directly without namespace*
183
152
 
184
- Result: `Billing::Invoice`, `Billing::TaxCalculator`
185
-
186
- **Single Export Optimization**: If a package exports only one constant, it's imported directly (not wrapped in a module):
187
-
188
- ```yaml
189
- # util exports only Calculator
190
- imports:
191
- - packages/util: Calc
192
- ```
193
-
194
- Result: `Calc` (not `Calc::Calculator`)
195
-
196
- ### 3. Selective Import
197
-
198
- Import specific constants directly:
199
-
153
+ **Selective import** (specific constants):
200
154
  ```yaml
201
155
  imports:
202
156
  - packages/finance:
203
157
  - Invoice
204
158
  - TaxCalculator
159
+ # Result: Invoice, TaxCalculator (no namespace)
205
160
  ```
206
161
 
207
- Result: `Invoice`, `TaxCalculator` (no namespace)
208
-
209
- ### 4. Selective Rename
210
-
211
- Import specific constants with custom names:
212
-
162
+ **Selective rename** (custom names):
213
163
  ```yaml
214
164
  imports:
215
165
  - packages/finance:
216
166
  Invoice: Bill
217
167
  TaxCalculator: Calculator
168
+ # Result: Bill, Calculator
218
169
  ```
219
170
 
220
- Result: `Bill`, `Calculator`
221
-
222
- ## Gems and Packages
223
-
224
- ### How Gems Work in Boxwerk
225
-
226
- When you run `boxwerk`, all gems in your `Gemfile` are:
227
- 1. Automatically loaded via Bundler in the root box
228
- 2. Accessible globally in all package boxes (gems are not isolated)
171
+ ## Gem Handling
229
172
 
230
- This means:
231
- - You can use any gem from your Gemfile in any package.
232
- - Gems don't need to be declared in `package.yml`.
233
- - You do not `require` gems manually.
234
-
235
- ### Isolation Model
236
-
237
- - **Root Box**: The box where Ruby bootstraps and all builtin classes/modules are defined. In Boxwerk, the root box performs all setup operations (Bundler setup, gem loading, dependency graph building, package box creation, and import wiring).
238
- - **Main Box**: The first user box created automatically by Ruby (copied from root box). In Boxwerk, it only runs the `exe/boxwerk` executable file, which then calls into the root box to execute the setup. The main box has no other purpose.
239
- - **Package Boxes**: Each package (including root package) runs in its own isolated `Ruby::Box` (created by copying from root box after gems are loaded).
240
- - **Box Inheritance**: All boxes are created via copy-on-write from the root box, inheriting builtin classes and loaded gems.
241
- - **Gems are Global**: All gems from Gemfile are accessible in all boxes (loaded in root box before package boxes are created).
242
- - **Package Exports are Isolated**: Only explicit imports from packages are accessible.
243
- - **No Transitive Access**: Packages can only see their explicit imports.
244
-
245
- For more details on how Ruby::Box works, see the [official Ruby::Box documentation](https://docs.ruby-lang.org/en/master/Ruby/Box.html).
173
+ All gems in your `Gemfile` are:
174
+ - Automatically loaded in the root box via Bundler
175
+ - Accessible globally in all packages (no gem isolation)
176
+ - No manual `require` or `package.yml` declaration needed
246
177
 
247
178
  ## Known Issues
248
179
 
249
- These issues are related to the current state of Ruby::Box in Ruby 4.0+. See the [Ruby::Box documentation](https://docs.ruby-lang.org/en/master/Ruby/Box.html) for known issues with the feature itself.
250
-
251
- ### Gem Requiring in Boxes
252
-
253
- Requiring any gem from within a box (after boot) currently crashes the Ruby VM. This is likely an issue with Ruby::Box itself. As a workaround, Boxwerk automatically requires all gems from the Gemfile in the root box before creating package boxes, so gems are already loaded and accessible everywhere.
254
-
255
- ### Console Context
256
-
257
- The console does not correctly run in the root package boxβ€”it runs in the context of the root box instead. It should run in the root package box. However, if we attempt to `require 'irb'` in the root package box, the Ruby VM crashes due to the gem requiring issue described above.
258
-
259
- ### IRB Autocomplete
180
+ Related to Ruby::Box in Ruby 4.0+. See [Ruby::Box documentation](https://docs.ruby-lang.org/en/master/Ruby/Box.html) for details.
260
181
 
261
- Autocomplete is disabled for the console/IRB by default. When enabled, the Ruby VM crashes as soon as any key is pressed. This appears to be an issue with Ruby::Box and IRB's autocomplete feature interacting poorly.
182
+ - **Gem requiring**: Crashes VM when requiring gems inside boxes after boot (workaround: gems pre-loaded in root box)
183
+ - **Console context**: Runs in root box instead of root package box due to IRB loading limitation
184
+ - **IRB autocomplete**: Disabled by since it currently crashes VMpe
262
185
 
263
186
  ## Architecture
264
187
 
265
- ### Boot Process
266
-
267
- 1. Setup Bundler and require all gems in the root box
268
- 2. Find root `package.yml` (searches up from current directory)
269
- 3. Build dependency graph from package manifests
270
- 4. Validate dependency graph (no circular dependencies)
271
- 5. Boot packages in topological order
272
- 6. Wire imports into each package box
273
- 7. Execute command in root package context
274
-
275
- ### Internal Components
276
-
277
- Boxwerk consists of several internal components that work together to provide package isolation:
278
-
279
- #### `Boxwerk::CLI`
280
-
281
- The command-line interface handler that:
282
- - Parses commands (`run`, `console`, `help`)
283
- - Validates the Ruby environment (checks for `RUBY_BOX=1` and Ruby::Box support)
284
- - Delegates to `Boxwerk::Setup` for the boot process
285
- - Executes the requested command in the root package's box context
286
-
287
- #### `Boxwerk::Setup`
288
-
289
- The setup orchestrator that:
290
- - Searches up the directory tree to find the root `package.yml`
291
- - Creates a `Boxwerk::Graph` instance to build and validate the dependency graph
292
- - Creates a `Boxwerk::Registry` instance to track booted packages
293
- - Calls `Boxwerk::Loader.boot_all` to boot all packages in topological order
294
- - Returns the loaded graph for introspection
295
-
296
- #### `Boxwerk::Graph`
297
-
298
- The dependency graph builder that:
299
- - Parses the root `package.yml` and recursively discovers all package dependencies
300
- - Builds a directed acyclic graph (DAG) of package relationships
301
- - Validates that there are no circular dependencies
302
- - Performs topological sorting to determine boot order (dependencies before consumers)
303
- - Provides access to all packages in the graph
304
-
305
- #### `Boxwerk::Package`
306
-
307
- The package manifest parser that:
308
- - Represents a single package with its configuration
309
- - Parses `package.yml` files to extract exports and imports
310
- - Normalizes the polymorphic import syntax (String, Array, Hash)
311
- - Stores the package path, name, exports, imports, and box reference
312
- - Tracks which exports have been loaded via `loaded_exports` hash (export name β†’ file path)
313
- - Tracks whether the package has been booted
314
-
315
- #### `Boxwerk::Loader`
316
-
317
- The package loader that:
318
- - Creates a new `Ruby::Box` for each package (including the root package)
319
- - Loads exported constants lazily on-demand when they are imported by other packages
320
- - Uses Zeitwerk naming conventions to discover file locations for exported constants
321
- - Caches loaded exports in `package.loaded_exports` to avoid redundant file loading
322
- - Wires imports by injecting constants from dependency boxes into consumer boxes
323
- - Implements all four import strategies (default namespace, aliased namespace, selective import, selective rename)
324
- - Handles the single-export optimization for namespace imports
325
- - Registers each booted package in the registry
326
- - Only loads files that define exported constants, never loading non-exported code
327
-
328
- #### `Boxwerk::Registry`
329
-
330
- The package registry that:
331
- - Tracks all booted package instances
332
- - Allows packages to be retrieved by name during the wiring phase
333
- - Ensures each package is only booted once
334
- - Provides a clean interface for package lookup
335
-
336
- ## Example
337
-
338
- See the [example/](example/) directory for a complete working example with:
339
-
340
- - Multi-package application
341
- - Gem usage
342
- - Transitive dependency demonstration
343
- - Isolation verification
344
- - Console usage examples
345
-
346
- Run it with:
347
-
348
- ```bash
349
- cd example
350
- RUBY_BOX=1 boxwerk run app.rb
351
- ```
352
-
353
- Or explore interactively:
354
-
355
- ```bash
356
- cd example
357
- RUBY_BOX=1 boxwerk console
358
- ```
188
+ **Boot process:**
189
+ 1. Setup Bundler and require all gems in root box
190
+ 2. Find root `package.yml` by searching up from current directory
191
+ 3. Build and validate dependency graph (DAG)
192
+ 4. Boot packages in topological order, creating isolated boxes
193
+ 5. Wire imports by lazily loading exports and injecting constants
194
+ 6. Execute command in root package context
195
+
196
+ **Components:**
197
+ - **CLI**: Parses commands, validates environment, delegates to Setup
198
+ - **Setup**: Finds root package, builds graph, creates registry, boots packages
199
+ - **Graph**: Builds DAG, validates no cycles, performs topological sort
200
+ - **Package**: Parses `package.yml`, tracks exports/imports/box
201
+ - **Loader**: Creates boxes, loads exports lazily (Zeitwerk conventions), wires imports
202
+ - **Registry**: Tracks booted packages, ensures single boot per package
359
203
 
360
204
  ## Development
361
205
 
data/exe/boxwerk CHANGED
@@ -1,28 +1,20 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Boxwerk CLI
5
- # Usage: boxwerk <command> [args...]
6
-
7
- # Check if Ruby::Box is available and enabled
8
4
  unless ENV['RUBY_BOX'] == '1'
9
5
  puts "Error: Boxwerk requires Ruby::Box to be enabled"
10
6
  puts "Please set RUBY_BOX=1 environment variable"
11
7
  exit 1
12
8
  end
13
9
 
14
- # Verify Ruby::Box is actually available in this Ruby version
15
10
  unless defined?(Ruby::Box)
16
11
  puts "Error: Ruby::Box is not available in this Ruby version"
17
12
  puts "Boxwerk requires Ruby 4.0 or later with Box support"
18
13
  exit 1
19
14
  end
20
15
 
21
- # Setup Bundler, require any gems and run Boxwerk - all in the root box
22
16
  Ruby::Box.root.eval(<<~RUBY)
23
17
  require 'bundler/setup'
24
- # Application gems need to be required in the root box to be accessible in package boxes
25
18
  Bundler.require
26
- # Run the CLI to handle the invocation
27
19
  Boxwerk::CLI.run(ARGV)
28
20
  RUBY
data/lib/boxwerk/cli.rb CHANGED
@@ -1,20 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Boxwerk
4
- # CLI handles command-line execution of Boxwerk applications
4
+ # CLI parses commands and delegates to Setup for package management.
5
+ # Handles run, console, and help commands.
5
6
  module CLI
6
7
  class << self
7
- # Main entry point for CLI
8
- # @param argv [Array<String>] Command line arguments
9
8
  def run(argv)
10
9
  if argv.empty?
11
10
  print_usage
12
11
  exit 1
13
12
  end
14
13
 
15
- command = argv[0]
16
-
17
- case command
14
+ case argv[0]
18
15
  when 'run'
19
16
  run_command(argv[1..-1])
20
17
  when 'console'
@@ -23,7 +20,7 @@ module Boxwerk
23
20
  print_usage
24
21
  exit 0
25
22
  else
26
- puts "Error: Unknown command '#{command}'"
23
+ puts "Error: Unknown command '#{argv[0]}'"
27
24
  puts ''
28
25
  print_usage
29
26
  exit 1
@@ -41,8 +38,6 @@ module Boxwerk
41
38
  puts ' run <script.rb> [args...] Run a script in the root package context'
42
39
  puts ' console [irb-args...] Start an IRB console in the root package context'
43
40
  puts ' help Show this help message'
44
- puts ''
45
- puts 'All packages are loaded and wired before the command executes.'
46
41
  end
47
42
 
48
43
  def run_command(args)
@@ -54,50 +49,31 @@ module Boxwerk
54
49
  end
55
50
 
56
51
  script_path = args[0]
57
- script_args = args[1..-1] || []
58
-
59
- # Verify script exists
60
52
  unless File.exist?(script_path)
61
53
  puts "Error: Script not found: #{script_path}"
62
54
  exit 1
63
55
  end
64
56
 
65
- # Perform Boxwerk setup (find package.yml, build graph, boot packages)
66
57
  graph = perform_setup
67
-
68
- # Execute the script in the root package's box
69
- root_package = graph.root
70
- execute_in_box(root_package.box, script_path, script_args)
58
+ execute_in_box(graph.root.box, script_path, args[1..-1] || [])
71
59
  end
72
60
 
73
61
  def console_command(args)
74
- # Require IRB while we're still in root box context
75
62
  require 'irb'
76
-
77
- # Perform Boxwerk setup
78
63
  graph = perform_setup
79
-
80
- # Start IRB in the root package's box with provided args
81
- root_package = graph.root
82
- start_console_in_box(root_package.box, args)
64
+ start_console_in_box(graph.root.box, args)
83
65
  end
84
66
 
85
67
  def perform_setup
86
- begin
87
- Boxwerk::Setup.run!(start_dir: Dir.pwd)
88
- rescue => e
89
- puts "Error: #{e.message}"
90
- exit 1
91
- end
68
+ Boxwerk::Setup.run!(start_dir: Dir.pwd)
69
+ rescue => e
70
+ puts "Error: #{e.message}"
71
+ exit 1
92
72
  end
93
73
 
94
74
  def execute_in_box(box, script_path, script_args)
95
- # Set ARGV for the script using eval
96
75
  box.eval("ARGV.replace(#{script_args.inspect})")
97
-
98
- # Run the script in the isolated box
99
- absolute_script_path = File.expand_path(script_path)
100
- box.require(absolute_script_path)
76
+ box.require(File.expand_path(script_path))
101
77
  end
102
78
 
103
79
  def start_console_in_box(box, irb_args = [])
@@ -112,16 +88,8 @@ module Boxwerk
112
88
  puts '=' * 70
113
89
  puts ''
114
90
 
115
- # Start IRB in the box context.
116
- # TODO: This is currently broken. IRB runs the in the root box context.
117
- # This should be fixed by calling `require 'irb'` inside the box, but
118
- # that currently crashes the VM.
119
- # Set ARGV to the provided IRB args so they can be processed by IRB.
120
- # Always add --noautocomplete to disable autocomplete (currently broken with Ruby::Box)
121
- # TODO: Enable autocomplete when it's not broken.
122
- irb_args_with_noautocomplete = ['--noautocomplete'] + irb_args
123
91
  box.eval(<<~RUBY)
124
- ARGV.replace(#{irb_args_with_noautocomplete.inspect})
92
+ ARGV.replace(#{(['--noautocomplete'] + irb_args).inspect})
125
93
  IRB.start
126
94
  RUBY
127
95
  end