Last active
August 25, 2022 22:27
-
-
Save rogerluan/aaba6694a45ed5381e7e6b2259abd9f7 to your computer and use it in GitHub Desktop.
Xcode doesn’t gather code coverage from packages when set to “some targets”. This script fixes this. Also see https://forums.swift.org/t/xcode-doesnt-gather-code-coverage-from-packages-when-set-to-some-targets/37220
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1. Configure your Swift Package scheme to collect code coverage for "all targets" - NOT "some targets" | |
# 2. Test your Swift Package using either `xcodebuild test`, which should generate a `.xcresult` file. | |
# 3. Convert that `.xcresult` file into a `.json` file using: | |
# ```sh | |
# $ xcrun xccov view --report --json #{path_to_xcresult_file} > #{xccov_json_report} | |
# ``` | |
# 4. Lastly, strip out the targets that you're not interested using this method. | |
# | |
# Note 1: This code considers you only want to keep 1 of the targets. | |
# Note 2: The resulting json file will replace/override the existing one without any warning. | |
# Note 3: The resulting json file will look like this: | |
# ```js | |
# { | |
# "coveredLines":373, | |
# "lineCoverage":0.979002624671916, | |
# "targets":[ | |
# { … Your desired targets information will be declared here … } | |
# ], | |
# "executableLines":381 | |
# } | |
# ``` | |
# So please note that this script is only modifying the targets array, thus the "coveredLines", | |
# "lineCoverage" and "executableLines" will still report information relevant to all the targets. | |
# This is not a problem if you're using Code Climate, because Code Climate's `format-coverage` | |
# script will ignore those top level information and look only at the information declared for the | |
# target. Your mileage may vary with other Code Coverage services/tools. | |
def remove_all_targets_except(xccov_json_path, targets_to_keep) | |
require 'json' | |
file = File.read(xccov_json_path) | |
json_hash = JSON.parse(file) | |
targets = json_hash['targets'] | |
targets = targets.filter do |target| | |
# This file has 2 targets with the name of the Swift Package, for some reason. | |
# One of them is invalid (it has zero files attached to it), thus generates 0% code coverage. | |
# Here we select the right one - the one that has files. | |
# If you select "some targets" in your Swift Package's scheme code coverage settings, | |
# you'll see 0% code coverage because it seems like Xcode picks up this "invalid" target | |
targets_to_keep.include?(target['name']) and !target['files'].empty? | |
end | |
json_hash['targets'] = targets | |
File.write(xccov_json_path, JSON.dump(json_hash)) | |
end | |
# Similar to the script above, but for `swift test`. `xcodebuild test` can be ~12x slower than `swift test`, so prefer the latter. | |
# 1. Configure your Swift Package scheme to collect code coverage for "all targets" - NOT "some targets" | |
# 2. Run `swift test --enable-code-coverage` which generates `.profdata` and `.profraw` files. | |
# 3. Run `swift test --show-codecov-path`.strip to get the absolute path of the code coverage file. | |
# 4. Lastly, pass in the result from the previous step as the `lcov_json_path` argument in the method below. | |
def remove_files_from_unwanted_targets(lcov_json_path, unwanted_targets_regex = /\.build|\/Tests\//) | |
require 'json' | |
file = File.read(lcov_json_path) | |
json_hash = JSON.parse(file) | |
files = json_hash['data'][0]['files'] | |
files = files.filter do |file| | |
file['filename'].match?(unwanted_targets_regex) ? false : true | |
end | |
json_hash['data'][0]['files'] = files | |
functions = json_hash['data'][0]['functions'] | |
functions = functions.filter do |function| | |
function['filenames'][0].match?(unwanted_targets_regex) ? false : true | |
end | |
json_hash['data'][0]['functions'] = functions | |
File.write(lcov_json_path, JSON.dump(json_hash)) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment