1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/bin/sh
# run-main — launch the installed `yog` and keep the window equal to main's tip.
#
# The machinery behind `make run` (the Makefile is the door, as with `drive`).
# It launches `$INSTALL_BIN/yog` in the FOREGROUND and relaunches it whenever
# the installed binary changes underneath it, so a merge landing on main closes
# the old window and opens one built from the new tip, with no operator verb in
# between.
#
# Usage (all three positional, as the Makefile passes them — it owns the paths):
# run-main <binary> <install-stamp> [workspace]
#
# It watches the STAMP, not the clock and not the binary's mtime: the stamp is
# the ONE record of which commit the installed binary was built from (written by
# `make install`, named by `make print-install-stamp`), so "the window is stale"
# is a string compare against a fact somebody else already established, and a
# half-written binary is never launched — the stamp moves after the rename.
#
# It also DISPATCHES `scripts/install-main` when main's tip is not what is
# installed. That is the same idempotent convergence `.githooks/
# reference-transaction` fires, so nothing is duplicated by running both; it is
# here so the verb stands on its own in a clone whose hooks were never armed
# (`make install-hooks`), and so a hook that failed or was missed still
# converges the moment you look at the window. Dispatch is once per tip: a
# build that fails warns and then waits for main to move again, rather than
# rebuilding every poll.
#
# It deliberately does NOT write YOG_PIDFILE. `make reload` kills the pid
# recorded there and launches a DETACHED replacement — beside this foreground
# supervisor that is two windows, both live, on one world. `run` owns its own
# relaunch; `ux`/`reload` own the pidfile instance. The two never see each other.
bin=
stamp=
ws=
here= ||
root= ||
poll=
# A tip we have already asked install-main to build. Seeded empty so the first
# poll converges a stale (or absent) install without waiting for a merge.
asked=
# Nothing to launch at all: converge synchronously, since there is no window to
# keep up while a detached build runs.
if [; then
asked=
|| {
}
fi
while ; do
launched=
if [; then
&
else
&
fi
pid=
restart=
while ; do
now=
if [ && [ && [; then
asked=
fi
if [; then
restart=yes
break
fi
done
# stderr silenced: when the swap above killed it, the shell's own job-control
# "Terminated" line reads as a crash to an operator who asked for a relaunch.
# Only a swap relaunches. A window the operator closed (or that crashed) ends
# the session — `make run` is a foreground verb, not a service manager.
[ ||
done