Skip to content

Commit 5ee8fff

Browse files
committed
SwiftPM: HTML Coverage Report
1 parent 79b68f9 commit 5ee8fff

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# HTML Coverage Report
2+
3+
* Proposal: [SE-NNNN](NNNN-swiftpm-html-coverage-report.md)
4+
* Authors: [Sam Khouri](https://github.com/bkhouri)
5+
* Review Manager: TBD
6+
* Status: **Awaiting implementation**
7+
* Implementation: [swiftlang/swift-package-manager#9076][PR]
8+
* Decision Notes: [Pitch](https://forums.swift.org/t/pitch-adding-html-coverage-support/82358)
9+
10+
## Introduction
11+
12+
Currently, `swift test` supports generating a JSON coverage report, which is
13+
great for ingesting into various systems. The JSON, however, is not very
14+
"human-readable" while iterating at-desk.
15+
16+
This proposes adding an additional command line argument to `swift test` that
17+
would allow the caller to select the generation of an HTML coverage report.
18+
19+
20+
## Motivation
21+
22+
JSON coverage report is great for ingesting into external tools that post-process
23+
the coverage data. If SwiftPM could generate an HTML coverage report:
24+
- said report can be uploaded to CI systems for visual inspection
25+
- developer can generate the report at-desk, giving faster feedback to determine
26+
if the current changes are sufficiently covered to their liking.
27+
28+
## Proposed solution
29+
30+
31+
32+
If users currently want an HTML report, the user must manually construct the
33+
`llvm-cov` binary directly with the correct command line arguments.
34+
35+
e.g.:
36+
```sh
37+
❯ swift test --enable-code-coverage
38+
39+
❯ swift test --show-codecov-path
40+
41+
❯ llvm-cov show \
42+
--project-title="HelloWorld" \
43+
--format="html" \
44+
--output-dir=".coverage" \
45+
--instr-profile=".build/arm64-apple-macosx/debug/codecov/default.profdata" \
46+
".build/.../HelloWorldPackageTests.xctest/Contents/MacOS/HelloWorldPackageTests" \
47+
"Sources"
48+
```
49+
50+
Since SwiftPM currently orchestrates the JSON coverage data, the solution adds a
51+
new command line argument, e.g.: `--coverage-format` to `swift test` which can
52+
be specified multiple times, to generate multiple coverage report type from a
53+
single test execution.
54+
55+
While processing the coverage data, SwiftPM will loop on all the unique coverage
56+
format options to generate the specified reports.
57+
58+
Unless otherwise specified, this proposal applies only to the HTML Coverage
59+
report. The generation of the JSON Coverage report is unchanged and is out of
60+
scope.
61+
62+
## Detailed design
63+
64+
Existing tools in LLVM have been around for several years (and maybe even decades),
65+
and provide robust tools for code coverage analysis. The LLVM tools are
66+
well-documented, and have been used in production for many years. SwiftPM will
67+
make use of LLVM's tools and construct the proper command line arguments to the
68+
`llvm-cov show` utility, which will generate the HTML report.
69+
70+
### Format Selection
71+
72+
The `swift test` command line will have an option named `--coverage-format`,
73+
which accepts either `json` or `html`. This option can be specified multiple
74+
times on the command line, and a report will be generated for each format
75+
specified.
76+
77+
The command line option will be similar to:
78+
79+
```sh
80+
--codecov-format, --code-coverage-format, --coverage-format <format>
81+
Format of the code coverage output. Can be specified multiple times. (default: json)
82+
json - Produces a JSON coverage report.
83+
html - Produces an HTML report producd by llvm-cov.
84+
```
85+
86+
87+
### Coverage Report configuration
88+
89+
`llvm-cov show` has several report configurability options. In order to
90+
prevent a "command line arguments" explosion to `swift test`, the configuration
91+
options will be read from a response file. The optinal response file will be
92+
located in `<repo>/.swiftpm/configuration/coverage.html.report.args.txt`. The
93+
response file will be supported.
94+
95+
The user can include `--format=text`, or a variation thereof, in the resoonse
96+
file. In order to ensure SwiftPM will always generated an HTML report, SwiftPM
97+
will add `--format=html` after the responsefile argument to ensure `llvm-cov`
98+
will generate an HTML report.
99+
100+
101+
102+
SwiftPM will not perform any validation on the response file contents, except
103+
to determine the output location.
104+
105+
### Coverage report location
106+
107+
By default, the HTML report will be created in location under the scratch path
108+
(ie: the build directory). However, this can be overriden using the response file.
109+
110+
Some CI system, such as [Jenkins](https://www.jenkins.io), only allow archiving
111+
contents required files/directories that belong in a "sandbox" location. It
112+
can be a safe assumption that the CI system will have a copy of the repository
113+
in the "sandbox" location, allow this system to upload the HTML report.
114+
115+
116+
### Show coverage path
117+
Prior to this proposal `swift test --show-coverage-path` would display a single
118+
absolute path location to the JSON coverage report.
119+
120+
Since `--coverage-format` can be specified multiple times, it's output must be
121+
changed to reflect the new functionality.
122+
123+
If the `--coverage-format` option is specified on the `swift test` command line
124+
a single time (or is not specified at all), there is no change to the output.
125+
126+
127+
if `--coverage-format` is specified multiple times, the output must reflect this.
128+
A new command line argument `--print-coverage-path-mode` option will be available
129+
to describe the visual representation of the output paths. The options accepts
130+
`json`json` or `text` and applies whenever `--show-coverage-path` is selected.
131+
132+
A value of `json` will output a JSON object with the key representing the format,
133+
and the value representing the output location of said format.
134+
135+
A value of `text` will omit the format in the output if a single `coverage-format`
136+
is requested. Otherwise, the output will be similar to
137+
138+
```sh
139+
❯ swift test -c release --build-system swiftbuild --show-coverage-path --coverage-format html --coverage-format json
140+
Building for debugging...
141+
[5/5] Write swift-version-4B9677C1F510A69F.txt
142+
Build complete! (0.37s)
143+
Html: /swift-package-manager/.build/arm64-apple-macosx/Products/Release/codecov/Simple-html
144+
Json: /swift-package-manager/.build/arm64-apple-macosx/Products/Release/codecov/Simple.json
145+
```
146+
147+
So user can programatically, and reliably, retrieve the coverage report location,
148+
an additional command line argument is made available.
149+
150+
```sh
151+
--print-codecov-path-mode, --print-code-coverage-path-mode, --print-coverage-path-mode <print-codecov-path-mode>
152+
How to display the paths of the selected code coverage file formats. (default: text)
153+
json - Display the output in JSON format.
154+
text - Display the output as plain text.
155+
```
156+
157+
```sh
158+
❯ swift test -c release --build-system swiftbuild --show-coverage-path --coverage-format html --coverage-format json --print-coverage-path-mode json
159+
Building for debugging...
160+
[1/1] Write swift-version-4B9677C1F510A69F.txt
161+
Build of product 'swift-test' complete! (0.40s)
162+
{
163+
"html" : "/Users/bkhouri/Documents/git/public/swiftlang/swift-package-manager/.build/arm64-apple-macosx/Products/Release/codecov/SwiftPM-html",
164+
"json" : "/Users/bkhouri/Documents/git/public/swiftlang/swift-package-manager/.build/arm64-apple-macosx/Products/Release/codecov/SwiftPM.json"
165+
}
166+
```
167+
168+
## Security
169+
170+
Since SwiftPM will use `llvm-cov show`, there may be security implications from
171+
the `llvm-cov` utility, but this is outside of the Swift organizations control.
172+
173+
The LLVM project has a [LLVM Security Response Group](https://llvm.org/docs/Security.html),
174+
which has a process for handling security vulnerabilities.
175+
176+
## Impact on existing packages
177+
178+
No impact is expected.
179+
180+
## Alternatives considered
181+
182+
- In addition to the response file, the coverage report generation can support
183+
a command line argument similar to `-Xlinker`, `-Xcc` and others, which will
184+
pass the arguments to `llvm-cov show` and override the values in the response
185+
file. This has _not_ be implemented in the [PR].
186+
187+
188+
189+
[PR]: https://github.com/swiftlang/swift-package-manager/pull/9076

0 commit comments

Comments
 (0)