turtle icon indicating copy to clipboard operation
turtle copied to clipboard

Feature suggestion: inline-shell

Open georgewsinger opened this issue 6 years ago • 6 comments

Suggestion: I think this library would be an order of magnitude more useful if it implemented something akin to inline-C. I.e:

main :: IO ()
main = do
  x <- [S.block| {
      # Print something to console from bash.
      echo "Hello from"
    } |]
 putStrLn $ x ++ " Haskell!"

This would allow someone to mix quick bash scripts with the aid of Turtle's typing system.

georgewsinger avatar Jan 25 '19 21:01 georgewsinger

@georgewsinger: To make sure I understand correctly: would this translate to one call to proc or procs per line in the block?

Gabriella439 avatar Jan 25 '19 22:01 Gabriella439

Oops, I mean shell or shells

Gabriella439 avatar Jan 25 '19 22:01 Gabriella439

I'm not sure what is best long-term, but at first glance it seems translating to one shell would be totally suitable for what I have in mind?

Though on second glance: how does bash itself treat a statement like echo "1"; echo "2"; echo "3"? Is that one "shell" or three "shells" from its perspective (here I'm taking "shell" to mean "process")? What about echo "1" && echo "2" && echo "3"? If bash treats these cases as three separate processes, then maybe the best way to translate would be to spawn multiple shells per inline-block as needed.

(I'm not very familiar with how shells and turtle work under the hood, so I hope I'm not spouting nonsense here).

georgewsinger avatar Jan 25 '19 22:01 georgewsinger

Maybe the simplest approach would be to save the inline shell block to a file and then interpret that file using the shell. The main reason I suggest this is that otherwise turtle would have to parse the file and do things like filter out comments/empty-lines

Gabriella439 avatar Jan 30 '19 23:01 Gabriella439

That sounds perfect. Every Haskell file file.hs could get its associated file.sh with all of the shell snippets pasted in order (I believe this is how inline-C does it).

georgewsinger avatar Jan 30 '19 23:01 georgewsinger

The main issue I can think of is that this would require creating multiple versions of this utility that parallel shell/shells/inshell/inshellWithStderr, etc.

One way to reduce the API proliferation might be to provide a utility for saving Text to a temporary file, such as:

tempFile :: MonadManaged managed => Text -> m FilePath

... because if you had such a utility then you can combine that with the neat-interpolation package plus the existing API to get most of what you need, like this:

{-# LANGUAGE QuasiQuotes #-}

import Turtle (fp)

import qualified NeatInterpolation
import qualified Turtle

main :: IO ()
main = Turtle.sh $ do
    script <- tempFile [NeatInterpolation.text|
      # Print something to console from bash.
      echo "Hello from"
    |]

    x <- Turtle.strict (Turtle.inshell "bash" [ Turtle.format fp script ] Turtle.empty)

    …

... as a bonus, if you use the neat-interpolation package then you also get support for string interpolation into the script

Gabriella439 avatar Jan 31 '19 05:01 Gabriella439