|  | 
|  | 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