| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
PbtCli.Cabal
Description
Constructing and running the cabal test invocations that back every
pbt-cli command.
Two details here are load-bearing.
First, custom test options are passed with repeated singular
--test-option= flags, never the plural --test-options=. Cabal splits the
plural form on whitespace, so a Tasty pattern containing a space — which is
the common case, since Tasty group names have spaces — would arrive at the
test binary as several mangled arguments. The singular form appends one
argument verbatim.
Second, nothing here goes through a shell. Arguments are handed to the process
as a list, so patterns, redeemer names and paths need no quoting and cannot be
re-interpreted. renderCommand exists only to *show* a copy-pasteable
equivalent for --dry-run and error messages.
Synopsis
- data Invocation = Invocation {
- invProgram :: FilePath
- invArgs :: [String]
- invWorkingDir :: Maybe FilePath
- testInvocation :: FilePath -> FilePath -> Maybe FilePath -> [String] -> TestOptions -> Invocation
- renderCommand :: Invocation -> String
- data TestOptions = TestOptions {}
- noTestOptions :: TestOptions
- testOptionArgs :: TestOptions -> [String]
- wantsStructuredOutput :: TestOptions -> Bool
- runInherit :: Invocation -> IO ExitCode
- runCapture :: Invocation -> IO (ExitCode, [ByteString])
- runStreaming :: Invocation -> (ByteString -> IO ()) -> IO ExitCode
- findCabal :: IO FilePath
- newtype CabalMissing = CabalMissing String
Invocations
data Invocation Source #
A resolved cabal command line, ready to run.
Constructors
| Invocation | |
Fields
| |
Instances
| Show Invocation Source # | |
Defined in PbtCli.Cabal Methods showsPrec :: Int -> Invocation -> ShowS # show :: Invocation -> String # showList :: [Invocation] -> ShowS # | |
| Eq Invocation Source # | |
Defined in PbtCli.Cabal | |
Arguments
| :: FilePath |
|
| -> FilePath | working directory (the repository root) |
| -> Maybe FilePath |
|
| -> [String] |
|
| -> TestOptions | |
| -> Invocation |
Build a cabal test invocation.
targets are suite names; passing several is what lets pbt-cli run launch a
whole project's suites in one cabal call. An empty target list means all,
cabal's own everything-target.
For the structured modes this forces --test-show-details=direct. Cabal's
default streams the suite's stdout through, but a target repository is free to
set test-show-details: failures or never in its cabal.project (or
cabal.project.local, or ~/.cabal/config), and then cabal captures that
stdout into a log under dist-newstyle and our pipe receives nothing at all --
so run --json would exit 0 having emitted no events. pbt-cli owns the pipe,
so it owns the setting; a later flag on the command line wins over the project
file, which makes this a safe unconditional override.
direct rather than streaming: both forward the suite's stdout, but
streaming adds cabal's own per-test decoration, and the NDJSON modes want the
suite's bytes and nothing else. Plain run is left alone -- it is a
pass-through of cabal's console output, so the project's own preference is the
right one there.
renderCommand :: Invocation -> String Source #
A copy-pasteable shell rendering of an invocation.
For display only — the real invocation never touches a shell. Arguments are single-quoted when they contain anything that a shell would treat specially.
Test options
data TestOptions Source #
The custom test options pbt-cli knows how to forward to a suite.
Constructors
| TestOptions | |
Fields
| |
Instances
| Show TestOptions Source # | |
Defined in PbtCli.Cabal Methods showsPrec :: Int -> TestOptions -> ShowS # show :: TestOptions -> String # showList :: [TestOptions] -> ShowS # | |
| Eq TestOptions Source # | |
Defined in PbtCli.Cabal | |
noTestOptions :: TestOptions Source #
No custom options: run the suite exactly as cabal test would.
testOptionArgs :: TestOptions -> [String] Source #
Render test options as --test-option= flags.
Flags that take a value contribute two arguments (--test-option=-p then
--test-option=<value>) because that is how Tasty's own parser reads them,
and it keeps values with spaces intact.
wantsStructuredOutput :: TestOptions -> Bool Source #
Does this invocation need the suite's stdout on our pipe?
True for every mode that parses NDJSON off it. Used to decide whether to
override the project's test-show-details.
Running
runInherit :: Invocation -> IO ExitCode Source #
Run an invocation with the child's stdio connected straight to ours.
Used by pbt-cli run so cabal's build progress and Tasty's console reporter
appear exactly as they would if the user had typed the cabal command.
runCapture :: Invocation -> IO (ExitCode, [ByteString]) Source #
Run an invocation, collecting its stdout lines and letting stderr through.
stderr stays connected to ours on purpose: cabal reports build failures there, and swallowing them would turn a compile error into a mystifying "no events" result.
runStreaming :: Invocation -> (ByteString -> IO ()) -> IO ExitCode Source #
Run an invocation, handing each stdout line to a callback as it arrives.
The child's stdout is line-buffered and consumed incrementally, which is what
makes pbt-cli stream actually live rather than a delayed dump at exit.
Environment
newtype CabalMissing Source #
Thrown when cabal is not on PATH; pbt-cli is a wrapper, not a build
system, so it cannot do anything useful without it.
Constructors
| CabalMissing String |
Instances
| Exception CabalMissing Source # | |
Defined in PbtCli.Cabal Methods toException :: CabalMissing -> SomeException # fromException :: SomeException -> Maybe CabalMissing # displayException :: CabalMissing -> String # | |
| Show CabalMissing Source # | |
Defined in PbtCli.Cabal Methods showsPrec :: Int -> CabalMissing -> ShowS # show :: CabalMissing -> String # showList :: [CabalMissing] -> ShowS # | |