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 +4 -4
- data/CHANGELOG.md +35 -0
- data/lib/enola/config.rb +7 -5
- data/lib/enola/probe.rb +8 -2
- data/lib/enola/resolver.rb +19 -2
- data/lib/enola/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f5c39f1dcc7577ecde43a125b51c74b640ec8f10ce6d38e4008bec02d7e8df6
|
|
4
|
+
data.tar.gz: 3a56415c6823950a6e115dbbe1b282f564e609211ee65609ef39b7e5daa35f15
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
24
|
-
#
|
|
25
|
-
#
|
|
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
|
-
|
|
36
|
-
|
|
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]
|
data/lib/enola/resolver.rb
CHANGED
|
@@ -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
|
-
|
|
46
|
-
|
|
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