Gabriella439 / Gabriella439/turtle
How to keep ExitCodes from folds?
- 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.