enola 0.4.4.1 → 0.5.1
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 +20 -0
- data/LICENSE +1 -1
- data/README.md +13 -11
- data/lib/enola/probe.rb +8 -2
- data/lib/enola/resolver.rb +19 -2
- data/lib/enola/version.rb +3 -3
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 35717854ffb165b2d79fe06be0998d847a25a0ce10a2907ab155a39fd3119a75
|
|
4
|
+
data.tar.gz: 8940517eabb47871b5321fd23ed4f369cc7f31486f2f486096fdf78cd8e6cbcc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cd181d1618ba05ebea4a77136ed6fc5d3afd197978c955576e1c8554d374b7558c3b4b0bd12b87e14f4c88642ff55faa6a5e8ef35bf12e33963fe7345418a778
|
|
7
|
+
data.tar.gz: 89206de715d8b08d9b7138cf4400df93b9385cf8b45c94bb08aa7de7b90f01267398e4d5da1f1ed3a4e87cd58ad33cf1e5f7492a6480ccee647a9129806ec142
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## enola 0.5.1 (2026-08-23)
|
|
2
|
+
|
|
3
|
+
The resolver no longer probes its own binstub. It read a candidate's first 512
|
|
4
|
+
bytes looking for the marker RubyGems writes, and a real binstub carries a
|
|
5
|
+
`/bin/sh` + `ruby -x` preamble holding the interpreter's absolute path, which puts
|
|
6
|
+
that marker around byte 580 — outside the window. So the guard missed every
|
|
7
|
+
RubyGems-generated binstub, the wrapper ran itself, and running itself has no
|
|
8
|
+
bottom: `enola --version` on a cold cache spawned Ruby processes until it was
|
|
9
|
+
killed. The whole file is read now, capped at 64 KiB so a released binary is never
|
|
10
|
+
slurped only to be rejected, and `Gem.bin_path` is recognised beside
|
|
11
|
+
`Gem.activate_bin_path`. A probe also marks its child's environment, and a resolver
|
|
12
|
+
that sees the marker declines to look at PATH at all, so the recursion is bounded
|
|
13
|
+
by construction rather than by how well a heuristic reads a file.
|
|
14
|
+
|
|
15
|
+
The marker is written where it is spawned: every probe passes it into the child,
|
|
16
|
+
so a wrapper reached under another name leaves PATH alone instead of probing in
|
|
17
|
+
turn. That bound is what covers the wrappers the content check cannot see, a
|
|
18
|
+
version manager's shim among them, which carries none of the markers a binstub
|
|
19
|
+
does. Reported and fixed by dejo1307 in #1.
|
|
20
|
+
|
|
1
21
|
## munola 0.4.4.2 and munola-rb 0.4.4.2 (2026-08-23)
|
|
2
22
|
|
|
3
23
|
munola follows the channel it drives. Its binary is now cut from the stable
|
data/LICENSE
CHANGED
|
@@ -187,7 +187,7 @@ APPENDIX: How to apply the Apache License to your work.
|
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
|
188
188
|
identification within third-party archives.
|
|
189
189
|
|
|
190
|
-
Copyright (c) 2026
|
|
190
|
+
Copyright (c) 2026 Muhamed Isabegovic
|
|
191
191
|
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
193
|
you may not use this file except in compliance with the License.
|
data/README.md
CHANGED
|
@@ -11,8 +11,9 @@ once, in `enola-rb`, and the munola gems add only what is munola's own.
|
|
|
11
11
|
|
|
12
12
|
## `enola`
|
|
13
13
|
|
|
14
|
-
The wrapper of the released enola.
|
|
15
|
-
drives
|
|
14
|
+
The wrapper of the released enola. The gem versions itself; the release it
|
|
15
|
+
drives is `Enola::UPSTREAM_VERSION`, v0.4.4 as of `enola 0.5.0`, and every
|
|
16
|
+
gemspec summary names it.
|
|
16
17
|
|
|
17
18
|
```ruby
|
|
18
19
|
gem "enola"
|
|
@@ -44,7 +45,7 @@ This gem is not an enola-labs release; it runs theirs.
|
|
|
44
45
|
|
|
45
46
|
## `enola-rb`
|
|
46
47
|
|
|
47
|
-
The Rails layer over `enola`. It depends on `enola` at the same
|
|
48
|
+
The Rails layer over `enola`. It depends on `enola` at the same minor and on
|
|
48
49
|
[enola-guides](https://github.com/misabegovic/enola-guides), and adds nothing
|
|
49
50
|
to the binary's surface.
|
|
50
51
|
|
|
@@ -73,10 +74,10 @@ remedy.
|
|
|
73
74
|
|
|
74
75
|
One person's taste on top of enola: the same wrapper over another channel,
|
|
75
76
|
the builds cut from [a fork of enola](https://github.com/misabegovic/enola),
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
against it. What it adds is the channel and the catalogue.
|
|
77
|
+
each release naming what differs from that upstream. The gem versions itself;
|
|
78
|
+
the channel release it fetches is `Munola::CHANNEL_VERSION`, which carries the
|
|
79
|
+
upstream it is built on plus a segment of its own (`0.4.4.2` on v0.4.4). It is
|
|
80
|
+
offered upstream where it fits and is not positioned against it. What it adds is the channel and the catalogue.
|
|
80
81
|
|
|
81
82
|
```ruby
|
|
82
83
|
gem "munola"
|
|
@@ -99,18 +100,19 @@ inflection table; it writes `mcp-arch.yaml` with both Ruby providers on by
|
|
|
99
100
|
default, Prism through the script the `enola` gem carries and Rubydex built
|
|
100
101
|
into the binary, and fetches the Rubydex library, a failed fetch reported as a
|
|
101
102
|
named skip. It never asks a question. `munola --version` names the munola
|
|
102
|
-
version, the upstream it is built on and which binary
|
|
103
|
+
version, the channel release and upstream it is built on, and which binary
|
|
104
|
+
answered.
|
|
103
105
|
|
|
104
106
|
The binary comes from the fork's releases the way `enola`'s comes from
|
|
105
107
|
upstream's, fetched on first use and verified against the sha256 the release
|
|
106
108
|
publishes; `MUNOLA_BINARY=/path/to/enola` names one to drive instead, and
|
|
107
|
-
every command says which answered. `munola` depends on `enola` at
|
|
108
|
-
|
|
109
|
+
every command says which answered. `munola` depends on `enola` at the same
|
|
110
|
+
minor and on `enola-guides` 0.3.1 or later; requiring it loads no Rails.
|
|
109
111
|
|
|
110
112
|
## `munola-rb`
|
|
111
113
|
|
|
112
114
|
The Rails layer over `munola`, what `enola-rb` is to `enola`. It depends on
|
|
113
|
-
both at
|
|
115
|
+
both at the same minor and adds one generator.
|
|
114
116
|
|
|
115
117
|
```ruby
|
|
116
118
|
gem "munola-rb"
|
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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Enola
|
|
4
|
-
# The
|
|
5
|
-
#
|
|
4
|
+
# The gem versions itself. UPSTREAM_VERSION names the enola release it
|
|
5
|
+
# fetches and drives.
|
|
6
6
|
UPSTREAM_VERSION = "0.4.4"
|
|
7
|
-
VERSION = "
|
|
7
|
+
VERSION = "0.5.1"
|
|
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.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Muhamed Isabegovic
|
|
@@ -26,8 +26,9 @@ dependencies:
|
|
|
26
26
|
version: '1.3'
|
|
27
27
|
description: |
|
|
28
28
|
A pure-Ruby wrapper around enola, the architecture-graph tool by enola-labs.
|
|
29
|
-
The gem
|
|
30
|
-
|
|
29
|
+
The gem versions itself; the enola release it drives is named in its
|
|
30
|
+
UPSTREAM_VERSION, 0.4.4 here. The binary is not in the
|
|
31
|
+
gem: the first command that needs it downloads the release for your
|
|
31
32
|
platform, verifies it against the checksum the release publishes, and keeps
|
|
32
33
|
it in a per-user cache. Every command and exit code is forwarded unchanged.
|
|
33
34
|
This gem is not an enola-labs release.
|
|
@@ -79,6 +80,6 @@ requirements: []
|
|
|
79
80
|
rubygems_version: 3.5.22
|
|
80
81
|
signing_key:
|
|
81
82
|
specification_version: 4
|
|
82
|
-
summary: 'Runs the released enola from Ruby: fetched on first use, verified,
|
|
83
|
-
|
|
83
|
+
summary: 'Runs the released enola from Ruby: fetched on first use, verified, cached.
|
|
84
|
+
This release drives enola 0.4.4.'
|
|
84
85
|
test_files: []
|