Skip to content

Commit 468d34b

Browse files
authored
Merge pull request #6255 from commercialhaskell/re6250-hpc
Re #6250 Output summary reports to stdout, not stderr
2 parents 876380e + a0db2a6 commit 468d34b

File tree

6 files changed

+53
-40
lines changed

6 files changed

+53
-40
lines changed

ChangeLog.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ Major changes:
1010

1111
Behavior changes:
1212

13-
* `stack list`, `stack templates` and `stack uninstall` output to the standard
14-
output stream rather than to the standard error stream.
13+
* `stack hpc report`, `stack list`, `stack templates` and `stack uninstall`
14+
output their information to the standard output stream rather than to the
15+
standard error stream. Logging is still to the standard error stream.
1516

1617
Other enhancements:
1718

doc/hpc_command.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ unified report with just two, we can instead command:
6363
stack hpc report A B
6464
~~~
6565

66-
This will output a textual report for the combined coverage from `A` and `B`'s
67-
test suites, along with a path to the HTML for the report.
66+
This will output to the standard output stream a summary report for the combined
67+
coverage from `A` and `B`'s test suites. It will also log the path to the HTML
68+
for the corresponding full report.
6869

6970
This command also supports taking extra `.tix` files. If you've also built an
7071
executable, against exactly the same library versions of `A`, `B`, and `C`, then
@@ -101,13 +102,17 @@ This report will consider all test results as well as the newly generated
101102

102103
When your project has these properties, you will get the following:
103104

104-
1. Textual coverage reports in the build output.
105+
1. Summary coverage reports, sent to the standard output stream in the build
106+
output, and a log of the paths to the HTML for the corresponding full
107+
reports.
105108

106-
2. A unified textual and HTML report, considering the coverage on all local
107-
libraries, based on all of the tests that were run.
109+
2. A summary unified report, sent to the standard output stream, and a log of
110+
the path to the HTML for the corresponding full report. These reports
111+
consider the coverage on all local libraries, based on all of the tests that
112+
were run.
108113

109114
3. An index of all generated HTML reports, in `index.html` in the local
110-
HPC root directory.
115+
HPC root directory, and a log of the path to the HTML for that index.
111116

112117
## Implementation details
113118

@@ -147,10 +152,10 @@ However, advanced users may want to understand exactly how `--coverage` works:
147152
executable. See issue
148153
[#1359](https://github.com/commercialhaskell/stack/issues/1359).
149154

150-
5. Once we have a `.tix` file for a test, we also generate a textual and HTML
151-
report for it. The textual report is sent to the terminal. The index of the
152-
test-specific HTML report is available `pkg-name/test-name/index.html` in the
153-
local HPC root directory.
155+
5. Once we have a `.tix` file for a test, we also generate a summary report and
156+
a corresponding full report using HTML. The summary report is sent to the
157+
standard output stream. The index of the test-specific HTML report is
158+
available at `pkg-name/test-name/index.html` in the local HPC root directory.
154159

155160
6. After the build completes, if there are multiple output `*.tix` files, they
156161
get combined into a unified report. The index of this report will be

src/Stack/Coverage.hs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ module Stack.Coverage
1414
, generateHpcMarkupIndex
1515
) where
1616

