Skip to content

Commit 70ee99d

Browse files
committed
Split tools.func into five parts behind an unchanged loader
tools.func was 10,449 lines and 134 functions, a third of the whole engine in one unsectioned file. The implementations now sit in shared/tools/ by domain -- system, forge, runtime, db, hwaccel -- and shared/tools.func is an 80-line loader, so every caller still sources exactly one file. Nothing about the API changed. The split was done by segmenting on top-level definitions and proven lossless two ways: concatenating the segments in original order reproduces the file byte for byte, and sourcing the loader yields the same 133 functions with byte-identical bodies as sourcing the original. That proof mattered. get_current_ip looks like a 134th top-level definition but is payload inside a heredoc that setup_local_ip_helper writes to disk. Splitting on brace balance would have cut that function in half; splitting on the next definition kept it whole, and it happened to land in the same part as its parent. Had it been classified elsewhere, the heredoc would have been torn across two files and the generated helper truncated -- visible only on a user's host, at install time. So shared/tools/API.txt records the exported set and a workflow diffs against it on any change under shared/tools/, alongside a parse check of every part. Two pre-existing documentation errors surfaced while cross-checking the published reference: it lists get_current_ip, which is heredoc payload and not an API at all, and is_alpine, which exists in core.func and alpine-tools.func rather than here.
1 parent e6ad1b3 commit 70ee99d

9 files changed

Lines changed: 10697 additions & 10400 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Verify tools split
2+
3+
# shared/tools.func is the published helper API for script authors, and its
4+
# implementation is split across shared/tools/*.func. A split can silently lose
5+
# a function -- most easily by cutting through a heredoc that contains a
6+
# column-0 function definition, which looks like a definition but is payload.
7+
# That only surfaces on a user's host, so it is checked here instead.
8+
9+
on:
10+
pull_request:
11+
paths:
12+
- "shared/tools.func"
13+
- "shared/tools/**"
14+
push:
15+
branches: [main]
16+
paths:
17+
- "shared/tools.func"
18+
- "shared/tools/**"
19+
workflow_dispatch:
20+
21+
jobs:
22+
verify:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Every part parses
28+
run: |
29+
set -euo pipefail
30+
for f in shared/tools.func shared/tools/*.func; do
31+
bash -n "$f" || { echo "::error file=$f::syntax error"; exit 1; }
32+
done
33+
34+
- name: The loader still defines the whole API
35+
run: |
36+
set -euo pipefail
37+
COMMUNITY_SCRIPTS_CORE_DIR="$PWD"
38+
_cs_source_func() { source "$COMMUNITY_SCRIPTS_CORE_DIR/$1"; }
39+
export -f _cs_source_func 2>/dev/null || true
40+
source shared/tools.func >/dev/null 2>&1
41+
declare -F | awk '{print $3}' \
42+
| grep -v '^_cs_source_func$\|^_tools_source_part$' | sort > /tmp/actual.txt
43+
if ! diff -u shared/tools/API.txt /tmp/actual.txt; then
44+
echo "::error::the set of exported functions changed."
45+
echo "Intentional? Regenerate shared/tools/API.txt in the same PR."
46+
exit 1
47+
fi
48+
echo "$(wc -l < /tmp/actual.txt) functions, unchanged"

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ shared/ platform-agnostic engine
7171
build.func entry point, origin resolution, platform dispatch
7272
build-ui.func whiptail wizard, validators, advanced settings
7373
core.func colors, spinners, messaging, silent()
74-
tools.func helper library used by install scripts
74+
tools.func helper library used by install scripts (loader)
75+
tools/system.func packages, repositories, OS probes, services
76+
tools/forge.func GitHub, GitLab and Codeberg releases
77+
tools/runtime.func language runtimes and application installers
78+
tools/db.func databases and search engines
79+
tools/hwaccel.func GPU detection and hardware acceleration
7580
install.func in-container bootstrap (multi-distro)
7681
alpine-install.func in-container bootstrap for Alpine
7782
alpine-tools.func helper library for Alpine
@@ -233,6 +238,9 @@ Before opening a PR:
233238
on Proxmox VE belongs in `pve/`.
234239
- Never hardcode a raw URL. Use `_cs_source_func "shared/<name>.func"` (or
235240
`pve/…`, `incus/…`) so both roots keep resolving and forks keep working.
241+
- `shared/tools.func` is the published helper API. Source that, not the parts
242+
under `shared/tools/`. If you add or rename a function there, regenerate
243+
`shared/tools/API.txt` in the same PR — CI compares against it.
236244
- New files go in the folder that matches their root. Nothing resolves by
237245
basename, so `incus/tools.func` and `shared/tools.func` are both fine.
238246
- `shellcheck` and `shfmt` the files you touched.

0 commit comments

Comments
 (0)