Skip to content

fix(minify): failed render must not truncate the existing output - #180

Merged
fentas merged 2 commits into
mainfrom
fix/minify-truncate
Aug 28, 2026
Merged

fix(minify): failed render must not truncate the existing output#180
fentas merged 2 commits into
mainfrom
fix/minify-truncate

Conversation

@fentas

@fentas fentas commented Aug 28, 2026

Copy link
Copy Markdown
Member

Fixes #178

Problem

argsh minify -t <template> -o <out> rendered the template with a direct redirect:

envsubst '$data,$commit_sha,$version' <"${template}" >"${out}"

The shell opens and truncates ${out} before envsubst runs, so a failed render destroys a previously-good artifact and leaves a 0-byte file behind. This shipped an empty lo-up installer once (lok8s install/build writes docs/public/lo-up, served to curl | sh).

Fix

  • Render into a mktemp file first, verify the render exit code AND that the render is non-empty (-s), only then mv over ${out}. For non-regular targets (the /dev/stdout default), cat instead of mv.
  • On failure the temp file is cleaned up by the existing subshell EXIT trap, ${out} is left untouched, and the error names what failed and states that the output was preserved.
  • Detect non-GNU envsubst drop-ins up front (envsubst --version | grep -q "GNU gettext"). renvsubst — which lok8s installs as envsubst — rejects the GNU SHELL-FORMAT positional with ERROR: Unknown flag, which gave no hint that the wrong binary was on PATH. The check fails early naming the culprit and the next action (install gettext or fix PATH). This was the issue's optional second suggestion; implemented since it is small and prescribed.

Tests

Four new bats tests in libraries/main.bats, using fake minifier/envsubst executables on PATH (not function stubs, so they also hold against the minified argsh):

  • happy path: template render writes the output
  • failed render: command fails, pre-existing output keeps its original content
  • empty render: command fails, pre-existing output keeps its original content
  • non-GNU envsubst: rejected with a clear message, output untouched

Mutation-checked: with the direct-redirect shape temporarily restored, the failed-render and empty-render tests fail on the truncated (empty) output file; with the fix they pass.

Full libraries/ suite: 366 pass locally; the 6 pre-existing failures (attrs bare--/-- tests, two argsh::lint discovery tests) fail identically on a clean origin/main checkout in the same environment and are unrelated to this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_016DJzGS3pNBzZs1jaEQ74Co

fentas and others added 2 commits August 28, 2026 08:09
argsh minify -t -o rendered the template with a direct redirect into the
output file, so the shell truncated a previously-good artifact before
envsubst even ran. A failed render left a 0-byte file behind — this once
shipped an empty lo-up installer.

Render into a mktemp file, verify the exit code and that the render is
non-empty, then mv over the output (cat for non-regular targets like the
/dev/stdout default). On failure the temp file is removed and the output
is left untouched, with an error naming what failed.

Also detect non-GNU envsubst drop-ins (e.g. renvsubst) up front via
--version, since they reject the GNU SHELL-FORMAT argument with an
unhelpful "Unknown flag".

Fixes #178

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DJzGS3pNBzZs1jaEQ74Co
Review round: mv handed ${out} mktemp's 0600 mode where the old redirect
kept existing perms/umask. chmod --reference the existing file (644 for a
new one) before the mv; perms assertion added to the happy-path test and
mutation-checked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DJzGS3pNBzZs1jaEQ74Co
@fentas
fentas merged commit 2b83318 into main Aug 28, 2026
12 of 13 checks passed
@fentas
fentas deleted the fix/minify-truncate branch August 28, 2026 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

minify truncates its output file when the template render fails

1 participant