on e94de40 help sign in
haskell.nix/lib/cover-project.nix
156 lines 4.9 kB history raw
1# A project coverage report is a composition of package coverage
2# reports
3{ stdenv, pkgs, lib, haskellLib }:
5# List of coverage reports to accumulate
6coverageReports:
8let
9 toBashArray = arr: "(" + (lib.concatStringsSep " " arr) + ")";
11 # Create table rows for a project coverage index page that look something like:
12 #
13 # | Package |
14 # |------------------|
15 # | cardano-shell |
16 # | cardano-launcher |
17 coverageTableRows = coverageReport:
18 ''
19 <tr>
20 <td>
21 <a href="${coverageReport.passthru.name}/hpc_index.html">${coverageReport.passthru.name}</href>
22 </td>
23 </tr>
24 '';
26 projectIndexHtml = pkgs.writeText "index.html" ''
27 <html>
28 <head>
29 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
30 </head>
31 <body>
32 <table border="1" width="100%">
33 <tbody>
34 <tr>
35 <th>Report</th>
36 </tr>
38 ${with lib; concatStringsSep "\n" (map coverageTableRows coverageReports)}
40 </tbody>
41 </table>
42 </body>
43 </html>
44 '';
46 ghc =
47 if (builtins.length coverageReports) > 0
48 then (builtins.head coverageReports).library.project.pkg-set.config.ghc.package or pkgs.ghc
49 else pkgs.ghc;
51 libs = map (r: r.library) coverageReports;
53 projectLibs = map (pkg: pkg.components.library) (lib.attrValues (haskellLib.selectProjectPackages ((lib.head libs).project.hsPkgs)));
55 mixDirs =
56 map
57 (l: "${l}/share/hpc/vanilla/mix/${l.identifier.name}-${l.identifier.version}")
58 (projectLibs);
60 srcDirs = map (l: l.src.outPath) (projectLibs);
62in pkgs.runCommand "project-coverage-report"
63 ({ nativeBuildInputs = [ (ghc.buildGHC or ghc) pkgs.buildPackages.zip ];
64 LANG = "en_US.UTF-8";
65 LC_ALL = "en_US.UTF-8";
66 } // lib.optionalAttrs (stdenv.buildPlatform.libc == "glibc") {
67 LOCALE_ARCHIVE = "${pkgs.buildPackages.glibcLocales}/lib/locale/locale-archive";
68 })
69 ''
70 function markup() {
71 local -n srcDs=$1
72 local -n mixDs=$2
73 local -n includedModules=$3
74 local destDir=$4
75 local tixFile=$5
77 local hpcMarkupCmd=("hpc" "markup" "--destdir=$destDir")
78 for srcDir in "''${srcDs[@]}"; do
79 hpcMarkupCmd+=("--srcdir=$srcDir")
80 done
82 for mixDir in "''${mixDs[@]}"; do
83 hpcMarkupCmd+=("--hpcdir=$mixDir")
84 done
86 for module in "''${includedModules[@]}"; do
87 hpcMarkupCmd+=("--include=$module")
88 done
90 hpcMarkupCmd+=("$tixFile")
92 echo "''${hpcMarkupCmd[@]}"
93 eval "''${hpcMarkupCmd[@]}"
94 }
96 function findModules() {
97 local searchDir=$2
98 local pattern=$3
100 pushd $searchDir
101 mapfile -d $'\0' $1 < <(find ./ -type f \
102 -wholename "$pattern" -not -name "Paths*" \
103 -exec basename {} \; \
104 | sed "s/\.mix$//" \
105 | tr "\n" "\0")
106 popd
107 }
109 mkdir -p $out/nix-support
110 mkdir -p $out/share/hpc/vanilla/tix/all
111 mkdir -p $out/share/hpc/vanilla/mix/
112 mkdir -p $out/share/hpc/vanilla/html/
114 # Find all tix files in each package
115 tixFiles=()
116 ${with lib; concatStringsSep "\n" (map (coverageReport: ''
117 identifier="${coverageReport.name}"
118 report=${coverageReport}
119 tix="$report/share/hpc/vanilla/tix/$identifier/$identifier.tix"
120 if test -f "$tix"; then
121 tixFiles+=("$tix")
122 fi
124 # Copy mix, tix, and html information over from each report
125 cp -Rn $report/share/hpc/vanilla/mix/$identifier/* $out/share/hpc/vanilla/mix/
126 cp -R $report/share/hpc/vanilla/tix/* $out/share/hpc/vanilla/tix/
127 cp -R $report/share/hpc/vanilla/html/* $out/share/hpc/vanilla/html/
128 '') coverageReports)}
130 if [ ''${#tixFiles[@]} -ne 0 ]; then
131 # Create tix file with test run information for all packages
132 tixFile="$out/share/hpc/vanilla/tix/all/all.tix"
133 hpcSumCmd=("hpc" "sum" "--union" "--output=$tixFile")
134 hpcSumCmd+=("''${tixFiles[@]}")
135 echo "''${hpcSumCmd[@]}"
136 eval "''${hpcSumCmd[@]}"
138 # Markup a HTML coverage report for the entire project
139 cp ${projectIndexHtml} $out/share/hpc/vanilla/html/index.html
140 echo "report coverage-per-package $out/share/hpc/vanilla/html/index.html" >> $out/nix-support/hydra-build-products
142 local markupOutDir="$out/share/hpc/vanilla/html/all"
143 local srcDirs=${toBashArray srcDirs}
144 local mixDirs=${toBashArray mixDirs}
145 local allMixModules=()
147 mkdir $markupOutDir
148 findModules allMixModules "$out/share/hpc/vanilla/mix/" "*.mix"
150 markup srcDirs mixDirs allMixModules "$markupOutDir" "$tixFile"
152 echo "report coverage $markupOutDir/hpc_index.html" >> $out/nix-support/hydra-build-products
153 ( cd $out/share/hpc/vanilla/html ; zip -r $out/share/hpc/vanilla/html.zip . )
154 echo "file zip $out/share/hpc/vanilla/html.zip" >> $out/nix-support/hydra-build-products
155 fi
156 ''