Skip to content

Commit 965c7ac

Browse files
peterbecichpurefnhamishmack
authored
Update HPC for better compatibility with large projects (#1484)
* patch hpc to allow files to be used for the list of src dirs, hpc dirs, and includes * delete trailing whitespace * use Response Files for HPC arguments; delete unnecessary patch * Add ghc patch based on what was merged upstream * Fix coverage tests * Update responseFile usage * Enable coverage-no-libs test Co-authored-by: Richard Wallace <[email protected]> Co-authored-by: Hamish Mackenzie <[email protected]>
1 parent 49c4aa4 commit 965c7ac

File tree

3 files changed

+68
-170
lines changed

3 files changed

+68
-170
lines changed

lib/cover-project.nix

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ project:
88
coverageReports:
99

1010
let
11-
toBashArray = arr: "(" + (lib.concatStringsSep " " arr) + ")";
12-
1311
# Create a list element for a project coverage index page.
1412
coverageListElement = coverageReport:
1513
''
@@ -51,12 +49,16 @@ let
5149

5250
libs = lib.unique (lib.concatMap (r: r.mixLibraries) coverageReports);
5351

52+
writeArr = name: arr: pkgs.writeText name (lib.concatStringsSep "\n" arr);
53+
5454
mixDirs =
5555
map
5656
(l: "${l}/share/hpc/vanilla/mix/${l.identifier.name}-${l.identifier.version}")
5757
libs;
58+
mixDirsFile = writeArr "mixdirs" mixDirs;
5859

5960
srcDirs = map (l: l.srcSubDirPath) libs;
61+
srcDirsFile = writeArr "srcdirs" srcDirs;
6062

6163
allCoverageReport = haskellLib.coverageReport {
6264
name = "all";
@@ -77,45 +79,6 @@ in pkgs.runCommand "project-coverage-report"
7779
LOCALE_ARCHIVE = "${pkgs.buildPackages.glibcLocales}/lib/locale/locale-archive";
7880
})
7981
''
80-
function markup() {
81-
local -n srcDs=$1
82-
local -n mixDs=$2
83-
local -n includedModules=$3
84-
local destDir=$4
85-
local tixFile=$5
86-
87-
local hpcMarkupCmd=("hpc" "markup" "--destdir=$destDir")
88-
for srcDir in "''${srcDs[@]}"; do
89-
hpcMarkupCmd+=("--srcdir=$srcDir")
90-
done
91-
92-
for mixDir in "''${mixDs[@]}"; do
93-
hpcMarkupCmd+=("--hpcdir=$mixDir")
94-
done
95-
96-
for module in "''${includedModules[@]}"; do
97-
hpcMarkupCmd+=("--include=$module")
98-
done
99-
100-
hpcMarkupCmd+=("$tixFile")
101-
102-
echo "''${hpcMarkupCmd[@]}"
103-
eval "''${hpcMarkupCmd[@]}"
104-
}
105-
106-
function findModules() {
107-
local searchDir=$2
108-
local pattern=$3
109-
110-
pushd $searchDir
111-
mapfile -d $'\0' $1 < <(find ./ -type f \
112-
-wholename "$pattern" -not -name "Paths*" \
113-
-exec basename {} \; \
114-
| sed "s/\.mix$//" \
115-
| tr "\n" "\0")
116-
popd
117-
}
118-
11982
mkdir -p $out/nix-support
12083
mkdir -p $out/share/hpc/vanilla/tix/all
12184
mkdir -p $out/share/hpc/vanilla/mix/
@@ -127,12 +90,14 @@ in pkgs.runCommand "project-coverage-report"
12790
identifier="${coverageReport.name}"
12891
report=${coverageReport}
12992
tix="$report/share/hpc/vanilla/tix/$identifier/$identifier.tix"
130-
if test -f "$tix"; then
93+
if [ -f "$tix" ]; then
13194
tixFiles+=("$tix")
13295
fi
13396
13497
# Copy mix, tix, and html information over from each report
135-
cp -Rn $report/share/hpc/vanilla/mix/$identifier $out/share/hpc/vanilla/mix/
98+
if [ -d "$report/share/hpc/vanilla/mix/$identifier" ]; then
99+
cp -Rn $report/share/hpc/vanilla/mix/$identifier $out/share/hpc/vanilla/mix/
100+
fi
136101
cp -R $report/share/hpc/vanilla/tix/* $out/share/hpc/vanilla/tix/
137102
cp -R $report/share/hpc/vanilla/html/* $out/share/hpc/vanilla/html/
138103
'') coverageReports)}

lib/cover.nix

Lines changed: 59 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
}:
1717

1818
let
19-
toBashArray = arr: "(" + (lib.concatStringsSep " " arr) + ")";
20-
2119
mixDir = l: "${l}/share/hpc/vanilla/mix/${l.identifier.name}-${l.identifier.version}";
2220
mixDirs = map mixDir mixLibraries;
2321

@@ -39,130 +37,35 @@ in pkgs.runCommand (name + "-coverage-report")
3937
LOCALE_ARCHIVE = "${pkgs.buildPackages.glibcLocales}/lib/locale/locale-archive";
4038
})
4139
''
42-
function markup() {
43-
local -n srcDs=$1
44-
local -n mixDs=$2
45-
local -n includedModules=$3
46-
local destDir=$4
47-
local tixFile=$5
48-
49-
local hpcMarkupCmd=("hpc" "markup" "--destdir=$destDir")
50-
for srcDir in "''${srcDs[@]}"; do
51-
hpcMarkupCmd+=("--srcdir=$srcDir")
52-
done
53-
54-
for mixDir in "''${mixDs[@]}"; do
55-
hpcMarkupCmd+=("--hpcdir=$mixDir")
56-
done
57-
58-
for module in "''${includedModules[@]}"; do
59-
hpcMarkupCmd+=("--include=$module")
60-
done
61-
62-
hpcMarkupCmd+=("$tixFile")
63-
64-
echo "''${hpcMarkupCmd[@]}"
65-
eval "''${hpcMarkupCmd[@]}"
66-
}
67-
68-
function sumTix() {
69-
local -n includedModules=$1
70-
local -n tixFs=$2
71-
local outFile="$3"
72-
73-
if (( "''${#tixFs[@]}" > 0 )); then
74-
local hpcSumCmd=("hpc" "sum" "--union" "--output=$outFile")
75-
76-
for module in "''${includedModules[@]}"; do
77-
hpcSumCmd+=("--include=$module")
78-
done
79-
80-
for tixFile in "''${tixFs[@]}"; do
81-
hpcSumCmd+=("$tixFile")
82-
done
83-
84-
echo "''${hpcSumCmd[@]}"
85-
eval "''${hpcSumCmd[@]}"
86-
else
87-
# If there are no tix files we output an empty tix file so that we can
88-
# markup an empty HTML coverage report. This is preferable to failing to
89-
# output a HTML report.
90-
echo 'Tix []' > $outFile
91-
fi
92-
}
93-
94-
function findModules() {
95-
local -n result=$1
96-
local -n searchDirs=$2
97-
local pattern=$3
98-
99-
for dir in "''${searchDirs[@]}"; do
100-
pushd $dir
101-
local temp=()
102-
mapfile -d $'\0' temp < <(find ./ -type f \
103-
-wholename "$pattern" -not -name "Paths*" \
104-
-exec basename {} \; \
105-
| sed "s/\.mix$//" \
106-
| tr "\n" "\0")
107-
result+=("''${temp[@]}")
108-
popd
109-
done
110-
}
111-
11240
mkdir -p $out/nix-support
11341
mkdir -p $out/share/hpc/vanilla/mix/
11442
mkdir -p $out/share/hpc/vanilla/tix/${name}
11543
mkdir -p $out/share/hpc/vanilla/html/${name}
11644
117-
local srcDirs=${toBashArray srcDirs}
118-
local mixDirs=${toBashArray mixDirs}
119-
120-
# Copy out mix files used for this report
121-
for dir in "''${mixDirs[@]}"; do
122-
if [ -d "$dir" ]; then
123-
cp -R "$dir" $out/share/hpc/vanilla/mix/
124-
fi
125-
done
126-
127-
local mixModules=()
128-
# Mix modules for all packages in "mixLibraries"
129-
findModules mixModules mixDirs "*.mix"
130-
131-
# We need to make a distinction between library "exposed-modules" and
132-
# "other-modules" used in test suites:
133-
# - "exposed-modules" are addressed as "$library-$version-$hash/module"
134-
# - "other-modules" are addressed as "module"
135-
#
136-
# This complicates the code required to find the mix modules. For a given mix directory:
137-
#
138-
# mix
139-
# └── ntp-client-0.0.1
140-
# └── ntp-client-0.0.1-gYjRsBHUCaHX7ENcjHnw5
141-
# ├── Network.NTP.Client.mix
142-
# ├── Network.NTP.Client.Packet.mix
143-
# └── Network.NTP.Client.Query.mix
144-
#
145-
# Iff ntp-client uses "other-modules" in a test suite, both:
146-
# - "mix/ntp-client-0.0.1", and
147-
# - "mix/ntp-client-0.0.1/ntp-client-0.0.1-gYjRsBHUCaHX7ENcjHnw5"
148-
# need to be provided to hpc as search directories.
149-
#
150-
# I'd prefer to just exclude "other-modules", but I can't think of an easy
151-
# way to do that in bash.
152-
#
153-
# Here we expand the search dirs and modify the mix dirs accordingly:
154-
for dir in "''${mixDirs[@]}"; do
155-
local otherModulesSearchDirs=()
156-
# Simply consider any directory with a mix file as a search directory.
157-
mapfile -d $'\0' otherModulesSearchDirs < <(find $dir -type f \
158-
-wholename "*.mix" \
159-
-exec dirname {} \; \
160-
| uniq \
161-
| tr "\n" "\0")
162-
mixDirs+=("''${otherModulesSearchDirs[@]}")
163-
done
164-
165-
local tixFiles=()
45+
local srcDirArgs=$(mktemp)
46+
${lib.concatStringsSep "\n" (map (srcDir: ''
47+
echo --srcdir=${srcDir} >> $srcDirArgs
48+
'') srcDirs)
49+
}
50+
local mixDirArgs=$(mktemp)
51+
${ # Copy out mix files used for this report
52+
lib.concatStrings (map (mixDir: ''
53+
local dir=${mixDir}
54+
echo --hpcdir=$dir >> $mixDirArgs
55+
if [ -d $dir ]; then
56+
cp -R "$dir" $out/share/hpc/vanilla/mix/
57+
fi
58+
'') mixDirs)
59+
}
60+
local includeArgs=$(mktemp)
61+
find $out/share/hpc/vanilla/mix/ -type f \
62+
-wholename "*.mix" -not -name "Paths*" \
63+
-exec basename {} \; \
64+
| sed "s/\.mix$//" \
65+
| sed "s/^.*$/--include=\0/" \
66+
>> $includeArgs
67+
68+
local tixFiles=$(mktemp -d)/tixFiles
16669
${lib.concatStringsSep "\n" (builtins.map (check: ''
16770
if [ -d "${check}/share/hpc/vanilla/tix" ]; then
16871
pushd ${check}/share/hpc/vanilla/tix
@@ -175,11 +78,19 @@ in pkgs.runCommand (name + "-coverage-report")
17578
cp "$tixFile" "$newTixFile"
17679
17780
# Add the tix file to our list
178-
tixFiles+=("$newTixFile")
81+
echo $newTixFile >> $tixFiles
17982
18083
# Create a coverage report for *just that check* affecting any of the
18184
# "mixLibraries"
182-
markup srcDirs mixDirs mixModules "$out/share/hpc/vanilla/html/${check.name}/" "$newTixFile"
85+
local responseFile=$(mktemp)
86+
echo markup > $responseFile
87+
echo '--destdir'=$out/share/hpc/vanilla/html/${check.name}/ >> $responseFile
88+
cat $srcDirArgs $mixDirArgs $includeArgs >> $responseFile
89+
echo $newTixFile >> $responseFile
90+
91+
echo hpc response file:
92+
cat $responseFile
93+
hpc @$responseFile
18394
18495
popd
18596
fi
@@ -192,10 +103,33 @@ in pkgs.runCommand (name + "-coverage-report")
192103
local markupOutDir="$out/share/hpc/vanilla/html/${name}"
193104
194105
# Sum all of our tix files
195-
sumTix mixModules tixFiles "$sumTixFile"
106+
if [ -e $tixFiles ]; then
107+
local responseFile=$(mktemp)
108+
echo sum > $responseFile
109+
echo '--union' >> $responseFile
110+
echo '--output'=$sumTixFile >> $responseFile
111+
cat $includeArgs >> $responseFile
112+
cat $tixFiles >> $responseFile
113+
114+
echo hpc response file:
115+
cat $responseFile
116+
hpc @$responseFile
117+
else
118+
# If there are no tix files we output an empty tix file so that we can
119+
# markup an empty HTML coverage report. This is preferable to failing to
120+
# output a HTML report.
121+
echo 'Tix []' > $sumTixFile
122+
fi
196123
197124
# Markup a HTML report
198-
markup srcDirs mixDirs mixModules "$markupOutDir" "$sumTixFile"
125+
local responseFile=$(mktemp)
126+
echo markup > $responseFile
127+
echo '--destdir'=$markupOutDir >> $responseFile
128+
cat $srcDirArgs $mixDirArgs $includeArgs >> $responseFile
129+
echo $sumTixFile >> $responseFile
130+
echo hpc response file:
131+
cat $responseFile
132+
hpc @$responseFile
199133
200134
# Provide a HTML zipfile and Hydra links
201135
( cd "$markupOutDir" ; zip -r $out/share/hpc/vanilla/${name}-html.zip . )

test/coverage-no-libs/default.nix

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ let
2222

2323
in recurseIntoAttrs ({
2424
# Does not work on ghcjs because it needs zlib.
25-
# TODO projectCoverageReport is broken in master for this example.
26-
meta.disabled = true || stdenv.hostPlatform.isGhcjs;
25+
meta.disabled = stdenv.hostPlatform.isGhcjs;
2726
run = stdenv.mkDerivation {
2827
name = "coverage-test";
2928

0 commit comments

Comments
 (0)