diff --git a/trainer/lib/trainer/test_parser.rb b/trainer/lib/trainer/test_parser.rb index c973043d290..53ee61bbfe8 100644 --- a/trainer/lib/trainer/test_parser.rb +++ b/trainer/lib/trainer/test_parser.rb @@ -197,12 +197,37 @@ def execute_cmd(cmd) return output end + # Hotfix: From Xcode 16 beta 3 'xcresulttool get --format json' has been deprecated; + # '--legacy' flag required to keep on using the command + def generate_cmd_parse_xcresult(path) + xcresulttool_cmd = %W( + xcrun + xcresulttool + get + --format + json + --path + #{path} + ) + + # e.g. DEVELOPER_DIR=/Applications/Xcode_16_beta_3.app + # xcresulttool version 23021, format version 3.53 (current) + match = `xcrun xcresulttool version`.match(/xcresulttool version (?\d+),/) + version = match[:version]&.to_f + xcresulttool_cmd << '--legacy' if version >= 23_021.0 + + xcresulttool_cmd.join(' ') + end + def parse_xcresult(path, output_remove_retry_attempts: false) require 'shellwords' path = Shellwords.escape(path) # Executes xcresulttool to get JSON format of the result bundle object - result_bundle_object_raw = execute_cmd("xcrun xcresulttool get --format json --path #{path}") + # Hotfix: From Xcode 16 beta 3 'xcresulttool get --format json' has been deprecated; '--legacy' flag required to keep on using the command + xcresulttool_cmd = generate_cmd_parse_xcresult(path) + + result_bundle_object_raw = execute_cmd(xcresulttool_cmd) result_bundle_object = JSON.parse(result_bundle_object_raw) # Parses JSON into ActionsInvocationRecord to find a list of all ids for ActionTestPlanRunSummaries @@ -215,7 +240,7 @@ def parse_xcresult(path, output_remove_retry_attempts: false) # Maps ids into ActionTestPlanRunSummaries by executing xcresulttool to get JSON # containing specific information for each test summary, summaries = ids.map do |id| - raw = execute_cmd("xcrun xcresulttool get --format json --path #{path} --id #{id}") + raw = execute_cmd("#{xcresulttool_cmd} --id #{id}") json = JSON.parse(raw) Trainer::XCResult::ActionTestPlanRunSummaries.new(json) end diff --git a/trainer/spec/test_parser_spec.rb b/trainer/spec/test_parser_spec.rb index af977270a72..191d2a30e84 100644 --- a/trainer/spec/test_parser_spec.rb +++ b/trainer/spec/test_parser_spec.rb @@ -26,6 +26,35 @@ end end + describe "#generate_cmd_parse_xcresult" do + let(:xcresult_sample_path) { "./trainer/spec/fixtures/Test.test_result.xcresult" } + let!(:subject) { Trainer::TestParser.new(xcresult_sample_path) } + let(:command) { subject.send(:generate_cmd_parse_xcresult, xcresult_sample_path) } + + before do + allow(File).to receive(:expand_path).with(xcresult_sample_path).and_return(xcresult_sample_path) + allow_any_instance_of(Trainer::TestParser).to receive(:`).with('xcrun xcresulttool version').and_return(version) + end + + context 'with >= Xcode 16 beta 3' do + let(:version) { 'xcresulttool version 23021, format version 3.53 (current)' } + let(:expected) { "xcrun xcresulttool get --format json --path #{xcresult_sample_path} --legacy" } + + it 'should pass `--legacy`', requires_xcode: true do + expect(command).to eq(expected) + end + end + + context 'with < Xcode 16 beta 3' do + let(:version) { 'xcresulttool version 22608, format version 3.49 (current)' } + let(:expected) { "xcrun xcresulttool get --format json --path #{xcresult_sample_path}" } + + it 'should not pass `--legacy`', requires_xcode: true do + expect(command).to eq(expected) + end + end + end + describe "Stores the data in a useful format" do describe "#tests_successful?" do it "returns false if tests failed" do