Gabriella439 / Gabriella439/turtle

How to keep ExitCodes from folds?

Open
#461 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
978
Forks
94
PR merge metrics
No merged PRs in 30d

Description

I wish to "fold" over the lines of a shell command's output, and then make a decision about how to continue based on both the result of the fold AND the exit status.

For example I may be looking for some particular text in the output AND a particular non-zero exit status at the same time. And whilst I'm searching for the text I may want to echo all output (or perhaps some or none) back to the user.

But the issue is the function, `inprocWithErr`, which is close to what I want, doesn't return the `ExitCode`, but instead throws it if it is non-zero.

Problem is if it throws, I can catch it but then the result of the fold is gone.

I've hacked up the following, using `IORef` to hold the fold accumulator so it's not lost on catching an exception, but I feel like it's hacky and I don't like it:

```
foldInprocWithErr :: MonadIO io => (Either Line Line -> a -> IO a) -> a -> Text -> [Text] -> Shell Line -> io (ExitCode, a)
foldInprocWithErr step initial cmd args stdinLines = liftIO $ do
accRef <- newIORef initial

let shellAction = do
eLine <- T.inprocWithErr cmd args stdinLines
acc0 <- liftIO (readIORef accRef)
acc1 <- liftIO (step eLine acc0)
liftIO (writeIORef accRef acc1)

result <- try (T.sh shellAction) :: IO (Either ExitCode ())
acc <- readIORef accRef
let exitCode = either id (const ExitSuccess) result
pure (exitCode, acc)
```

Is there a better way to approach what I've done above? I considered functions like [Turtle.Shell.foldIO](https://hackage.haskell.org/package/turtle-1.6.2/docs/Turtle-Shell.html#v:foldIO) but I can't see how that helps because on anything non-zero exit status I'm still going to have to catch an exception, and then I've lost the result, unless I've stashed it away whilst processing in an IORef.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.