highway 0.0.1 → 1.0.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 +7 -0
- data/lib/highway.rb +8 -4
- data/lib/highway/compiler/analyze/analyzer.rb +249 -0
- data/lib/highway/compiler/analyze/tree/root.rb +95 -0
- data/lib/highway/compiler/analyze/tree/segments/text.rb +36 -0
- data/lib/highway/compiler/analyze/tree/segments/variable.rb +43 -0
- data/lib/highway/compiler/analyze/tree/stage.rb +48 -0
- data/lib/highway/compiler/analyze/tree/step.rb +69 -0
- data/lib/highway/compiler/analyze/tree/values/array.rb +45 -0
- data/lib/highway/compiler/analyze/tree/values/base.rb +67 -0
- data/lib/highway/compiler/analyze/tree/values/hash.rb +45 -0
- data/lib/highway/compiler/analyze/tree/values/primitive.rb +43 -0
- data/lib/highway/compiler/analyze/tree/variable.rb +48 -0
- data/lib/highway/compiler/build/builder.rb +154 -0
- data/lib/highway/compiler/build/output/invocation.rb +70 -0
- data/lib/highway/compiler/build/output/manifest.rb +52 -0
- data/lib/highway/compiler/parse/parser.rb +92 -0
- data/lib/highway/compiler/parse/tree/root.rb +73 -0
- data/lib/highway/compiler/parse/tree/step.rb +62 -0
- data/lib/highway/compiler/parse/tree/variable.rb +48 -0
- data/lib/highway/compiler/parse/versions/v1.rb +110 -0
- data/lib/highway/compiler/suite.rb +56 -0
- data/lib/highway/environment.rb +282 -0
- data/lib/highway/fastlane/action.rb +67 -0
- data/lib/highway/interface.rb +135 -0
- data/lib/highway/main.rb +173 -0
- data/lib/highway/runtime/context.rb +229 -0
- data/lib/highway/runtime/report.rb +80 -0
- data/lib/highway/runtime/runner.rb +286 -0
- data/lib/highway/steps/infrastructure.rb +20 -0
- data/lib/highway/steps/library/action.rb +42 -0
- data/lib/highway/steps/library/appcenter.rb +106 -0
- data/lib/highway/steps/library/appstore.rb +137 -0
- data/lib/highway/steps/library/carthage.rb +67 -0
- data/lib/highway/steps/library/cocoapods.rb +76 -0
- data/lib/highway/steps/library/copy_artifacts.rb +36 -0
- data/lib/highway/steps/library/lane.rb +42 -0
- data/lib/highway/steps/library/sh.rb +36 -0
- data/lib/highway/steps/library/slack.rb +381 -0
- data/lib/highway/steps/library/testflight.rb +105 -0
- data/lib/highway/steps/library/xcode_archive.rb +162 -0
- data/lib/highway/steps/library/xcode_test.rb +264 -0
- data/lib/highway/steps/parameters/base.rb +52 -0
- data/lib/highway/steps/parameters/compound.rb +141 -0
- data/lib/highway/steps/parameters/single.rb +74 -0
- data/lib/highway/steps/registry.rb +92 -0
- data/lib/highway/steps/step.rb +52 -0
- data/lib/highway/steps/types/any.rb +65 -0
- data/lib/highway/steps/types/anyof.rb +64 -0
- data/lib/highway/steps/types/array.rb +44 -0
- data/lib/highway/steps/types/bool.rb +36 -0
- data/lib/highway/steps/types/enum.rb +44 -0
- data/lib/highway/steps/types/hash.rb +45 -0
- data/lib/highway/steps/types/number.rb +38 -0
- data/lib/highway/steps/types/set.rb +39 -0
- data/lib/highway/steps/types/string.rb +47 -0
- data/lib/highway/steps/types/url.rb +35 -0
- data/lib/highway/utilities.rb +51 -0
- data/lib/highway/version.rb +9 -1
- metadata +194 -22
- data/.gitignore +0 -4
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/highway.gemspec +0 -24
@@ -0,0 +1,105 @@
|
|
1
|
+
#
|
2
|
+
# testflight.rb
|
3
|
+
# Copyright © 2019 Netguru S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
require "fastlane"
|
7
|
+
|
8
|
+
require "highway/steps/infrastructure"
|
9
|
+
|
10
|
+
module Highway
|
11
|
+
module Steps
|
12
|
+
module Library
|
13
|
+
|
14
|
+
class TestFlightStep < Step
|
15
|
+
|
16
|
+
def self.name
|
17
|
+
"testflight"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parameters
|
21
|
+
[
|
22
|
+
Parameters::Single.new(
|
23
|
+
name: "apple_id",
|
24
|
+
required: true,
|
25
|
+
type: Types::String.new()
|
26
|
+
),
|
27
|
+
Parameters::Single.new(
|
28
|
+
name: "app_specific_password",
|
29
|
+
required: false,
|
30
|
+
type: Types::String.new()
|
31
|
+
),
|
32
|
+
Parameters::Single.new(
|
33
|
+
name: "password",
|
34
|
+
required: false,
|
35
|
+
type: Types::String.new()
|
36
|
+
),
|
37
|
+
Parameters::Single.new(
|
38
|
+
name: "session",
|
39
|
+
required: false,
|
40
|
+
type: Types::String.new()
|
41
|
+
),
|
42
|
+
Parameters::Single.new(
|
43
|
+
name: "skip_submission",
|
44
|
+
required: false,
|
45
|
+
default: true,
|
46
|
+
type: Types::Bool.new()
|
47
|
+
),
|
48
|
+
Parameters::Single.new(
|
49
|
+
name: "skip_waiting_for_build_processing",
|
50
|
+
required: false,
|
51
|
+
default: true,
|
52
|
+
type: Types::Bool.new()
|
53
|
+
),
|
54
|
+
Parameters::Single.new(
|
55
|
+
name: "team_name",
|
56
|
+
required: false,
|
57
|
+
type: Types::String.new()
|
58
|
+
),
|
59
|
+
Parameters::Single.new(
|
60
|
+
name: "username",
|
61
|
+
required: true,
|
62
|
+
type: Types::String.regex(/^\S+@\S+\.\S+$/)
|
63
|
+
)
|
64
|
+
]
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.run(parameters:, context:, report:)
|
68
|
+
|
69
|
+
password = parameters["password"]
|
70
|
+
app_specific_password = parameters["app_specific_password"]
|
71
|
+
session = parameters["session"]
|
72
|
+
|
73
|
+
if password.nil? && app_specific_password.nil?
|
74
|
+
context.interface.fatal!("You need to provide an account password or application specific password! Additionally if you have enabled two-step verification, you will need to provide generated session.")
|
75
|
+
end
|
76
|
+
|
77
|
+
username = parameters["username"]
|
78
|
+
apple_id = parameters["apple_id"]
|
79
|
+
team_name = parameters["team_name"]
|
80
|
+
skip_submission = parameters["skip_submission"]
|
81
|
+
skip_waiting_for_build_processing = parameters["skip_waiting_for_build_processing"]
|
82
|
+
|
83
|
+
env = {
|
84
|
+
"FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD" => app_specific_password,
|
85
|
+
"FASTLANE_PASSWORD" => password,
|
86
|
+
"FASTLANE_SESSION" => session
|
87
|
+
}
|
88
|
+
|
89
|
+
context.with_modified_env(env) {
|
90
|
+
context.run_action("upload_to_testflight", options: {
|
91
|
+
username: username,
|
92
|
+
skip_submission: skip_submission,
|
93
|
+
skip_waiting_for_build_processing: skip_waiting_for_build_processing,
|
94
|
+
apple_id: apple_id,
|
95
|
+
team_name: team_name
|
96
|
+
})
|
97
|
+
}
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#
|
2
|
+
# xcode_archive.rb
|
3
|
+
# Copyright © 2019 Netguru S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
require "fastlane"
|
7
|
+
require "xcodeproj"
|
8
|
+
|
9
|
+
require "highway/steps/infrastructure"
|
10
|
+
|
11
|
+
module Highway
|
12
|
+
module Steps
|
13
|
+
module Library
|
14
|
+
|
15
|
+
class XcodeArchiveStep < Step
|
16
|
+
|
17
|
+
def self.name
|
18
|
+
"xcode_archive"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.parameters
|
22
|
+
[
|
23
|
+
Parameters::Single.new(
|
24
|
+
name: "clean",
|
25
|
+
required: false,
|
26
|
+
type: Types::Bool.new(),
|
27
|
+
default: true,
|
28
|
+
),
|
29
|
+
Parameters::Single.new(
|
30
|
+
name: "configuration",
|
31
|
+
required: false,
|
32
|
+
type: Types::String.new(),
|
33
|
+
),
|
34
|
+
Parameters::Single.new(
|
35
|
+
name: "flags",
|
36
|
+
required: false,
|
37
|
+
type: Types::Array.new(Types::String.new()),
|
38
|
+
default: [],
|
39
|
+
),
|
40
|
+
Parameters::Single.new(
|
41
|
+
name: "method",
|
42
|
+
required: true,
|
43
|
+
type: Types::Enum.new("ad-hoc", "app-store", "development", "developer-id", "enterprise", "package"),
|
44
|
+
),
|
45
|
+
Parameters::Single.new(
|
46
|
+
name: "project",
|
47
|
+
required: true,
|
48
|
+
type: Types::AnyOf.new(
|
49
|
+
project: Types::String.regex(/.+\.xcodeproj/),
|
50
|
+
workspace: Types::String.regex(/.+\.xcworkspace/),
|
51
|
+
),
|
52
|
+
),
|
53
|
+
Parameters::Single.new(
|
54
|
+
name: "scheme",
|
55
|
+
required: true,
|
56
|
+
type: Types::String.new(),
|
57
|
+
),
|
58
|
+
Parameters::Single.new(
|
59
|
+
name: "settings",
|
60
|
+
required: false,
|
61
|
+
type: Types::Hash.new(Types::String.new(), validate: lambda { |dict| dict.keys.all? { |key| /[A-Z_][A-Z0-9_]*/ =~ key } }),
|
62
|
+
default: {},
|
63
|
+
),
|
64
|
+
]
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.run(parameters:, context:, report:)
|
68
|
+
|
69
|
+
# Interpret the parameters. At this point they are parsed and
|
70
|
+
# transformed to be recognizable by Fastlane.
|
71
|
+
|
72
|
+
clean = parameters["clean"]
|
73
|
+
scheme = parameters["scheme"]
|
74
|
+
method = parameters["method"]
|
75
|
+
|
76
|
+
configuration = parameters["configuration"]
|
77
|
+
configuration ||= detect_configuration(parameters)
|
78
|
+
|
79
|
+
flags = parameters["flags"].join(" ")
|
80
|
+
settings = parameters["settings"].map { |setting, value| "#{setting}=\"#{value.shellescape}\"" }.join(" ")
|
81
|
+
|
82
|
+
xcargs = flags + settings
|
83
|
+
xcargs = nil if xcargs.empty?
|
84
|
+
|
85
|
+
project_key = parameters["project"][:tag]
|
86
|
+
project_value = parameters["project"][:value]
|
87
|
+
|
88
|
+
# Prepare artifacts. Create temporary directories, get file names that
|
89
|
+
# will be later passed to the build command.
|
90
|
+
|
91
|
+
output_raw_temp_dir = Dir.mktmpdir()
|
92
|
+
output_raw_path = report.prepare_artifact("raw.log")
|
93
|
+
|
94
|
+
output_ipa_path = report.prepare_artifact("archive.ipa")
|
95
|
+
output_ipa_dir = File.dirname(output_ipa_path)
|
96
|
+
output_ipa_file = File.basename(output_ipa_path)
|
97
|
+
|
98
|
+
# Run the build and archival.
|
99
|
+
|
100
|
+
context.run_action("build_ios_app", options: {
|
101
|
+
|
102
|
+
project_key => project_value,
|
103
|
+
|
104
|
+
clean: clean,
|
105
|
+
configuration: configuration,
|
106
|
+
scheme: scheme,
|
107
|
+
export_method: method,
|
108
|
+
|
109
|
+
xcargs: xcargs,
|
110
|
+
export_xcargs: xcargs,
|
111
|
+
|
112
|
+
buildlog_path: output_raw_temp_dir,
|
113
|
+
output_directory: output_ipa_dir,
|
114
|
+
output_name: output_ipa_file,
|
115
|
+
|
116
|
+
})
|
117
|
+
|
118
|
+
# Save the archive and artifacts subreports in the report.
|
119
|
+
|
120
|
+
report[:archive] = {
|
121
|
+
result: :success
|
122
|
+
}
|
123
|
+
|
124
|
+
report[:artifacts] = {
|
125
|
+
ipa: context.fastlane_lane_context[:IPA_OUTPUT_PATH],
|
126
|
+
dsym: context.fastlane_lane_context[:DSYM_OUTPUT_PATH],
|
127
|
+
}
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
def self.detect_configuration(parameters)
|
134
|
+
if parameters["project"][:tag] == :project
|
135
|
+
detect_configuration_from_project(parameters["project"][:value], parameters["scheme"])
|
136
|
+
elsif parameters["project"][:tag] == :workspace
|
137
|
+
detect_configuration_from_workspace(parameters["project"][:value], parameters["scheme"])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.detect_configuration_from_project(project_path, scheme_name)
|
142
|
+
return nil unless File.exist?(project_path)
|
143
|
+
project_schemes = Xcodeproj::Project.schemes(project_path)
|
144
|
+
return nil unless project_schemes.include?(scheme_name)
|
145
|
+
scheme_path = File.join(project_path, "xcshareddata", "xcschemes", "#{scheme_name}.xcscheme")
|
146
|
+
return nil unless File.exist?(scheme_path)
|
147
|
+
Xcodeproj::XCScheme.new(scheme_path).archive_action.build_configuration
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.detect_configuration_from_workspace(workspace_path, scheme_name)
|
151
|
+
return nil unless File.exist?(workspace_path)
|
152
|
+
workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path)
|
153
|
+
workspace_schemes = workspace.schemes.reject { |k, v| v.include?("Pods/Pods.xcodeproj") }
|
154
|
+
return nil unless workspace_schemes.keys.include?(scheme_name)
|
155
|
+
detect_configuration_from_project(workspace_schemes[scheme_name], scheme_name)
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
#
|
2
|
+
# xcode_test.rb
|
3
|
+
# Copyright © 2019 Netguru S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
require "highway/steps/infrastructure"
|
7
|
+
|
8
|
+
module Highway
|
9
|
+
module Steps
|
10
|
+
module Library
|
11
|
+
|
12
|
+
class XcodeTestStep < Step
|
13
|
+
|
14
|
+
def self.name
|
15
|
+
"xcode_test"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.parameters
|
19
|
+
[
|
20
|
+
Parameters::Single.new(
|
21
|
+
name: "clean",
|
22
|
+
type: Types::Bool.new(),
|
23
|
+
required: false,
|
24
|
+
default: true,
|
25
|
+
),
|
26
|
+
Parameters::Single.new(
|
27
|
+
name: "configuration",
|
28
|
+
type: Types::String.new(),
|
29
|
+
required: false,
|
30
|
+
),
|
31
|
+
Parameters::Single.new(
|
32
|
+
name: "device",
|
33
|
+
type: Types::String.new(),
|
34
|
+
required: false,
|
35
|
+
),
|
36
|
+
Parameters::Single.new(
|
37
|
+
name: "flags",
|
38
|
+
type: Types::Array.new(Types::String.new()),
|
39
|
+
required: false,
|
40
|
+
default: [],
|
41
|
+
),
|
42
|
+
Parameters::Single.new(
|
43
|
+
name: "project",
|
44
|
+
type: Types::AnyOf.new(
|
45
|
+
project: Types::String.regex(/.+\.xcodeproj/),
|
46
|
+
workspace: Types::String.regex(/.+\.xcworkspace/),
|
47
|
+
),
|
48
|
+
required: true,
|
49
|
+
),
|
50
|
+
Parameters::Single.new(
|
51
|
+
name: "scheme",
|
52
|
+
type: Types::String.new(),
|
53
|
+
required: true,
|
54
|
+
),
|
55
|
+
Parameters::Single.new(
|
56
|
+
name: "skip_build",
|
57
|
+
type: Types::Bool.new(),
|
58
|
+
required: false,
|
59
|
+
default: false,
|
60
|
+
),
|
61
|
+
Parameters::Single.new(
|
62
|
+
name: "settings",
|
63
|
+
type: Types::Hash.new(Types::String.new(), validate: lambda { |dict| dict.keys.all? { |key| /[A-Z_][A-Z0-9_]*/ =~ key } }),
|
64
|
+
required: false,
|
65
|
+
default: {},
|
66
|
+
),
|
67
|
+
Parameters::Single.new(
|
68
|
+
name: "code_coverage",
|
69
|
+
type: Types::Bool.new(),
|
70
|
+
required: false,
|
71
|
+
)
|
72
|
+
]
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.run(parameters:, context:, report:)
|
76
|
+
|
77
|
+
# Interpret the parameters. At this point they are parsed and
|
78
|
+
# transformed to be recognizable by Fastlane.
|
79
|
+
|
80
|
+
clean = parameters["clean"]
|
81
|
+
configuration = parameters["configuration"]
|
82
|
+
device = parameters["device"]
|
83
|
+
scheme = parameters["scheme"]
|
84
|
+
skip_build = parameters["skip_build"]
|
85
|
+
code_coverage = parameters["code_coverage"]
|
86
|
+
|
87
|
+
flags = parameters["flags"].join(" ")
|
88
|
+
settings = parameters["settings"].map { |setting, value| "#{setting}=\"#{value.shellescape}\"" }.join(" ")
|
89
|
+
|
90
|
+
xcargs = flags + settings
|
91
|
+
xcargs = nil if xcargs.empty?
|
92
|
+
|
93
|
+
project_key = parameters["project"][:tag]
|
94
|
+
project_value = parameters["project"][:value]
|
95
|
+
|
96
|
+
# Prepare artifacts. Create temporary directories, get file names that
|
97
|
+
# will be later passed to the build command.
|
98
|
+
|
99
|
+
output_raw_temp_dir = Dir.mktmpdir()
|
100
|
+
output_raw_path = report.prepare_artifact("raw.log")
|
101
|
+
|
102
|
+
output_html_path = report.prepare_artifact("report.html")
|
103
|
+
output_junit_path = report.prepare_artifact("report.junit")
|
104
|
+
|
105
|
+
output_html_file = File.basename(output_html_path)
|
106
|
+
output_junit_file = File.basename(output_junit_path)
|
107
|
+
|
108
|
+
# Configure xcpretty. Set custom locations of report artifacts so that
|
109
|
+
# we can track them accurately.
|
110
|
+
|
111
|
+
output_dir = context.artifacts_dir
|
112
|
+
output_types = ["html", "junit"].join(",")
|
113
|
+
output_files = [output_html_file, output_junit_file].join(",")
|
114
|
+
|
115
|
+
# Prepare temporary variables.
|
116
|
+
|
117
|
+
report_test = {}
|
118
|
+
report_artifacts = {}
|
119
|
+
rescued_error = nil
|
120
|
+
|
121
|
+
# Run the build and test.
|
122
|
+
|
123
|
+
begin
|
124
|
+
|
125
|
+
context.run_action("run_tests", options: {
|
126
|
+
|
127
|
+
project_key => project_value,
|
128
|
+
|
129
|
+
clean: clean,
|
130
|
+
configuration: configuration,
|
131
|
+
device: device,
|
132
|
+
scheme: scheme,
|
133
|
+
code_coverage: code_coverage,
|
134
|
+
skip_build: skip_build,
|
135
|
+
|
136
|
+
xcargs: xcargs,
|
137
|
+
|
138
|
+
buildlog_path: output_raw_temp_dir,
|
139
|
+
output_directory: output_dir,
|
140
|
+
output_types: output_types,
|
141
|
+
output_files: output_files,
|
142
|
+
|
143
|
+
})
|
144
|
+
|
145
|
+
rescue FastlaneCore::Interface::FastlaneBuildFailure => error
|
146
|
+
|
147
|
+
# A compile error occured. Save it to be re-raised later.
|
148
|
+
|
149
|
+
report_test[:result] = :error
|
150
|
+
rescued_error = error
|
151
|
+
|
152
|
+
rescue FastlaneCore::Interface::FastlaneTestFailure => error
|
153
|
+
|
154
|
+
# A test failure occured. Save it to be re-raised later.
|
155
|
+
|
156
|
+
report_test[:result] = :failure
|
157
|
+
rescued_error = error
|
158
|
+
|
159
|
+
else
|
160
|
+
|
161
|
+
# Build succeeded!
|
162
|
+
|
163
|
+
report_test[:result] = :success
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
# Now the real fun begins. Move the raw xcodebuild log from temporary
|
168
|
+
# directory to artifacts directory.
|
169
|
+
|
170
|
+
output_raw_temp_path = Dir.glob(File.join(output_raw_temp_dir, "*.log")).first
|
171
|
+
unless output_raw_temp_path.nil?
|
172
|
+
FileUtils.mv(output_raw_temp_path, output_raw_path)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Save the artifact paths in the subreport.
|
176
|
+
|
177
|
+
report_artifacts[:raw] = output_raw_path
|
178
|
+
report_artifacts[:html] = output_html_path
|
179
|
+
report_artifacts[:junit] = output_junit_path
|
180
|
+
|
181
|
+
# Load the raw log and pipe it through xcpretty with a JSON formatter.
|
182
|
+
# That will output a machine-readable information about everything
|
183
|
+
# that happened in the build.
|
184
|
+
|
185
|
+
xcpretty_json_formatter_path = context.run_sh("xcpretty-json-formatter", bundle_exec: true, silent: true)
|
186
|
+
temp_json_report_path = File.join(Dir.mktmpdir(), "report.json")
|
187
|
+
|
188
|
+
context.with_modified_env({"XCPRETTY_JSON_FILE_OUTPUT" => temp_json_report_path}) do
|
189
|
+
context.run_sh(["cat", output_raw_path, "| xcpretty --formatter", xcpretty_json_formatter_path], bundle_exec: true, silent: true)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Export JSON file report to environment variable
|
193
|
+
|
194
|
+
context.env["XCODE_TEST_JSON_REPORT_PATH"] = temp_json_report_path
|
195
|
+
|
196
|
+
# Load the build report and a JUnit report into memory.
|
197
|
+
|
198
|
+
junit_report = Scan::TestResultParser.new.parse_result(File.read(output_junit_path))
|
199
|
+
if File.exist?(temp_json_report_path)
|
200
|
+
xcode_report = JSON.parse(File.read(temp_json_report_path))
|
201
|
+
else
|
202
|
+
xcode_report = Hash.new()
|
203
|
+
end
|
204
|
+
|
205
|
+
# Extract test numbers from JUnit report.
|
206
|
+
|
207
|
+
report_test_count = {}
|
208
|
+
|
209
|
+
report_test_count[:all] = junit_report[:tests]
|
210
|
+
report_test_count[:failed] = junit_report[:failures]
|
211
|
+
report_test_count[:succeeded] = report_test_count[:all] - report_test_count[:failed]
|
212
|
+
|
213
|
+
report_test[:count] = report_test_count
|
214
|
+
|
215
|
+
# Extract compile errors from the build report.
|
216
|
+
|
217
|
+
report_test_errors = []
|
218
|
+
|
219
|
+
report_test_errors += xcode_report.fetch("file_missing_errors", []).map { |entry|
|
220
|
+
{location: File.basename(entry["file_path"]), reason: entry["reason"]}
|
221
|
+
}
|
222
|
+
|
223
|
+
report_test_errors += xcode_report.fetch("compile_errors", []).map { |entry|
|
224
|
+
{location: File.basename(entry["file_path"]), reason: entry["reason"]}
|
225
|
+
}
|
226
|
+
|
227
|
+
report_test_errors += xcode_report.fetch("undefined_symbols_errors", []).map { |entry|
|
228
|
+
{location: entry["symbol"], reason: entry["message"]}
|
229
|
+
}
|
230
|
+
|
231
|
+
report_test_errors += xcode_report.fetch("format_duplicate_symbols", []).map {
|
232
|
+
{location: nil, reason: entry["message"]}
|
233
|
+
}
|
234
|
+
|
235
|
+
report_test_errors += xcode_report.fetch("errors", []).map { |entry|
|
236
|
+
{location: nil, reason: entry}
|
237
|
+
}
|
238
|
+
|
239
|
+
report_test[:errors] = report_test_errors
|
240
|
+
|
241
|
+
# Extract test failures from the build report.
|
242
|
+
|
243
|
+
report_test_failures = xcode_report.fetch("tests_failures", {}).values.flatten.map { |entry|
|
244
|
+
{location: entry["test_case"], reason: entry["reason"]}
|
245
|
+
}
|
246
|
+
|
247
|
+
report_test[:failures] = report_test_failures
|
248
|
+
|
249
|
+
# Save the test and artifacts subreports in the report.
|
250
|
+
|
251
|
+
report[:test] = report_test
|
252
|
+
report[:artifacts] = report_artifacts
|
253
|
+
|
254
|
+
# Re-raise the error after the report is finally prepared.
|
255
|
+
|
256
|
+
raise rescued_error if rescued_error != nil
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|