enola 0.5.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 689fed2c591f5809d780118557d16abb71dd2c16ae81e71382fbeee1cb70001e
4
- data.tar.gz: c7c4671e4d4c153f8f0f6db9f9395a6670681a1006581c5faecf2b196170cc30
3
+ metadata.gz: 0f5c39f1dcc7577ecde43a125b51c74b640ec8f10ce6d38e4008bec02d7e8df6
4
+ data.tar.gz: 3a56415c6823950a6e115dbbe1b282f564e609211ee65609ef39b7e5daa35f15
5
5
  SHA512:
6
- metadata.gz: b4a72e0931b1f110f482062fa8e2627f59adfac7add1592ea1c8ef22e5bc4f6f7fc5c4ae851cf7534c50997ec8fc3cd2928e3e84a0e3bc841f9f22ee87933d85
7
- data.tar.gz: 7f5cd2dc8f9b69897c095c54e95d4c9d58913607de47ca71789fa3eb8d419811d5d2c5393cc6abed7630e2f35314b6c76b61836beff63fa012761eaa0f27c4e7
6
+ metadata.gz: 9f2727a63a05b9aee2c24023014d7363c1b2fac11e4ad4cea85473d14bb4534fe769d5ff6e6c3ee6b71fd2a853cadd0d2dc67b72772d5188c2a63b7e05a5c033
7
+ data.tar.gz: 98734b4d06a0867d8808f023e59276d6c1b8e9dec27703078c5ae98f8dd02a2bd2add19606f42d4442f914b21818839af4bb5717448af5180aafd5ebb88453ca
data/CHANGELOG.md CHANGED
@@ -1,3 +1,38 @@
1
+ ## enola 0.5.2, enola-rb 0.5.2, munola 0.5.2 and munola-rb 0.5.2 (2026-08-23)
2
+
3
+ Rubydex is off in the config these gems write, and named in a comment beside
4
+ the reason. The release each gem drives carries a walk that can fail to
5
+ return: a constant reference spanning lines could be treated as its own
6
+ predecessor, so a tree with vendored gems could snapshot for twenty-six
7
+ minutes and several gigabytes without finishing. Two of the three Rails trees
8
+ it was tried on did exactly that.
9
+
10
+ The fix exists and is not yet in a published enola, so the default cannot
11
+ depend on it. Prism is unaffected and stays on: it parses a monolith in 13.7
12
+ seconds. Uncommenting the two lines brings Rubydex back for anyone who wants
13
+ it deliberately, and the default returns the moment the binary each gem drives
14
+ carries the fix.
15
+
16
+ ## enola 0.5.1 (2026-08-23)
17
+
18
+ The resolver no longer probes its own binstub. It read a candidate's first 512
19
+ bytes looking for the marker RubyGems writes, and a real binstub carries a
20
+ `/bin/sh` + `ruby -x` preamble holding the interpreter's absolute path, which puts
21
+ that marker around byte 580 — outside the window. So the guard missed every
22
+ RubyGems-generated binstub, the wrapper ran itself, and running itself has no
23
+ bottom: `enola --version` on a cold cache spawned Ruby processes until it was
24
+ killed. The whole file is read now, capped at 64 KiB so a released binary is never
25
+ slurped only to be rejected, and `Gem.bin_path` is recognised beside
26
+ `Gem.activate_bin_path`. A probe also marks its child's environment, and a resolver
27
+ that sees the marker declines to look at PATH at all, so the recursion is bounded
28
+ by construction rather than by how well a heuristic reads a file.
29
+
30
+ The marker is written where it is spawned: every probe passes it into the child,
31
+ so a wrapper reached under another name leaves PATH alone instead of probing in
32
+ turn. That bound is what covers the wrappers the content check cannot see, a
33
+ version manager's shim among them, which carries none of the markers a binstub
34
+ does. Reported and fixed by dejo1307 in #1.
35
+
1
36
  ## munola 0.4.4.2 and munola-rb 0.4.4.2 (2026-08-23)
2
37
 
3
38
  munola follows the channel it drives. Its binary is now cut from the stable
data/lib/enola/config.rb CHANGED
@@ -20,9 +20,11 @@ module Enola
20
20
 
21
21
  def self.render(ruby: Providers.ruby)
22
22
  <<~YAML
23
- # Written by the enola gem; edit freely. Both providers are on by default:
24
- # Prism runs under the Ruby that runs the gem, Rubydex is built into the
25
- # binary and fetched once. Remove one to leave it out of the graph.
23
+ # Written by the enola gem; edit freely. Prism is on by default and runs
24
+ # under the Ruby that runs the gem. Rubydex is left off: the release this
25
+ # gem drives has a walk that can fail to return on a tree with vendored
26
+ # gems, fixed but not yet in a published enola. Uncomment it to run it
27
+ # anyway, and expect a snapshot that may not finish.
26
28
  repo: .
