Skip to content

allow Process.runPure to express exit codes - #588

Open
4z3 wants to merge 2 commits into
NixOS:mainfrom
4z3:Process.runPure-can-ExitCode
Open

4z3 wants to merge 2 commits into
NixOS:mainfrom
4z3:Process.runPure-can-ExitCode

Conversation

@4z3

@4z3 4z3 commented Oct 26, 2026

Copy link
Copy Markdown

Replace the current set of Process constructors by non-throwing ones only and feed [(ExitCode, ByteString, ByteString)] to runPure. This enables it to mock all cases of runIO we care about.

read_ becomes a function in Sem using Error ExitCodeException.

This change doesn't affect existing code as nothing is currently using ourReadProcess_Sem, and NixpkgsReview.run uses ourReadProcessInterleavedSem which in turn uses ReadInterleaved as before.

runPure will concatenate stdout and stderr for ReadInterleaved, which test authors need to be aware of. (True interleaving doesn't seem worth mocking, or rather might be mockable by using e.g. just stdout and leaving stderr as "".)

Tests have been added showing how read_ under runPure gives Left ExitCodeException, and how readInterleaved concatenates stdout and stderr.

This PR implements steps 1. through 3. of #585 (comment).

4z3 added 2 commits October 26, 2026 14:20
Replace the current set of Process constructors by non-throwing ones
only and feed [(ExitCode, ByteString, ByteString)] to runPure.  This
enables it to mock all cases of runIO we care about.

read_ becomes a function in Sem using Error ExitCodeException.

This change doesn't affect existing code as nothing is currently using
ourReadProcess_Sem, and NixpkgsReview.run uses ourReadProcessInterleavedSem
which in turn uses ReadInterleaved as before.

runPure will concatenate stdout and stderr for ReadInterleaved, which
test authors need to be aware of.
@4z3 4z3 changed the title Process.run pure can exit code allow Process.runPure to express exit codes Oct 26, 2026

@rhendric rhendric left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start! A few changes, please:

Comment thread test/ProcessSpec.hs
Comment on lines +21 to +24
either
((`shouldBe` ExitFailure 1) . TP.eceExitCode)
(expectationFailure . ("expected Left, but got Right " ++) . show)
result

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
either
((`shouldBe` ExitFailure 1) . TP.eceExitCode)
(expectationFailure . ("expected Left, but got Right " ++) . show)
result
left TP.eceExitCode result `shouldBe` Left (ExitFailure 1)

Comment thread test/ProcessSpec.hs
Comment on lines +29 to +32
either
(expectationFailure . ("expected Right, but got Left " ++) . show)
(`shouldBe` (ExitSuccess, "foobar"))
result

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
either
(expectationFailure . ("expected Right, but got Left " ++) . show)
(`shouldBe` (ExitSuccess, "foobar"))
result
result `shouldBe` Right (ExitSuccess, "foobar")

Comment thread test/ProcessSpec.hs
result

describe "ReadInterleaved" do
it "concatenation stdout and stderr under runPure" do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
it "concatenation stdout and stderr under runPure" do
it "concatenates stdout and stderr under runPure" do

Comment thread src/Process.hs
return (r, "")
ReadInterleaved_ _config -> maybe "" id <$> input
Read _config ->
maybe (ExitSuccess, "", "") id <$> input

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
maybe (ExitSuccess, "", "") id <$> input
fromMaybe (ExitSuccess, "", "") <$> input

(This is the sort of tidying up that I encourage if you're going to be touching the line anyway.)

Comment thread src/Process.hs
ReadInterleaved _config -> do
r <- maybe "" id <$> input
return (ExitSuccess, r)
(exitCode, out, err) <- maybe (ExitSuccess, "", "") id <$> input

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(exitCode, out, err) <- maybe (ExitSuccess, "", "") id <$> input
(exitCode, out, err) <- fromMaybe (ExitSuccess, "", "") <$> input

Comment thread src/OurPrelude.hs

ourReadProcess_Sem ::
(Members '[P.Process] r) =>
(Members '[P.Process, Error ExitCodeException] r) =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want this to go through mapError tshow to become Error Text, to match the type of the ExceptT Text functions that this will replace. Error Text is a bit distasteful but matching the existing idiom is the first priority, so that we can establish tests and then refactor at will.

This branch has not been deployed

No deployments
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.

2 participants