17-
import qualified Data.ByteString.Char8 as S8
18-
import qualified Data.ByteString.Lazy as BL
17+
import qualified Data.ByteString.Lazy.Char8 as L8
1918
import qualified Data.List as L
2019
import qualified Data.Map.Strict as Map
2120
import qualified Data.Set as Set
@@ -32,6 +31,7 @@ import Path.IO
3231
, ignoringAbsence, listDir, removeDirRecur, removeFile
3332
, resolveDir', resolveFile'
3433
)
34+
import RIO.ByteString.Lazy ( putStrLn )
3535
import RIO.Process ( ProcessException, proc, readProcess_ )
3636
import Stack.Build.Target ( NeedTargets (..) )
3737
import Stack.Constants
@@ -212,9 +212,9 @@ generateHpcReport pkgDir package tests = do
212212
tixSrc <- tixFilePath (packageName package) (T.unpack testName)
213213
let report = fillSep
214214
[ flow "coverage report for"
215-
, fromString pkgName' <> "'s"
215+
, style Current (fromString pkgName') <> "'s"
216216
, "test-suite"
217-
, fromString $ "\"" <> T.unpack testName <> "\""
217+
, style PkgComponent (fromString $ T.unpack testName)
218218
]
219219
reportHtml =
220220
"coverage report for"
@@ -289,14 +289,15 @@ generateHpcReportInternal tixSrc reportDir report reportHtml extraMarkupArgs ext
289289
[ "Generating"
290290
, report <> "."
291291
]
292-
outputLines <- map (S8.filter (/= '\r')) . S8.lines . BL.toStrict . fst <$>
292+
-- Strip @\r@ characters because Windows.
293+
outputLines <- map (L8.filter (/= '\r')) . L8.lines . fst <$>
293294
proc "hpc"
294295
( "report"
295296
: toFilePath tixSrc
296297
: (args ++ extraReportArgs)
297298
)
298299
readProcess_
299-
if all ("(0/0)" `S8.isSuffixOf`) outputLines
300+
if all ("(0/0)" `L8.isSuffixOf`) outputLines
300301
then do
301302
let msgHtml =
302303
"Error: [S-6829]\n\
@@ -327,9 +328,16 @@ generateHpcReportInternal tixSrc reportDir report reportHtml extraMarkupArgs ext
327328
pure Nothing
328329
else do
329330
let reportPath = reportDir </> relFileHpcIndexHtml
330-
-- Print output, stripping @\r@ characters because Windows.
331-
forM_ outputLines (logInfo . displayBytesUtf8)
332-
-- Generate the markup.
331+
-- Print the summary report to the standard output stream.
332+
putUtf8Builder =<< displayWithColor
333+
( fillSep
334+
[ "Summary"
335+
, report <> ":"
336+
]
337+
<> line
338+
)
339+
forM_ outputLines putStrLn
340+
-- Generate the HTML markup.
333341
void $ proc "hpc"
334342
( "markup"
335343
: toFilePath tixSrc
@@ -392,8 +400,8 @@ generateHpcReportForTargets opts tixFiles targetNames = do
392400
dest <- resolveDir' destDir
393401
ensureDir dest
394402
pure dest
395-
let report = flow "combined report"
396-
reportHtml = "combined report"
403+
let report = flow "combined coverage report"
404+
reportHtml = "combined coverage report"
397405
mreportPath <- generateUnionReport report reportHtml reportDir tixPaths
398406
forM_ mreportPath $ \reportPath ->
399407
if hroptsOpenBrowser opts
@@ -429,8 +437,8 @@ generateHpcUnifiedReport = do
429437
, flow "so not generating a unified coverage report."
430438
]
431439
else do
432-
let report = flow "unified report"
433-
reportHtml = "unified report"
440+
let report = flow "unified coverage report"
441+
reportHtml = "unified coverage report"
434442
mreportPath <- generateUnionReport report reportHtml reportDir tixFiles
435443
forM_ mreportPath (displayReportPath "The" report . pretty)
436444

tests/integration/tests/3997-coverage-with-cabal-3/Main.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ main :: IO ()
66
main = do
77
stack ["setup"]
88
stackCheckStderr ["test", "--coverage"] $ \out -> do
9-
unless ("The coverage report for foo's test-suite \"foo-test\" is available at" `isInfixOf` out) $
9+
unless ("The coverage report for foo's test-suite foo-test is available at" `isInfixOf` out) $
1010
fail "Coverage report didn't build"
Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import Control.Monad (unless)
2-
import Data.List (isInfixOf, isPrefixOf)
1+
import Control.Monad ( unless )
2+
import Data.List ( isInfixOf, isPrefixOf )
33
import StackTest
44

55
main :: IO ()
66
main = do
77
stack ["clean"]
8-
stack ["build"]
9-
res <- getCoverageLines . snd <$> stackStderr ["test", "--coverage", "--color", "never"]
10-
case res of
11-
_:exprs:_ -> unless ("2/2" `isInfixOf` exprs) testFail
12-
_ -> testFail
13-
where
14-
testFail = fail "Stack didn't generate coverage from both libraries"
8+
stackCheckStdout ["test", "--coverage", "--color", "never"] check
9+
10+
check :: String -> IO ()
11+
check output = case getCoverageLines output of
12+
_:exprs:_ -> unless ("2/2" `isInfixOf` exprs) testFail
13+
_ -> testFail
14+
where
15+
testFail = fail "Stack didn't generate coverage from both libraries"
1516

1617
getCoverageLines :: String -> [String]
1718
getCoverageLines = dropWhile (not . isCoverageHeader) . lines
18-
where
19-
isCoverageHeader = isPrefixOf "Generating coverage report for "
19+
where
20+
isCoverageHeader = isPrefixOf "Summary coverage report for "

tests/integration/tests/multi-test/Main.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ import StackTest
44

55
main :: IO ()
66
main = do
7-
stack ["build"]
8-
stack ["test"]
97
-- FIXME: Make 'clean' unnecessary (see #1411)
108
stack ["clean"]
119
stackCheckStderr ["test", "--coverage"] $ \out -> do
12-
unless ("The coverage report for multi-test-suite's test-suite \"multi-test-suite-test\" is available at" `isInfixOf` out) $
10+
unless ("The coverage report for multi-test-suite's test-suite multi-test-suite-test is available at" `isInfixOf` out) $
1311
fail "Didn't get expected report for multi-test-suite-test"
1412
unless ("[S-6829]" `isInfixOf` out) $
1513
fail "Didn't get expected empty report for multi-test-suite-test-2"

0 commit comments

Comments
 (0)