xcov 1.7.4 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/lib/xcov/manager.rb +70 -23
- data/lib/xcov/model/report.rb +7 -1
- data/lib/xcov/options.rb +31 -4
- data/lib/xcov/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f9fd23056fe7c21f3e20fb62814b10715e4dbcea016c57114b54f7ebbcf904b
|
4
|
+
data.tar.gz: f29f43359b5fdfdb72b33760341b61e3dc51293d84d207cace704c669be639ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74424f15672e083e2936c0a42b46be69e02f6f556766a98b9fc786118bcb45eb6b5c621c8c9f457b3cb84b6e53a9707a44b050edb80c6ffaa44c4c869daa856e
|
7
|
+
data.tar.gz: c1b3101eabaf8ddb241fa7da1019c3d53b0111d207c08f997ec30c9b0eff4084e5e5bfd159251bbeb3901700d78297172af375ad0870e30e971334d7678fe583
|
data/README.md
CHANGED
@@ -61,6 +61,7 @@ xcov -w LystSDK.xcworkspace -s LystSDK -o xcov_output
|
|
61
61
|
* `--source_directory` `-r`: The path to project's root directory (optional).
|
62
62
|
* `--derived_data_path` `-j`: Path of your project `Derived Data` folder (optional).
|
63
63
|
* `--xccov_file_direct_path` `-f`: Direct path to the xccoverage/xccovreport file to parse to generate code coverage (optional).
|
64
|
+
* `--cloned_source_packages_path` `-C`: Sets a custom path for Swift Package Manager dependencies (optional).
|
64
65
|
* `--minimum_coverage_percentage` `-m`: Raise exception if overall coverage percentage is under this value (ie. 75.0).
|
65
66
|
* `--include_test_targets`: Enables coverage reports for `.xctest` targets.
|
66
67
|
* `--ignore_file_path` `-x`: Relative or absolute path to the file containing the list of ignored files.
|
@@ -79,7 +80,10 @@ xcov -w LystSDK.xcworkspace -s LystSDK -o xcov_output
|
|
79
80
|
* `--coveralls_repo_token`: Repository token to be used by integrations not compatible with Coveralls (optional).
|
80
81
|
* `--slack_username`: The username which is used to publish to slack (optional).
|
81
82
|
* `--slack_message`: The message which is published together with a successful report (optional).
|
83
|
+
* `--xcconfig`: Use an extra XCCONFIG file to build your app (optional).
|
84
|
+
* `--ideFoundationPath`: Absolute path to the IDEFoundation.framework binary (optional).
|
82
85
|
* `--legacy_support`: Enables parsing coverage reports generated by Xcode 9.2 or previous versions.
|
86
|
+
* `--is_swift_package`: Enables generating coverage reports for Package.swift derived projects.
|
83
87
|
|
84
88
|
_**Note:** All paths you provide should be absolute and unescaped_
|
85
89
|
|
data/lib/xcov/manager.rb
CHANGED
@@ -17,8 +17,10 @@ module Xcov
|
|
17
17
|
Xcov.config = options
|
18
18
|
|
19
19
|
# Set project options
|
20
|
-
|
21
|
-
|
20
|
+
if !Xcov.config[:is_swift_package]
|
21
|
+
FastlaneCore::Project.detect_projects(options)
|
22
|
+
Xcov.project = FastlaneCore::Project.new(options)
|
23
|
+
end
|
22
24
|
|
23
25
|
# Set ignored files handler
|
24
26
|
Xcov.ignore_handler = IgnoreHandler.new
|
@@ -47,13 +49,15 @@ module Xcov
|
|
47
49
|
|
48
50
|
# Find .xccoverage file
|
49
51
|
# If no xccov direct path, use the old derived data path method
|
50
|
-
if xccov_file_direct_paths.
|
52
|
+
if xccov_file_direct_paths.empty?
|
51
53
|
extension = Xcov.config[:legacy_support] ? "xccoverage" : "xccovreport"
|
54
|
+
|
52
55
|
test_logs_path = derived_data_path + "Logs/Test/"
|
53
|
-
|
54
|
-
|
56
|
+
UI.important("Derived content from #{Dir["#{test_logs_path}/*"]}")
|
57
|
+
|
58
|
+
xccoverage_files = Dir["#{test_logs_path}*.#{extension}", "#{test_logs_path}*.xcresult/*/action.#{extension}"]
|
55
59
|
if xccoverage_files.empty?
|
56
|
-
xcresult_paths = Dir["#{test_logs_path}*.xcresult"]
|
60
|
+
xcresult_paths = Dir["#{test_logs_path}*.xcresult"]
|
57
61
|
xcresult_paths.each do |xcresult_path|
|
58
62
|
xcresults_to_parse_and_export << xcresult_path
|
59
63
|
end
|
@@ -77,6 +81,7 @@ module Xcov
|
|
77
81
|
# Iterates over xcresults
|
78
82
|
# Exports .xccovarchives
|
79
83
|
# Exports .xccovreports and collects the paths
|
84
|
+
# Merge .xccovreports if multiple exists and return merged report
|
80
85
|
unless xcresults_to_parse_and_export.empty?
|
81
86
|
xccoverage_files = process_xcresults!(xcresults_to_parse_and_export)
|
82
87
|
end
|
@@ -88,6 +93,7 @@ module Xcov
|
|
88
93
|
|
89
94
|
# Convert .xccoverage file to json
|
90
95
|
ide_foundation_path = Xcov.config[:legacy_support] ? nil : Xcov.config[:ideFoundationPath]
|
96
|
+
xccoverage_files = xccoverage_files.sort_by {|filename| File.mtime(filename)}.reverse
|
91
97
|
json_report = Xcov::Core::Parser.parse(xccoverage_files.first, Xcov.config[:output_directory], ide_foundation_path)
|
92
98
|
ErrorHandler.handle_error("UnableToParseXccoverageFile") if json_report.nil?
|
93
99
|
|
@@ -154,6 +160,11 @@ module Xcov
|
|
154
160
|
report.targets.each do |target|
|
155
161
|
table_rows << [target.name, target.displayable_coverage]
|
156
162
|
end
|
163
|
+
|
164
|
+
if report.targets.count > 0
|
165
|
+
table_rows << ["Average Coverage", "#{"%.2f%%" % (report.coverage*100)}"]
|
166
|
+
end
|
167
|
+
|
157
168
|
puts Terminal::Table.new({
|
158
169
|
title: "xcov Coverage Report".green,
|
159
170
|
rows: table_rows
|
@@ -194,40 +205,76 @@ module Xcov
|
|
194
205
|
def xccov_file_direct_paths
|
195
206
|
# If xccov_file_direct_path was supplied, return
|
196
207
|
if Xcov.config[:xccov_file_direct_path].nil?
|
197
|
-
return
|
208
|
+
return []
|
198
209
|
end
|
199
210
|
|
200
|
-
|
201
|
-
return
|
211
|
+
paths = Xcov.config[:xccov_file_direct_path]
|
212
|
+
return paths.map { |path| Pathname.new(path).to_s }
|
202
213
|
end
|
203
214
|
|
204
215
|
def process_xcresults!(xcresult_paths)
|
205
216
|
output_path = Xcov.config[:output_directory]
|
206
217
|
FileUtils.mkdir_p(output_path)
|
207
|
-
|
208
|
-
|
218
|
+
|
219
|
+
result_path = ""
|
220
|
+
index = 0
|
221
|
+
|
222
|
+
xcresult_paths.flat_map do |xcresult_path|
|
209
223
|
begin
|
210
224
|
parser = XCResult::Parser.new(path: xcresult_path)
|
211
|
-
|
225
|
+
|
212
226
|
# Exporting to same directory as xcresult
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
#
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
UI.important("Copying .xccovreport to #{path}")
|
227
|
+
tmp_archive_paths = parser.export_xccovarchives(destination: output_path)
|
228
|
+
tmp_report_paths = parser.export_xccovreports(destination: output_path)
|
229
|
+
|
230
|
+
# Rename each file with global index
|
231
|
+
tmp_report_paths.each_with_index do |item, i|
|
232
|
+
File.rename(tmp_archive_paths[i], "#{output_path}/xccovarchive-#{index + i}.xccovarchive")
|
233
|
+
File.rename(item, "#{output_path}/xccovreport-#{index + i}.xccovreport")
|
234
|
+
index += 1
|
222
235
|
end
|
223
|
-
|
224
|
-
report_paths
|
225
236
|
rescue
|
226
237
|
UI.error("Error occured while exporting xccovreport from xcresult '#{xcresult_path}'")
|
227
238
|
UI.error("Make sure you have both Xcode 11 selected and pointing to the correct xcresult file")
|
228
239
|
UI.crash!("Failed to export xccovreport from xcresult'")
|
229
240
|
end
|
230
241
|
end
|
242
|
+
|
243
|
+
# Grab paths from the directory instead of parser
|
244
|
+
report_paths = Dir["#{output_path}/*.xccovreport"]
|
245
|
+
archive_paths = Dir["#{output_path}/*.xccovarchive"]
|
246
|
+
|
247
|
+
# Merge coverage reports
|
248
|
+
if report_paths.length > 1 then
|
249
|
+
# Creating array of paths for merging
|
250
|
+
paths = ""
|
251
|
+
for i in 0..report_paths.length
|
252
|
+
paths += " #{report_paths[i]} #{archive_paths[i]}"
|
253
|
+
end
|
254
|
+
|
255
|
+
UI.important("Merging multiple coverage reports with #{paths}")
|
256
|
+
if system ( "xcrun xccov merge --outReport #{output_path}/out.xccovreport --outArchive #{output_path}/out.xccovarchive #{paths}" ) then
|
257
|
+
result_path = "#{output_path}/out.xccovreport"
|
258
|
+
else
|
259
|
+
UI.error("Error occured during merging multiple coverage reports")
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
if result_path == "" then
|
264
|
+
# Informating user of export paths
|
265
|
+
archive_paths.each do |path|
|
266
|
+
UI.important("Copying .xccovarchive to #{path}")
|
267
|
+
end
|
268
|
+
report_paths.each do |path|
|
269
|
+
UI.important("Copying .xccovreport to #{path}")
|
270
|
+
end
|
271
|
+
|
272
|
+
# Return array of report_paths if coverage reports were not merged
|
273
|
+
return report_paths
|
274
|
+
else
|
275
|
+
# Return merged xccovreport
|
276
|
+
return [result_path]
|
277
|
+
end
|
231
278
|
end
|
232
279
|
end
|
233
280
|
end
|
data/lib/xcov/model/report.rb
CHANGED
@@ -58,6 +58,10 @@ module Xcov
|
|
58
58
|
# Create target objects
|
59
59
|
targets = targets.map { |target| Target.map(target) }.sort { |lhs, rhs| lhs.name <=> rhs.name }
|
60
60
|
|
61
|
+
if !Xcov.config[:include_zero_targets]
|
62
|
+
targets = targets.select { |target| target.coverage > 0 }
|
63
|
+
end
|
64
|
+
|
61
65
|
Report.new(targets)
|
62
66
|
end
|
63
67
|
|
@@ -73,7 +77,9 @@ module Xcov
|
|
73
77
|
filtered_targets = filtered_targets.select { |target| self.included_targets.include?(target["name"])}
|
74
78
|
end
|
75
79
|
|
76
|
-
|
80
|
+
filtered_targets = filtered_targets.select { |target| !target["files"].empty? }
|
81
|
+
|
82
|
+
supported_targets = Xcov.config[:is_swift_package] ? [] : Xcov.project.targets
|
77
83
|
if Xcov.config[:only_project_targets] && !supported_targets.empty?
|
78
84
|
filtered_targets = filtered_targets.select do |target|
|
79
85
|
name = target["name"]
|
data/lib/xcov/options.rb
CHANGED
@@ -77,12 +77,16 @@ module Xcov
|
|
77
77
|
key: :xccov_file_direct_path,
|
78
78
|
short_option: "-f",
|
79
79
|
env_name: "XCOV_FILE_DIRECT_PATH",
|
80
|
-
description: "The path to the xccoverage/xccovreport/xcresult
|
80
|
+
description: "The path or array of paths to the xccoverage/xccovreport/xcresult files to parse to generate code coverage",
|
81
|
+
type: Array,
|
81
82
|
optional: true,
|
82
83
|
verify_block: proc do |value|
|
83
|
-
|
84
|
-
|
85
|
-
|
84
|
+
values = value.is_a?(String) ? [value] : value
|
85
|
+
values.each do |value|
|
86
|
+
v = File.expand_path(value.to_s)
|
87
|
+
raise "xccoverage/xccovreport/xcresult file does not exist".red unless File.exist?(v)
|
88
|
+
raise "Invalid xccov file type (must be xccoverage, xccovreport, xcresult)".red unless value.end_with? "xccoverage" or value.end_with? "xccovreport" or value.end_with? "xcresult"
|
89
|
+
end
|
86
90
|
end
|
87
91
|
),
|
88
92
|
FastlaneCore::ConfigItem.new(
|
@@ -101,6 +105,22 @@ module Xcov
|
|
101
105
|
type: String,
|
102
106
|
optional: true
|
103
107
|
),
|
108
|
+
FastlaneCore::ConfigItem.new(
|
109
|
+
key: :use_system_scm,
|
110
|
+
env_name: "XCOV_USE_SYSTEM_SCM",
|
111
|
+
description: "Lets xcodebuild use system's scm configuration",
|
112
|
+
optional: true,
|
113
|
+
is_string: false,
|
114
|
+
default_value: false
|
115
|
+
),
|
116
|
+
FastlaneCore::ConfigItem.new(
|
117
|
+
key: :is_swift_package,
|
118
|
+
env_name: "XCOV_IS_SWIFT_PACKAGE",
|
119
|
+
description: "Enables generating coverage reports for Package.swift derived projects",
|
120
|
+
optional: true,
|
121
|
+
is_string: false,
|
122
|
+
default_value: false
|
123
|
+
),
|
104
124
|
|
105
125
|
# Report options
|
106
126
|
FastlaneCore::ConfigItem.new(
|
@@ -189,6 +209,13 @@ module Xcov
|
|
189
209
|
is_string: false,
|
190
210
|
default_value: false
|
191
211
|
),
|
212
|
+
FastlaneCore::ConfigItem.new(
|
213
|
+
key: :include_zero_targets,
|
214
|
+
env_name: "XCOV_INCLUDE_ZERO_TARGETS",
|
215
|
+
description: "Final report will include target even if the coverage is 0%",
|
216
|
+
is_string: false,
|
217
|
+
default_value: true
|
218
|
+
),
|
192
219
|
FastlaneCore::ConfigItem.new(
|
193
220
|
key: :exclude_targets,
|
194
221
|
optional: true,
|
data/lib/xcov/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcov
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Vidal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fastlane
|
@@ -142,6 +142,20 @@ dependencies:
|
|
142
142
|
- - ">="
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: rspec
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
145
159
|
description: xcov is a friendly visualizer for Xcode's code coverage files
|
146
160
|
email:
|
147
161
|
- nakioparkour@gmail.com
|
@@ -209,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
223
|
- !ruby/object:Gem::Version
|
210
224
|
version: '0'
|
211
225
|
requirements: []
|
212
|
-
rubygems_version: 3.
|
226
|
+
rubygems_version: 3.2.3
|
213
227
|
signing_key:
|
214
228
|
specification_version: 4
|
215
229
|
summary: xcov is a friendly visualizer for Xcode's code coverage files
|