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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
#!/bin/sh
#
# Bump the canonical zyginit version.
#
# Usage: ./scripts/bump-version.sh <new-version>
#
# Rewrites in lock-step:
# - reef.toml (canonical)
# - tools/zygctl/reef.toml
# - src/version.reef (regenerated)
# - tools/zygctl/src/version.reef (regenerated)
# - tools/sysv-wrapper/version.h (regenerated)
#
# Does NOT auto-commit. Review with `hg diff` and commit by hand.
#
# ----------------------------------------------------------------------------
# Helpers for regenerating templated files.
# ----------------------------------------------------------------------------
gen_reef_module() {
project="$1"
path="$2"
version="$3"
cat > "$path" <<EOF
/******************************************************************************
__ ____ __
/ / ___ ____ _/ __/_____________ _/ /__
/ / / _ \\/ __ \`/ /_/ ___/ ___/ __ \`/ / _ \\
/ /___/ __/ /_/ / __(__ ) /__/ /_/ / / __/
/_____/\\___/\\__,_/_/ /____/\\___/\\__,_/_/\\___/
(C)opyright 2025-2026, Leafscale, LLC - https://www.leafscale.com
Project: $project
Filename: version.reef
Authors: Chris Tusa <chris.tusa@leafscale.com>
License: <see LICENSE file included with this source code>
Description: Generated version constant. Do not edit by hand — regenerated
by scripts/bump-version.sh.
******************************************************************************/
module version
export
fn VERSION(): string
end export
fn VERSION(): string
return "$version"
end VERSION
end module
EOF
}
gen_c_header() {
path="$1"
version="$2"
cat > "$path" <<EOF
/******************************************************************************
__ ____ __
/ / ___ ____ _/ __/_____________ _/ /__
/ / / _ \\/ __ \`/ /_/ ___/ ___/ __ \`/ / _ \\
/ /___/ __/ /_/ / __(__ ) /__/ /_/ / / __/
/_____/\\___/\\__,_/_/ /____/\\___/\\__,_/_/\\___/
(C)opyright 2025-2026, Leafscale, LLC - https://www.leafscale.com
Project: zyginit
Filename: version.h
Authors: Chris Tusa <chris.tusa@leafscale.com>
License: <see LICENSE file included with this source code>
Description: Generated version constant. Do not edit by hand — regenerated
by scripts/bump-version.sh.
******************************************************************************/
#ifndef ZYGINIT_VERSION_H
#define ZYGINIT_VERSION_H
#define ZYGINIT_VERSION "$version"
#endif
EOF
}
set -e
# This script uses GNU sed extensions (-i without backup suffix, 0,/addr/
# first-match range). Bumps are cut on a Linux dev host, not on Hammerhead;
# fail fast if invoked elsewhere so the breakage isn't a cryptic sed error.
case "$(uname -s)" in
Linux) ;;
*)
echo "error: bump-version.sh requires GNU sed (Linux dev host)" >&2
echo " detected: $(uname -s)" >&2
exit 1
;;
esac
if [ $# -ne 1 ]; then
echo "usage: $0 <new-version>" >&2
exit 1
fi
NEW="$1"
# Validate semver shape (no pre-release suffix yet).
echo "$NEW" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' || {
echo "error: '$NEW' is not in MAJOR.MINOR.PATCH form" >&2
exit 1
}
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
ROOT=$(dirname "$SCRIPT_DIR")
cd "$ROOT"
CURRENT=$(grep '^version' reef.toml | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
if [ -z "$CURRENT" ]; then
echo "error: could not read current version from reef.toml" >&2
exit 1
fi
if [ "$CURRENT" = "$NEW" ]; then
echo "error: version is already $NEW" >&2
exit 1
fi
echo "zyginit: bumping $CURRENT -> $NEW"
# 1. Root reef.toml — sed in place. Match only the first 'version = "..."'
# in the [package] table (top of file).
# $NEW is safe inside the substitution: the semver regex above guarantees
# digits + dots only — no '/' or '&' to misinterpret.
echo " rewriting reef.toml"
sed -i "0,/^version = \"[^\"]*\"/s//version = \"$NEW\"/" reef.toml
# 2. tools/zygctl/reef.toml
# $NEW is safe inside the substitution: the semver regex above guarantees
# digits + dots only — no '/' or '&' to misinterpret.
echo " rewriting tools/zygctl/reef.toml"
sed -i "0,/^version = \"[^\"]*\"/s//version = \"$NEW\"/" tools/zygctl/reef.toml
# 3. src/version.reef — full regenerate.
echo " regenerating src/version.reef"
gen_reef_module zyginit src/version.reef "$NEW"
# 4. tools/zygctl/src/version.reef — full regenerate.
echo " regenerating tools/zygctl/src/version.reef"
gen_reef_module zygctl tools/zygctl/src/version.reef "$NEW"
# 5. tools/sysv-wrapper/version.h — full regenerate.
echo " regenerating tools/sysv-wrapper/version.h"
gen_c_header tools/sysv-wrapper/version.h "$NEW"
echo
echo "summary of changes:"
hg diff --stat || true
echo
echo "review with 'hg diff' and commit:"
echo " hg ci -m 'Bump version to $NEW'"
#!/bin/sh
#
# Create a source release tarball for the zyginit suite.
#
# Usage: ./scripts/make-release.sh [version-override]
#
# Reads the canonical version from reef.toml unless an override is given.
# Produces:
# releases/zyginit-<version>-source.tar.xz
# releases/zyginit-<version>-source.tar.xz.sha256
#
set -e
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
ROOT=$(dirname "$SCRIPT_DIR")
cd "$ROOT"
if [ -n "$1" ]; then
VERSION="$1"
else
VERSION=$(grep '^version' reef.toml | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
fi
if [ -z "$VERSION" ]; then
echo "error: could not determine version" >&2
exit 1
fi
NAME="zyginit-${VERSION}-source"
RELEASES="releases"
TARBALL="${RELEASES}/${NAME}.tar.xz"
echo "Creating release: $NAME"
mkdir -p "$RELEASES"
tar \
--exclude='build' \
--exclude='build/*' \
--exclude='tools/*/build' \
--exclude='tools/*/build/*' \
--exclude='releases' \
--exclude='.hg' \
--exclude='.hgignore' \
--exclude='.hgtags' \
--exclude='resume' \
--exclude='ss' \
--exclude='stub' \
--exclude='*.o' \
--exclude='*.a' \
--exclude='*.swp' \
--transform "s,^,${NAME}/," \
-cJf "$TARBALL" \
reef.toml \
README.md \
ROADMAP.md \
CLAUDE.md \
SRCHEADER.txt \
src \
docs \
tests \
examples \
bugs \
tools \
utils \
scripts
echo "Created: $TARBALL"
ls -la "$TARBALL"
sha256sum "$TARBALL" > "${TARBALL}.sha256"
echo "Checksum: ${TARBALL}.sha256"
cat "${TARBALL}.sha256"
#!/bin/sh
# *****************************************************************************
# __ ____ __
# / / ___ ____ _/ __/_____________ _/ /__
# / / / _ \/ __ `/ /_/ ___/ ___/ __ `/ / _ \
# / /___/ __/ /_/ / __(__ ) /__/ /_/ / / __/
# /_____/\___/\__,_/_/ /____/\___/\__,_/_/\___/
#
# (C)opyright 2025-2026, Leafscale, LLC - https://www.leafscale.com
#
# Project: zyginit
# Filename: migrate-layout.sh
# Authors: Chris Tusa <chris.tusa@leafscale.com>
# License: CDDL-1.0
# Description: Migrate a 0.1.x /etc/zyginit/ flat layout to the 0.2.0
# per-service directory layout. Idempotent. Dry-run by default.
# Run with --apply to actually move files.
#
# *****************************************************************************
set -e
usage() {
cat <<EOF
Usage: $0 [--dry-run|--apply] [--config-dir <path>]
--dry-run Print planned moves and exit (default)
--apply Perform the moves
--config-dir DIR Target directory (default /etc/zyginit/)
-h, --help Show this help
EOF
}
MODE=dry-run
CONFIG_DIR=/etc/zyginit
while [ $# -gt 0 ]; do
case "$1" in
--dry-run) MODE=dry-run; shift ;;
--apply) MODE=apply; shift ;;
--config-dir) CONFIG_DIR="$2"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) echo "error: unknown arg: $1" >&2; usage >&2; exit 2 ;;
esac
done
if [ ! -d "$CONFIG_DIR" ]; then
echo "error: $CONFIG_DIR is not a directory" >&2
exit 1
fi
cd "$CONFIG_DIR"
# Ambiguity check: refuse if any service has BOTH <name>.toml at top level
# AND services/<name>/service.toml.
AMBIGUOUS=""
if [ -d services ]; then
for f in *.toml; do
[ -f "$f" ] || continue
name="${f%.toml}"
if [ -f "services/$name/service.toml" ]; then
AMBIGUOUS="$AMBIGUOUS $name"
fi
done
fi
if [ -n "$AMBIGUOUS" ]; then
echo "error: ambiguous layout — both old <name>.toml and services/<name>/service.toml exist for:$AMBIGUOUS" >&2
echo " Resolve manually before re-running." >&2
exit 3
fi
# Plan moves
PLAN_FILE=$(mktemp /tmp/migrate-plan.XXXXXX)
trap 'rm -f "$PLAN_FILE"' EXIT
COUNT=0
for f in *.toml; do
[ -f "$f" ] || continue
name="${f%.toml}"
echo "mkdir -p services/$name" >> "$PLAN_FILE"
echo "mv $f services/$name/service.toml" >> "$PLAN_FILE"
if [ -d "$name" ] && [ ! -L "$name" ]; then
# Move helper scripts (start.sh, stop.sh, etc.) into the new dir
for sf in "$name"/*; do
[ -e "$sf" ] || continue
base=$(basename "$sf")
echo "mv $name/$base services/$name/$base" >> "$PLAN_FILE"
done
echo "rmdir $name" >> "$PLAN_FILE"
fi
COUNT=$((COUNT + 1))
done
# Plan enabled.d symlink retarget
if [ -d enabled.d ]; then
for link in enabled.d/*; do
[ -L "$link" ] || continue
target=$(readlink "$link")
case "$target" in
*.toml)
name=$(basename "$link")
echo "ln -sfn ../services/$name $link" >> "$PLAN_FILE"
;;
esac
done
fi
# Plan examples/ migration (same convention as services/)
if [ -d examples ]; then
for f in examples/*.toml; do
[ -f "$f" ] || continue
name=$(basename "${f%.toml}")
echo "mkdir -p examples/$name" >> "$PLAN_FILE"
echo "mv $f examples/$name/service.toml" >> "$PLAN_FILE"
done
fi
if [ ! -s "$PLAN_FILE" ]; then
echo "no changes — tree already in 0.2.0 layout"
exit 0
fi
if [ "$MODE" = "dry-run" ]; then
echo "PLANNED MOVES ($COUNT services):"
cat "$PLAN_FILE"
echo
echo "Re-run with --apply to perform these moves."
exit 0
fi
# Apply
echo "Applying $COUNT services..."
while IFS= read -r line; do
eval "$line"
done < "$PLAN_FILE"
echo "Migration complete."
|