From a5c265d8ee36ab7bdcfa43715e11c640cfb346c5 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 12 Mar 2026 03:22:51 -0600 Subject: [PATCH] fix(installer-skill): revise docs per second adversarial review - Move set -e/set -u inside __init_ (matches _example canonical form) - Fix PS1 framework claim: template exists, provides helpers, but package script must download and extract itself - Fix WEBI_SINGLE description: linking strategy, not default-deps rule - Fix Pattern G pkg_link to use $pkg_src instead of $pkg_src_dir - Fix Pattern H skeleton to match real pwsh (no bin/ subdir, uses pkg_link) - Fix Pattern A WEBI_SINGLE description in PATTERNS.md - Remove goreleaser from Pattern C representative list (it's Pattern A layout) - Drop goreleaser man page from Pattern C man page location list - Remove Python snippet from ARCHIVE-LAYOUTS.md zst inspection (use zstd -dc) --- _skills/installer/SKILL.md | 42 ++++++++++++------- .../installer/references/ARCHIVE-LAYOUTS.md | 7 +--- _skills/installer/references/PATTERNS.md | 37 ++++++++++------ 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/_skills/installer/SKILL.md b/_skills/installer/SKILL.md index 1ca3216..a07a7ec 100644 --- a/_skills/installer/SKILL.md +++ b/_skills/installer/SKILL.md @@ -130,10 +130,10 @@ sourced by the framework: ```sh #!/bin/sh -set -e -set -u __init_toolname() { + set -e + set -u #################### # Install toolname # @@ -173,22 +173,28 @@ __init_toolname | `pkg_src_dir` | Versioned install dir: `~/.local/opt/-v` | | `pkg_src` | Same as `pkg_src_cmd` for single-binary packages; same as `pkg_src_dir` for SDKs | -**Framework-derived (do not set these yourself):** +**Framework-derived (set by the framework before calling `pkg_install` — do not set manually):** - `pkg_src_bin` — `$(dirname "$pkg_src_cmd")` — the versioned `bin/` dir - `pkg_dst_bin` — `$(dirname "$pkg_dst_cmd")` — `~/.local/bin` ### `WEBI_SINGLE` -`WEBI_SINGLE=true` tells the framework to link the binary directly: -`~/.local/bin/cmd → ~/.local/opt/cmd-vX.Y.Z/bin/cmd` +`WEBI_SINGLE=true` affects the default values the framework uses for +`pkg_src` and `pkg_dst`, and how `webi_link()` creates the symlink: -Without it (the default), the framework links the whole directory: -`~/.local/opt/cmd → ~/.local/opt/cmd-vX.Y.Z` +- **With `WEBI_SINGLE=true`**: links the binary file directly: + `~/.local/bin/cmd → ~/.local/opt/cmd-vX.Y.Z/bin/cmd` +- **Without it (default)**: links the directory: + `~/.local/opt/cmd → ~/.local/opt/cmd-vX.Y.Z` -**Set `WEBI_SINGLE=true` for any package that installs a single binary** -— regardless of whether the archive has a subdirectory. Pattern G (SDKs) -is the main case where you do NOT set it, because the whole directory tree -needs to be accessible (e.g. `node/lib/`, `go/src/`). +Set `WEBI_SINGLE=true` when using the conventional Pattern A skeleton +(where `pkg_src` and `pkg_dst` are not set to custom values). When you +explicitly assign all six variables yourself (as in Patterns B–F), +`WEBI_SINGLE` is not strictly required but can still be set for clarity. + +Pattern G (SDKs) and Pattern H (.NET bundles) do NOT use `WEBI_SINGLE` — +they define `pkg_link()` manually because the whole directory tree must +be linked, not just a single binary. ### Required function: `pkg_install` @@ -313,7 +319,7 @@ pkg_install() { pkg_link() { rm -f "$pkg_dst" - ln -s "$pkg_src_dir" "$pkg_dst" + ln -s "$pkg_src" "$pkg_dst" } ``` @@ -321,10 +327,14 @@ pkg_link() { ## 4. Write `install.ps1` -Unlike the shell side, there is no PowerShell framework template — each -`install.ps1` is a self-contained script that handles download, extraction, -and placement itself. The same path conventions apply (opt/bin layout), but -Windows uses `Copy-Item` instead of symlinks for the final `bin/` step. +A PowerShell framework template exists (`_webi/package-install.tpl.ps1`) +and injects the `install.ps1` script at the `# {{ installer }}` placeholder. +The template provides: error handling, directory setup, `Invoke-DownloadUrl` +helper, and PATH management via `webi_path_add`. However, unlike the shell +side, the PS1 framework does **not** download or extract the archive — the +package script must handle that itself. The same path conventions apply +(opt/bin layout), but Windows uses `Copy-Item` instead of symlinks for +the final `bin/` step. ### Variable block (always at top) diff --git a/_skills/installer/references/ARCHIVE-LAYOUTS.md b/_skills/installer/references/ARCHIVE-LAYOUTS.md index 4fa8a2d..f76e642 100644 --- a/_skills/installer/references/ARCHIVE-LAYOUTS.md +++ b/_skills/installer/references/ARCHIVE-LAYOUTS.md @@ -276,11 +276,8 @@ curl -fsSL "$URL" | tar -tz | head -20 curl -fsSL "$URL" -o /tmp/pkg.zip unzip -l /tmp/pkg.zip | head -20 -# For a .zst file you don't have zstd for: -curl -fsSL "$URL" | python3 -c " -import sys, subprocess -subprocess.run(['tar', '--zstd', '-tz'], stdin=sys.stdin) -" | head -20 +# For a .zst file when tar doesn't support zstd natively: +curl -fsSL "$URL" -o /tmp/pkg.tar.zst && zstd -dc /tmp/pkg.tar.zst | tar -tz | head -20 ``` **What to look for**: diff --git a/_skills/installer/references/PATTERNS.md b/_skills/installer/references/PATTERNS.md index a4a9abb..567d639 100644 --- a/_skills/installer/references/PATTERNS.md +++ b/_skills/installer/references/PATTERNS.md @@ -10,7 +10,9 @@ the most common. Check `tar -tz $ARCHIVE` before writing any code. The archive extracts directly to the current directory with no wrapper subdirectory. Binary (and optional LICENSE/README) is at the top level. -**Set `WEBI_SINGLE=true`** — tells the framework the archive is flat. +**Set `WEBI_SINGLE=true`** — tells the framework to link the binary file +directly (`~/.local/bin/cmd → ~/.local/opt/cmd-vX/bin/cmd`) rather than +linking the versioned directory. Representative packages: caddy, fzf, k9s, terraform, sttr, lf, monorel, awless, bun, cilium, curlie, dashmsg, dotenv, dotenv-linter, ffuf, @@ -93,11 +95,13 @@ Move-Item -Path ".\delta-*\delta.exe" -Destination "$pkg_src_bin" Same as B but the archive also contains shell completions and/or man pages worth installing. -Representative packages: bat, fd, goreleaser, lsd, rg/ripgrep, sd, -watchexec, zoxide +Representative packages: bat, fd, lsd, rg/ripgrep, sd, watchexec, zoxide + +Note: goreleaser has a flat archive (Pattern A layout) but with completions at +the archive root. See the goreleaser entry in ARCHIVE-LAYOUTS.md. **Completion directory name varies by package**: -- `completions/` — sd, goreleaser, watchexec, zoxide +- `completions/` — sd, watchexec, zoxide - `autocomplete/` — bat, fd, lsd - `complete/` — rg/ripgrep @@ -110,7 +114,6 @@ watchexec, zoxide **Man page location varies**: - `tool.1` at subdirectory root — sd, bat, fd, lsd - `doc/tool.1` — rg/ripgrep -- `manpages/tool.1.gz` — goreleaser - `man/man1/tool.1` — zoxide (deepest path) **install.sh** (rg as example): @@ -298,7 +301,9 @@ pkg_get_current_version() { ## Pattern H — .NET runtime bundle Flat directory with one binary and hundreds of `.dll` files. The entire -directory must be preserved intact. +directory must be preserved. Like Pattern G (SDK) in structure — the +versioned directory is the package root, with the binary directly inside +(no `bin/` subdirectory). A `pkg_link()` creates the unversioned symlink. Representative packages: pwsh (PowerShell Core) @@ -306,19 +311,25 @@ Representative packages: pwsh (PowerShell Core) ```sh pkg_cmd_name="pwsh" -pkg_dst_cmd="$HOME/.local/bin/pwsh" -pkg_dst="$pkg_dst_cmd" -pkg_src_cmd="$HOME/.local/opt/pwsh-v$WEBI_VERSION/bin/pwsh" +# note: binary is at pkg_src_dir root, no bin/ subdirectory +pkg_src_cmd="$HOME/.local/opt/pwsh-v$WEBI_VERSION/pwsh" pkg_src_dir="$HOME/.local/opt/pwsh-v$WEBI_VERSION" -pkg_src="$pkg_src_cmd" +pkg_src="$pkg_src_dir" + +pkg_dst_cmd="$HOME/.local/opt/pwsh/pwsh" +pkg_dst="$HOME/.local/opt/pwsh" pkg_install() { + # Archive extracts flat — move all contents into the versioned dir mkdir -p "$pkg_src_dir" - # Archive extracts flat — move all contents into bin/ - mkdir -p "$pkg_src_bin" - mv ./* "$pkg_src_bin/" 2>/dev/null || true + mv ./* "$pkg_src_dir" chmod a+x "$pkg_src_cmd" } + +pkg_link() { + rm -rf "$pkg_dst" + ln -s "$pkg_src" "$pkg_dst" +} ``` ---