Skip to content

fix(devlore-test): route output streams portably instead of via /dev paths - #380

Merged
David-Noble-at-work merged 1 commit into
developfrom
fix/windows-output-streams
Aug 12, 2026
Merged

David-Noble-at-work merged 1 commit into
developfrom
fix/windows-output-streams

Conversation

@David-Noble-at-work

Copy link
Copy Markdown
Contributor

Issue #379, phase 3 of #373.

The defect

devlore-test run could not execute on Windows at all. Every output stream defaulted to /dev/stdout, openDest was a plain os.OpenFile, and the open failed before the command produced anything:

error: opening graph output: open /dev/null: The system cannot find the path specified.

Two sentinels, two treatments

Per the ruling, because they are genuinely different problems:

Standard output is intercepted. stdoutSentinel is matched in openDest and never reaches the filesystem. This also fixes a latent bug the Unix path was hiding: callers defer a Close on whatever openDest returns, so routing to stdout was closing the process's own standard output. openDest now returns an io.WriteCloser, and the stdout case is a nopWriteCloser.

Discard needs no interception. os.DevNull already names each platform's device — /dev/null on Unix, NUL on Windows — and opens correctly on both. The fix there is spelling, not mechanism.

Scope

Four further sites carried the identical mistake and are corrected together rather than split out: commands_test.go routed to /dev/null directly, and scenario_integration_test.go and repo_cmd_test.go set GIT_CONFIG_GLOBAL/GIT_CONFIG_SYSTEM to /dev/null to suppress ambient git config. No /dev/null literal remains in non-prototype Go code — asserted by the commit script.

The root help also advertised /tmp/receipt.yaml; now a bare relative filename, meaningful everywhere.

This should clear roughly 16 of the 47 remaining Windows failures.

Deliberately not in this PR

data/test_compensation.star forces a failure via destination_path="/dev/null/impossible/path.txt". On Windows that path is apparently creatable, so the copy succeeds where the fixture expects an error. That's the impossible-path idiom, not the discard sentinel — a different problem deserving its own change.

Plan update

The corrected phase 2 triage rides along: the .exe fix cleared 16, not the ~37 I estimated, because 14 TestCLI_* cases were failing for this second reason hidden behind the first.

Verified on Darwin: make vet, make build, full make test green (zero FAIL/panic by count), gofmt clean, and run --help renders /dev/null here — which is what os.DevNull is on this platform. CI's windows leg is the real verification.

…paths

Issue #379. devlore-test run could not execute on Windows at all: every output
stream defaulted to /dev/stdout, openDest was a plain os.OpenFile, and the open
failed before the command produced anything. It aborted with "opening graph
output: open /dev/null: The system cannot find the path specified."

Per the ruling, the two sentinels are handled differently because they are
different problems.

Standard output is intercepted. stdoutSentinel is matched in openDest and never
reaches the filesystem, which also fixes a latent bug the Unix path was hiding:
the callers defer a Close on what openDest returns, so routing to stdout was
closing the process's own standard output. openDest now returns an
io.WriteCloser and the stdout case is a nopWriteCloser.

Discard needs no interception. os.DevNull already names each platform's device
— /dev/null on Unix, NUL on Windows — and opens correctly on both. So the fix
there is spelling, not mechanism: help text and examples interpolate
os.DevNull rather than hardcoding /dev/null, and the same applies to the tests
that route streams away.

Four further sites carried the same defect and are corrected together, being
the identical mistake rather than separate scope: commands_test.go routed to
/dev/null directly, and scenario_integration_test.go and repo_cmd_test.go both
set GIT_CONFIG_GLOBAL and GIT_CONFIG_SYSTEM to /dev/null to suppress ambient
git configuration. No /dev/null literal remains in non-prototype Go code.

The root command's help also advertised /tmp/receipt.yaml as its example
destination; that is now a bare relative filename, which is meaningful
everywhere.

This is roughly 16 of the 47 remaining Windows failures — the 12 exit-code-1
cases, the 5 missing JSON summaries, the 2 missing "Hello World!" assertions,
and the 2 explicit /dev/null failures.

Not addressed here, and left for its own change: data/test_compensation.star
forces a failure with destination_path="/dev/null/impossible/path.txt". On
Windows that path is apparently creatable, so the copy succeeds where the
fixture expects an error. That is a different problem — the impossible-path
idiom — not the discard sentinel.

The plan's corrected phase 2 triage rides in this commit: the .exe fix cleared
16 failures rather than the ~37 estimated, because 14 TestCLI cases were
failing for this second reason behind the first.

Verified on Darwin: make vet, make build, full make test green — zero FAIL or
panic lines by count; gofmt clean; run --help renders /dev/null here, which is
what os.DevNull is on this platform. CI's windows leg is the real verification.
Plan: docs/plans/platform-test-matrix.md (phase 3).
Issue: #379
@David-Noble-at-work David-Noble-at-work self-assigned this Aug 12, 2026
@David-Noble-at-work
David-Noble-at-work merged commit 26a1104 into develop Aug 12, 2026
7 of 8 checks passed
@David-Noble-at-work
David-Noble-at-work deleted the fix/windows-output-streams branch August 12, 2026 05:14
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.

1 participant