yamine 0.7.1 → 0.8.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 +35 -0
- data/lib/ask/skills/yamine/SKILL.md +22 -0
- data/lib/yamine/cli/system.rb +8 -2
- data/lib/yamine/hosts.rb +13 -0
- data/lib/yamine/log.rb +15 -3
- data/lib/yamine/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: 46a9c0208ca1d5581c3c25d45b60370a6e37c7dd4fcf721bda7a5573fc1c70db
|
|
4
|
+
data.tar.gz: 0b534671965987794b3872969dcc3065dfca5532a401f12701e531a0779e7820
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 339e64fabec8dab3c019bfdec8ec8f9f558dc4700b647fd462c4898e4f8796f93c1b65078d9ff171c338f38c70d055a8185b1d21bb547c63831bd816c5b7c6de
|
|
7
|
+
data.tar.gz: a71d56eef8327103f46a050307bb01095810ccd70085f3728a430617d3230cf567ffe3e9a04047428d6988d63efa7dd6965546bbb5e689f270991f8d4cc55d6d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.1] — 2026-09-10
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **An already-correct `/etc/hosts` no longer reports a failure.**
|
|
8
|
+
`Hosts.sync` rewrote the file unconditionally, so on a normal machine
|
|
9
|
+
(where `/etc/hosts` is root-owned) it raised `Errno::EACCES`, returned
|
|
10
|
+
false, and made `yamine start` print "could not write /etc/hosts (try
|
|
11
|
+
sudo yamine hosts sync)" on every boot — pointing at an elevated write
|
|
12
|
+
for a file that already had exactly the right block. `synced?` existed
|
|
13
|
+
for precisely this guard but `sync` never consulted it. `sync` is now a
|
|
14
|
+
no-op returning true when the block already matches, and the setup step
|
|
15
|
+
reports "already lists N hostname(s)" instead of implying a failure.
|
|
16
|
+
Chrome/Firefox/Edge resolve `*.localhost` natively anyway; the file only
|
|
17
|
+
matters for Safari and custom TLDs.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## [0.8.0] — 2026-09-10
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **`--json` progress is flushed as it happens.** stdout is
|
|
25
|
+
block-buffered when it is a pipe — exactly how an agent reads the
|
|
26
|
+
stream — so the per-phase events added in 0.7.0 stayed in the buffer
|
|
27
|
+
until it filled or the process exited, making a slow boot look frozen.
|
|
28
|
+
That is the "poll and guess" behaviour the JSON stream exists to
|
|
29
|
+
replace. Every line is now flushed before the next phase runs.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- The yamine agent skill documents the boot stream: the human
|
|
34
|
+
phase lines, the `--json` contract (one flushed object per line, human
|
|
35
|
+
banner on stderr, payload last), and that failures carry the log tail
|
|
36
|
+
and path.
|
|
37
|
+
|
|
3
38
|
## [0.7.1] — 2026-09-10
|
|
4
39
|
|
|
5
40
|
### Fixed
|
|
@@ -46,6 +46,28 @@ yamine log [-f] # tail the web process log
|
|
|
46
46
|
stable URLs, background ones are supervised without routes. A process
|
|
47
47
|
that exits cleans up the whole tree.
|
|
48
48
|
|
|
49
|
+
The boot narrates every phase — deps, db, schema, and each process's
|
|
50
|
+
healthcheck — one line per phase, so a slow boot is never a black box:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
[deps] ok (479ms) dependencies satisfied
|
|
54
|
+
[web] ok (2.2s) healthcheck /up returned 2xx-3xx
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
With `--json` the same events stream to stdout as one JSON object per
|
|
58
|
+
line, flushed as they happen (safe to read incrementally), and the
|
|
59
|
+
human banner moves to stderr — so stdout stays parseable and the final
|
|
60
|
+
payload is the last line:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
{"phase":"deps","action":"deps","status":"ok","duration_ms":479,...}
|
|
64
|
+
{"phase":"process","action":"web","status":"ok","duration_ms":2223,...}
|
|
65
|
+
{"ok":true,"service":"myapp","urls":{"web":"https://myapp.localhost"},...}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
On failure the payload carries the failed phase, that process's log tail,
|
|
69
|
+
and the log path — no need to go digging.
|
|
70
|
+
|
|
49
71
|
## Cross-service wiring
|
|
50
72
|
|
|
51
73
|
```bash
|
data/lib/yamine/cli/system.rb
CHANGED
|
@@ -220,6 +220,8 @@ module Yamine
|
|
|
220
220
|
hostnames = ctx.store.load_routes.map { |r| r["hostname"] }
|
|
221
221
|
if hostnames.empty?
|
|
222
222
|
puts " No routes registered yet — hosts sync will happen on the next boot."
|
|
223
|
+
elsif Yamine::Hosts.synced?(hostnames)
|
|
224
|
+
puts " /etc/hosts already lists #{hostnames.length} hostname(s)."
|
|
223
225
|
elsif Yamine::Hosts.sync(hostnames)
|
|
224
226
|
puts " Synced #{hostnames.length} hostname(s) to /etc/hosts."
|
|
225
227
|
else
|
|
@@ -758,8 +760,12 @@ module Yamine
|
|
|
758
760
|
end
|
|
759
761
|
end
|
|
760
762
|
|
|
761
|
-
# 3. Hosts (best-effort: only needed for Safari
|
|
762
|
-
|
|
763
|
+
# 3. Hosts (best-effort: only needed for Safari and custom TLDs —
|
|
764
|
+
# Chrome/Firefox/Edge resolve *.localhost natively). Already-synced
|
|
765
|
+
# is the common case and must stay silent: warning there sent
|
|
766
|
+
# people to a sudo write for a file that needed nothing.
|
|
767
|
+
hostnames = ctx.store.load_routes.map { |r| r["hostname"] }
|
|
768
|
+
unless hostnames.empty? || Yamine::Hosts.synced?(hostnames) || Hosts.sync(hostnames)
|
|
763
769
|
warn "Warning: could not write /etc/hosts (try sudo yamine hosts sync)."
|
|
764
770
|
end
|
|
765
771
|
end
|
data/lib/yamine/hosts.rb
CHANGED
|
@@ -41,7 +41,20 @@ module Yamine
|
|
|
41
41
|
names
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Bring the managed block to exactly these hostnames. Idempotent: when
|
|
45
|
+
# the block already matches, this is a no-op returning true.
|
|
46
|
+
#
|
|
47
|
+
# The short-circuit is load-bearing, not an optimization. /etc/hosts is
|
|
48
|
+
# root-owned on a normal machine, so a rewrite fails without sudo — and
|
|
49
|
+
# `setup` and every boot's workstation check run this. Without the
|
|
50
|
+
# guard, a machine whose hosts file was already correct got a
|
|
51
|
+
# "could not write /etc/hosts (try sudo yamine hosts sync)" warning on
|
|
52
|
+
# every run, sending people to an elevated write for a file that
|
|
53
|
+
# needed nothing. (Chrome/Firefox/Edge resolve *.localhost natively;
|
|
54
|
+
# /etc/hosts only matters for Safari and custom TLDs.)
|
|
44
55
|
def sync(hostnames, path = PATH)
|
|
56
|
+
return true if synced?(hostnames, path)
|
|
57
|
+
|
|
45
58
|
content = read(path)
|
|
46
59
|
block = managed_block(hostnames)
|
|
47
60
|
if content.include?(BEGIN_MARKER)
|
data/lib/yamine/log.rb
CHANGED
|
@@ -96,6 +96,12 @@ module Yamine
|
|
|
96
96
|
|
|
97
97
|
# One JSON object per line — the agent contract. Same events, no
|
|
98
98
|
# prose.
|
|
99
|
+
#
|
|
100
|
+
# Every line is flushed. stdout is block-buffered when it is a pipe
|
|
101
|
+
# or a file, which is exactly how an agent reads it, so without the
|
|
102
|
+
# flush the whole progress stream stays invisible until the buffer
|
|
103
|
+
# fills or the process exits — the "poll and guess" behaviour the
|
|
104
|
+
# JSON stream exists to replace, now with extra steps.
|
|
99
105
|
class Json
|
|
100
106
|
def initialize(io = $stdout)
|
|
101
107
|
@io = io
|
|
@@ -103,12 +109,18 @@ module Yamine
|
|
|
103
109
|
|
|
104
110
|
def event(event)
|
|
105
111
|
require "json"
|
|
106
|
-
|
|
112
|
+
emit(event.to_h)
|
|
107
113
|
end
|
|
108
114
|
|
|
109
115
|
def note(message)
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
emit({ note: message })
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
def emit(payload)
|
|
122
|
+
@io.puts JSON.generate(payload)
|
|
123
|
+
@io.flush if @io.respond_to?(:flush)
|
|
112
124
|
end
|
|
113
125
|
end
|
|
114
126
|
end
|
data/lib/yamine/version.rb
CHANGED