27
29
  repos:
28
30
  - .
@@ -32,8 +34,8 @@ module Enola
32
34
  - name: prism
33
35
  command: [#{ruby.inspect}, #{Providers.prism_script.inspect}]
34
36
  expected_version: "#{Providers.prism_version || '0.1.0'}"
35
- - name: rubydex
36
- expected_version: "#{Providers::RUBYDEX_EXPECTED_VERSION}"
37
+ # - name: rubydex
38
+ # expected_version: "#{Providers::RUBYDEX_EXPECTED_VERSION}"
37
39
  YAML
38
40
  end
39
41
  end
data/lib/enola/probe.rb CHANGED
@@ -6,12 +6,18 @@ module Enola
6
6
  class Probe
7
7
  SURFACES = %w[constraints providers check plan hook].freeze
8
8
 
9
+ # A probed binary may be this wrapper wearing another name. The marker
10
+ # travels into the child, where the resolver reads it and leaves PATH
11
+ # alone, so a probe cannot start another one.
12
+ PROBE_ENV = "ENOLA_RESOLVER_PROBE"
13
+ CHILD_ENV = {PROBE_ENV => "1"}.freeze
14
+
9
15
  def initialize(binary)
10
16
  @binary = binary
11
17
  end
12
18
 
13
19
  def version
14
- out, status = Open3.capture2e(@binary, "--version")
20
+ out, status = Open3.capture2e(CHILD_ENV, @binary, "--version")
15
21
  return nil unless status.success?
16
22
 
17
23
  out[/\d+\.\d+\.\d+(?:[.-][\w.]+)?/]
@@ -23,7 +29,7 @@ module Enola
23
29
  # for --help); one it lacks is refused by the top-level dispatch by name.
24
30
  def capabilities
25
31
  SURFACES.to_h do |surface|
26
- out, = Open3.capture2e(@binary, surface, "--help")
32
+ out, = Open3.capture2e(CHILD_ENV, @binary, surface, "--help")
27
33
  [surface.to_sym, !out.include?("unknown command \"#{surface}\"")]
28
34
  rescue SystemCallError
29
35
  [surface.to_sym, false]
@@ -25,9 +25,19 @@ module Enola
25
25
 
26
26
  EXECUTABLE = File.expand_path("../../exe/enola", __dir__)
27
27
 
28
+ # A binstub is a script; the released binary is megabytes. The cap keeps the
29
+ # whole-file read cheap and means a real binary is never slurped to be rejected.
30
+ MAX_SCRIPT_BYTES = 64 * 1024
31
+
28
32
  private
29
33
 
30
34
  def matching_path_binary
35
+ # A probe runs the candidate, and the candidate may be this wrapper wearing
36
+ # another name. The marker travels into that child, and a resolver that finds
37
+ # it declines to look at PATH — so the recursion is bounded by construction
38
+ # rather than by how well the check below reads a file.
39
+ return [nil, nil] if ENV[Probe::PROBE_ENV]
40
+
31
41
  candidate = @path.split(File::PATH_SEPARATOR).map { |dir| File.join(dir, "enola") }
32
42
  .find { |bin| File.executable?(bin) && !wrapper?(bin) }
33
43
  return [nil, nil] unless candidate
@@ -39,11 +49,18 @@ module Enola
39
49
  # Bundler puts this gem's own exe on PATH, and a rubygems binstub for the
40
50
  # gem looks like a binary too; probing either would run the wrapper inside
41
51
  # itself without end.
52
+ #
53
+ # The whole file is read, not a fixed head. RubyGems writes a /bin/sh + `ruby -x`
54
+ # polyglot preamble carrying the interpreter's absolute path, so the marker sits
55
+ # ~580 bytes in — past the 512 this used to read, which made the guard miss every
56
+ # real binstub and the wrapper probe itself without end.
42
57
  def wrapper?(bin)
43
58
  return true if File.realpath(bin) == File.realpath(EXECUTABLE)
59
+ return false if File.size(bin) > MAX_SCRIPT_BYTES
44
60
 
45
- head = File.binread(bin, 512)
46
- head.include?("Gem.activate_bin_path") || head.include?('require "enola"')
61
+ body = File.binread(bin)
62
+ body.include?("Gem.activate_bin_path") || body.include?("Gem.bin_path") ||
63
+ body.include?('require "enola"')
47
64
  rescue SystemCallError
48
65
  true
49
66
  end
data/lib/enola/version.rb CHANGED
@@ -4,5 +4,5 @@ module Enola
4
4
  # The gem versions itself. UPSTREAM_VERSION names the enola release it
5
5
  # fetches and drives.
6
6
  UPSTREAM_VERSION = "0.4.4"
7
- VERSION = "0.5.0"
7
+ VERSION = "0.5.2"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enola
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muhamed Isabegovic