carton 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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +119 -1
  3. data/README.md +98 -26
  4. data/lib/carton/activate_gems.rb +8 -0
  5. data/lib/carton/box.rb +96 -69
  6. data/lib/carton/bundler.rb +73 -0
  7. data/lib/carton/error.rb +23 -0
  8. data/lib/carton/export_declaration.rb +72 -0
  9. data/lib/carton/export_methods.rb +7 -2
  10. data/lib/carton/exports.rb +27 -8
  11. data/lib/carton/gem_activation.rb +117 -0
  12. data/lib/carton/import_cache.rb +70 -0
  13. data/lib/carton/kernel_patch.rb +15 -5
  14. data/lib/carton/resolver.rb +120 -0
  15. data/lib/carton/runtime.rb +74 -53
  16. data/lib/carton/version.rb +1 -1
  17. data/lib/carton.rb +12 -19
  18. data/sig/carton.rbs +42 -0
  19. metadata +17 -31
  20. data/AGENTS.md +0 -47
  21. data/DESIGN.md +0 -84
  22. data/Rakefile +0 -52
  23. data/TODO.md +0 -33
  24. data/USAGE.md +0 -173
  25. data/examples/complex/README.md +0 -33
  26. data/examples/complex/cartons/adventure/.env +0 -1
  27. data/examples/complex/cartons/adventure/Gemfile +0 -5
  28. data/examples/complex/cartons/adventure/Gemfile.lock +0 -17
  29. data/examples/complex/cartons/adventure/lib/adventure.rb +0 -12
  30. data/examples/complex/cartons/loot/.env +0 -1
  31. data/examples/complex/cartons/loot/Gemfile +0 -5
  32. data/examples/complex/cartons/loot/Gemfile.lock +0 -17
  33. data/examples/complex/cartons/loot/lib/loot.rb +0 -47
  34. data/examples/complex/cartons/quest/lib/quest.rb +0 -6
  35. data/examples/complex/main.rb +0 -37
  36. data/examples/minimal/README.md +0 -16
  37. data/examples/minimal/bar.rb +0 -10
  38. data/examples/minimal/baz.rb +0 -7
  39. data/examples/minimal/foo.rb +0 -7
  40. data/examples/minimal/main.rb +0 -17
  41. data/images/carton.png +0 -0
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
- require 'open3'
5
- require 'rbconfig'
6
-
7
- Plans = import 'quest'
8
-
9
- # This carton is imported plainly by name. The subprocess below is where it
10
- # selects its own Gemfile, because doing the conflicting dotenv activation
11
- # directly in another box still collides through shared RubyGems activation
12
- # state and can even crash under Ruby::Box today.
13
- dotenv_payload =
14
- begin
15
- env_file = File.expand_path('../.env', __dir__)
16
- gemfile = File.expand_path('../Gemfile', __dir__)
17
- script = <<~'RUBY'
18
- require 'json'
19
- require 'bundler/setup'
20
- require 'dotenv'
21
-
22
- config = Dotenv.parse(ARGV.fetch(0))
23
- version = Gem.loaded_specs.fetch('dotenv').version.to_s
24
- puts JSON.generate(version:, config:)
25
- RUBY
26
-
27
- output, status =
28
- Open3.capture2e(
29
- { 'BUNDLE_GEMFILE' => gemfile },
30
- RbConfig.ruby,
31
- '-e',
32
- script,
33
- env_file,
34
- )
35
-
36
- unless status.success?
37
- raise RuntimeError, "failed to load loot dotenv bundle: #{output}"
38
- end
39
-
40
- JSON.parse output
41
- end
42
-
43
- dotenv_version = dotenv_payload.fetch 'version'
44
- legacy_message =
45
- "#{dotenv_payload.fetch('config').fetch('MESSAGE')} | quest says: #{Plans.fetch :summary}"
46
-
47
- export legacy_message:, DOTENV_VERSION: dotenv_version
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- FEATURES = ['single exports', 'named exports', 'import by name'].freeze
4
- SUMMARY = 'plain carton loaded by name'
5
-
6
- export FEATURES:, summary: SUMMARY
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../lib/carton'
4
-
5
- cartons_dir = File.expand_path('cartons', __dir__)
6
-
7
- # Local carton lib directories still need to be on the caller's load path when
8
- # we want import 'name' to resolve inside nested boxes.
9
- Dir
10
- .glob(File.join(cartons_dir, '*/lib'))
11
- .sort
12
- .each { |dir| $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) }
13
-
14
- adventure_gemfile = File.expand_path('cartons/adventure/Gemfile', __dir__)
15
-
16
- # Bundler still picks the active Gemfile from env/process state today, so the
17
- # bundled import stays explicit even though the wrapper is small.
18
- Adventure = Carton.with_bundle(adventure_gemfile) { import 'adventure' }
19
-
20
- Plans = import 'quest'
21
-
22
- # loot still imports by name, but it does not need Carton.with_bundle here
23
- # because the conflicting dotenv activation happens entirely in the subprocess
24
- # inside loot.rb, not during this import itself.
25
- import('loot') => { legacy_message:, DOTENV_VERSION: loot_dotenv_version }
26
-
27
- puts '-- Bundled single export --'
28
- puts "Adventure.banner = #{Adventure.banner}"
29
- puts "Adventure.dotenv_version = #{Adventure.dotenv_version}"
30
- puts
31
- puts '-- Named export loaded by name --'
32
- puts "Plans::FEATURES = #{Plans::FEATURES.join(', ')}"
33
- puts "Plans.summary = #{Plans.fetch :summary}"
34
- puts
35
- puts '-- Destructured named export --'
36
- puts "loot dotenv version = #{loot_dotenv_version}"
37
- puts "legacy_message = #{legacy_message}"
@@ -1,16 +0,0 @@
1
- # Minimal example
2
-
3
- Smallest working example of the library.
4
-
5
- ## What it shows
6
-
7
- - single export (`foo.rb`, `baz.rb`)
8
- - named exports (`bar.rb`)
9
- - `import_relative`
10
- - one carton importing another carton internally
11
-
12
- ## Run
13
-
14
- ```sh
15
- RUBY_BOX=1 ruby examples/minimal/main.rb
16
- ```
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Bar depends on Baz via import_relative
4
- Baz = import_relative 'baz'
5
-
6
- def hello
7
- "Hello from Bar! (#{Baz.hello})"
8
- end
9
-
10
- export hello: method(:hello), MAGIC: 42
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Baz
4
- def self.hello = 'Hello from Baz!'
5
- end
6
-
7
- export_default Baz
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Foo
4
- def self.hello = 'Hello from Foo!'
5
- end
6
-
7
- export_default Foo
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../lib/carton'
4
-
5
- # Single import — Foo exports a module
6
- Foo = import_relative 'foo'
7
-
8
- # Namespace import — Bar exports a hash with methods and constants
9
- Bar = import_relative 'bar'
10
-
11
- puts '-- Foo --'
12
- puts Foo.hello
13
-
14
- puts
15
- puts '-- Bar (uses Baz internally) --'
16
- puts Bar.hello
17
- puts "Bar::MAGIC = #{Bar::MAGIC}"
data/images/carton.png DELETED
Binary file