chshersh / iris

🌈 Haskell CLI Framework supporting Command Line Interface Guidelines
https://hackage.haskell.org/package/iris
Mozilla Public License 2.0
173 stars 21 forks source link

Implement 'out', 'outLn', 'err' and 'errLn' functions for outputting 'Text' to corresponding handlers #107

Open chshersh opened 1 year ago

chshersh commented 1 year ago

I believe, the title is pretty clear. What's needed specifically:

martinhelmer commented 1 year ago

i'll take care of this. should i migrate existing internal IO usage as well? (such as the IO in Question.hs and Formatting.hs)

chshersh commented 1 year ago

Feel free to take care of this issue!

I think using these functions in others would be a good idea indeed. As long as there're no cyclic dependencies.

martinhelmer commented 1 year ago

so after this we have slight inconsistencies in naming raw output

Iris.out
Iris.outLn
Iris.err
Iris.errLn

colored output

Iris.putStdoutColoured
Iris.putStdoutColouredLn
Iris.putStderrColoured
Iris.putStderrColouredLn

OK with that?

Ideally i'd prefer renaming the colored ones to

Iris.outColoured
Iris.outColouredLn
Iris.errColoured
Iris.errColouredLn

but that's not backwards compatible

martinhelmer commented 1 year ago

Would you like some tests using System.IO.Silently (capture) to capture and check stderr + stdout

or

skip the tests for this since the definitions are trivial.

martinhelmer commented 1 year ago

overkill example:

import System.IO.Silently (capture_, hCapture_, silence, hCapture, hSilence)
import System.IO (stderr, stdout)

import Iris.IO 
import qualified Iris as IO

checkStdErr f = hCapture_ [stderr] (hSilence [stdout] f)
checkStdOut f = hCapture_ [stdout] (hSilence [stderr] f)

ioSpec :: Spec
ioSpec =
    describe "IO" $ do
        describe "out" $ do 
            it "writes to stdout, no LF " $ checkStdOut (IO.out "TEXT") >>= shouldBe "TEXT"
            it "does not write to stderr " $ checkStdErr (IO.out "TEXT") >>= shouldBe ""
        describe "outLn" $ do 
            it "writes to stdout,  LF " $ checkStdOut (IO.outLn "TEXT") >>= shouldBe "TEXT\n"
            it "does not write to stderr " $ checkStdErr (IO.outLn "TEXT") >>= shouldBe ""
        describe "err" $ do 
            it "writes to sterr, no LF " $ checkStdErr (IO.err "TEXT") >>= shouldBe "TEXT"
            it "does not write to stdout " $ checkStdOut (IO.err "TEXT") >>= shouldBe ""
        describe "errLn" $ do 
            it "writes to stderr,  LF " $ checkStdErr (IO.errLn "TEXT") >>= shouldBe "TEXT\n"
            it "does not write to stdout " $ checkStdOut (IO.errLn "TEXT") >>= shouldBe ""
  IO
    out
      writes to stdout, no LF  [✔]
      does not write to stderr  [✔]
    outLn
      writes to stdout,  LF  [✔]
      does not write to stderr  [✔]
    err
      writes to sterr, no LF  [✔]
      does not write to stdout  [✔]
    errLn
      writes to stderr,  LF  [✔]
      does not write to stdout  [✔]
chshersh commented 1 year ago

@martinhelmer I like these tests with silently, so let's add them to the implementation as well! 👍🏻

so after this we have slight inconsistencies in naming

My plan is to remove put*Coloured functions completely, so I wouldn't bother with changing their names for now 🙂

Initially, I implemented a design with a separate formatting function, so it could be used in a combination with something like pretty-terminal:

Iris.putStderrColouredLn
    (Pretty.style Pretty.Bold . Pretty.color Pretty.Green)
    "my message"

But I'd rather do #110 properly, so functions like putStderrColouredLn could be removed completely, and the above example will look like:

Iris.errLn $ Iris.bold $ Iris.green "my message"
martinhelmer commented 1 year ago

ok. roger that. what about the tests? like / no like ? you answered that already. doh'