Conversation
Install remotely via `go install`, stream toolchain output live, and fix the
defects found by auditing the v1.9.9 baseline twice.
Module rename to github.com/divijg19/Helm, so the published binary is
installable with `go install`. The major version stays unversioned because
cmd/helm is package main and the module ships no library import path.
Install transparency: the terminal streams the toolchain's own output as each
tool installs, and that live output is the record. A successful install no
longer repeats it in a trailing block, so the terminal's notes branch is gone
entirely. The report-level notes field names the tools that were successfully
updated and produced output; it never carried the text, and the docs now say so.
Correctness fixes, each with a test that fails before the fix:
* Inventory reported invalid binaries in both Invalid and Unhealthy, so every
renderer summed them twice and the user saw "2 issues found" for one
problem, breaking the documented conservation invariant. Unhealthy now
counts only unhealthy tools; three goldens regenerated.
* --help and --version constructed the App, which shells out to `go env`, so a
broken toolchain made them exit 3 and print nothing, failing in exactly the
state they exist to diagnose. They now answer before any toolchain access.
* An empty GOBIN serialized as "tools": null, violating the never-null array
contract. Fixed at the builder and enforced at the JSON wire boundary.
* tool.Update was displaced by ResolveUpdateCandidates in v1.8.0 and was
reachable only from its own tests, so ~70 lines were dead while the
streaming and notes contract it covered had no live-path coverage. Deleted,
and its tests now drive UpdateCandidates with a real progress sink, which
also pins the exact-version install reference.
* install.sh armed its cleanup trap before assigning TMPDIR. TMPDIR is a
standard variable that macOS exports in every interactive shell, so exiting
early on an unsupported platform or architecture ran `rm -rf` against the
caller's own temporary directory. The trap is now armed only after
mktemp, against a private WORKDIR.
* A failed install reported only its name in --json, --ci and --quiet, while
the terminal kept the reason and resolution failures already produced a
diagnostic. The two failure classes were treated asymmetrically, so a script
could not tell a network failure from a build failure. UpdateReport now
carries failed_detail, printed as `failed-reason:` in CI, a combined line on
quiet's stderr, and an array in JSON. The terminal deliberately does not
repeat it. Both new keys are omitempty, so a clean run is byte-identical.
* Failure messages did not agree in number with their count, so a single
problem was reported as "1 issues found". All three operation messages now
use a pluralizing helper; the singular form is the only text that changes,
so no golden moved.
Consolidation: one Err() per report type replaces ten copies of three failure
messages, and the terminal's empty-inventory path no longer bypasses it. The
update summary rows, the skipped-tool list, and the selection-plus-eligibility
split shared by Plan and ResolveUpdateCandidates each have one builder, so a
plan and the update that follows it cannot disagree. The declared ProgressSink
is now the type the App probes for. Removed the tool.Status enum and both of
its carriers, the redundant installTool ref parameter, a name that shadowed its
own helper, and a verification map that Verify's 1:1 positional contract makes
unnecessary (now asserted, not assumed).
Removed the Invocation type and cli.Run's unused inv parameter: the CLI never
read it, so it was production-dead, and main.go paid for filepath.Base for
nothing. The three alias tests remain as guards against reintroducing per-name
dispatch.
Test suite: fixed a TestMain that leaked three binaries per run (its defer was
unreachable before os.Exit), a duration mask that could not match the minute
form formatDuration emits past 60s, and an os.Stdout swap that was not restored
on panic. Collapsed four fixture builders into one shared helper, replaced
assertion-only tests with ones that pin the branch they name, and added
coverage for the concurrency clamp (whose removal hangs the suite rather than
failing it), filtered-update scope end to end, terminal failure rendering, the
CI outdated and info reports, NewRenderer's mode mapping, the empty module-path
fallback, semver v-prefix normalization, and App.load memoization. The
deterministic-ordering guard no longer depends on a 50ms scheduling margin; a
channel barrier makes the completion order structural. BenchmarkVerify measures
the healthy path against real executables rather than missing files.
Docs: corrected the notes contract, the --info and --help contracts, the
staticcheck configuration, the CI job list, the golden-regeneration procedure,
and the JSON omissions. Documented the failure-reason fields, --verbose, and
the validation that precedes the discovery header.
Verified: gofmt, go vet, staticcheck (CI check set), golangci-lint,
go test -count=1 ./..., go test -race -count=1 ./..., GOOS=windows and
GOOS=darwin builds, go mod tidy -diff, git diff --check, sh -n install.sh,
goreleaser check, and an end-to-end rehearsal of install.sh against a local
release (both the pinned-VERSION and resolve-latest paths, including that a
tampered artifact is rejected by the checksum check before anything installs).
divijg19
commented
Sep 28, 2026
divijg19
left a comment
Owner
Author
There was a problem hiding this comment.
v2.0.0: remote install, live-only progress, and two correctness sweeps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Installable with
go install, transparent install output, and two rounds of correctness fixes against the v1.9.9 baseline.What changed
Module path. Renamed to
github.com/divijg19/Helmso the published binary is installable withgo install github.com/divijg19/Helm/cmd/helm@latest. The major version stays unversioned becausecmd/helmispackage mainand the module ships no library import path.Transparent install output. The terminal streams the toolchain's own output (
go: downloading,go: extracting, and anything else it prints) live under each installing tool, and that live output is the record. A successful install no longer repeats it in a trailing block, so the terminal's notes branch is gone entirely. The report-levelnotesfield carries the names of tools that were successfully updated and produced output — it never carried the text, and the docs now say so.Fixes
install.shcouldrm -rfthe caller's$TMPDIRon an unsupported platform or architecturehelm --listcounted one uninspectable binary twice, reporting "2 issues found"Also fixed, with a regression test that fails before the fix:
--helpand--versionconstructed theApp, which shells out togo env, so a broken toolchain made them exit3and print nothing — failing in exactly the state they exist to diagnose. They now answer before any toolchain access."tools": null, violating the never-null array contract. Fixed at the builder and enforced at the JSON wire boundary.--json/--ci/--quiet, while resolution failures already produced a diagnostic, so a script could not tell a network failure from a build failure.UpdateReportnow carriesfailed_detail; both new keys areomitempty, so a clean run is byte-identical.Consolidation
One
Err()per report type replaces ten copies of three failure messages, so the exit code, stderr text, and JSONsuccessflag cannot disagree. The update summary rows, the skipped-tool list, and the selection-plus-eligibility split shared byPlanandResolveUpdateCandidateseach have a single builder, so a plan and the update that follows it cannot disagree. Removed: thetool.Statusenum and both carriers, a redundantinstallToolparameter, a variable that shadowed its own helper, a verification map made unnecessary byVerify's positional contract, and theInvocationtype whose parametercli.Runnever read.Verification
gofmt·go vet·staticcheck(CI check set) ·golangci-lint(0 issues) ·go test -count=1 ./...·go test -race -count=1 ./...·GOOS=windowsandGOOS=darwinbuilds ·go mod tidy -diff·sh -n install.sh·goreleaser check· golden regeneration audit (all 20 goldens byte-exact).install.shwas additionally rehearsed end to end against a local release, running the unmodified script through both the pinned-VERSIONand resolve-latest paths, confirming the binary and both aliases install and report the right version, and confirming a tampered artifact is rejected by the checksum check before anything is written.Closes #97, closes #98, closes #99.