loopsmith v0.1.3
The release where Windows stopped being a badge and started being a platform.
Fixed
-
which()found nothing at all on Windows. It joined the bare command name
onto eachPATHentry, and executables there aregit.exe— so nothing ever
matched and it returnedNonefor every command on the machine. Every caller
then faithfully reported the falsehood it was handed:doctorlisted every tool
as absent,Platform::detectfound no scheduler, and worktree isolation
degraded to the shared directory with "git not on PATH" on a runner where
actions/checkouthad just usedC:\Program Files\Git\bin\git.exe. The
schtaskssupport added in 0.1.0 was dead on arrival for the same reason,
becausewhich("schtasks")could never succeed. Roughly a third of the Windows
claim was decoration.Each
PATHEXTsuffix is now tried as well as the bare name, honouring the
variable rather than hardcoding a list — it is how a machine says.ps1counts
as a command. The suffix is appended, not set as the extension, socheck.sh
can becomecheck.sh.exewhereset_extensionwould have producedcheck.exe.Command::new("git")was never affected: Windows'CreateProcessappends the
extension itself. Only loopsmith's own lookups were broken. -
The generated
.cmdlaunchers reported success when they had failed.
setlocalsaves the current errorlevel and the implicitendlocalat the end
of a batch file restores it, so a bareexit /b 127inside asetlocalscope
exits 0. A loop whose pinned binary had moved printed "loopsmith is not at
… and not on PATH" and then exited successfully — the precise silent failure
the exit code exists to prevent, and one a scheduled job would never surface.
resume.cmd's "no run id given" exit 2 had the same defect, as did the export
launcher.endlocal & exit /b <code>fixes it on a top-level line but not inside a
nestedif ( … )block, which is where the broken one lived — so each launcher
now has exactly oneexit /b, on its last line, reached by every path via
goto. They also enable delayed expansion and capture with!ERRORLEVEL!,
because a parenthesised block is parsed before it runs and%ERRORLEVEL%inside
one reads the value from before the command. A test asserts the single exit,
the label, and the absence of parse-time capture. -
loopsmith newclosed by telling every user to runrun.sh, including on
Windows wherecmd.execannot execute it andrun.cmdwas sitting beside it.
It now names the launcher the host can run, and printssetrather than
exportfor the API-key line there.
Changed
- Every published package now carries a README that stands on its own. The
crates.io, npm, and PyPI pages previously said little and pointed at the
repository; someone arriving from a registry had to leave to learn what the tool
was. Each now explains the design, shows a real config, lists the subcommands,
and covers install, providers, scheduling, and platform behaviour in the idiom
of that registry. The eight library crates had no README at all and rendered
as blank pages; each now explains its own role and where it sits. - CI no longer downloads a third-party toolchain or cache action.
rustupis
preinstalled on GitHub-hosted runners, and eight consecutive runs lost a leg to
codeload 429/502/503 while fetching an action — before a line of loopsmith
compiled.continue-on-errorcould not save it either: actions are downloaded
during "Set up job", before the step that was allowed to fail ever runs. A cold
build takes about two minutes, so the cache was saving less than the flakiness
cost. - Two tests that invoked
./run.shand./resume.shdirectly now pick the
launcher the host can execute. Gating them with#[cfg(unix)]would have made
the suite green while leaving the.cmdlaunchers unexercised on the only
platform that runs them.