Skip to content

Fix to parse xcresulttool version when the version string has major.minor format #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Sources/XCParseCore/String+Tokenizer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// String+Tokenizer.swift
// xcparse
//
// Created by Suman Cherukuri on 7/11/25.
//


/// https://stackoverflow.com/a/64108233
extension String {
func before(first delimiter: Character) -> String {
if let index = firstIndex(of: delimiter) {
let before = prefix(upTo: index)
return String(before)
}
return ""
}

func after(first delimiter: Character) -> String {
if let index = firstIndex(of: delimiter) {
let after = suffix(from: index).dropFirst()
return String(after)
}
return ""
}
}
16 changes: 12 additions & 4 deletions Sources/XCParseCore/Version+XCPTooling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,32 @@ public extension Version {
let xcresultVersionString = try xcresulttoolVersionResult.utf8Output()

let components = xcresultVersionString.components(separatedBy: CharacterSet(charactersIn: ",\n"))
var xcresulttoolVersion: Version?

for string in components {
let trimmedString = string.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmedString.hasPrefix("xcresulttool version ") {
let xcresulttoolVersionString = trimmedString.replacingOccurrences(of: "xcresulttool version ", with: "")
// Check to see if we can convert it to a number
var xcresulttoolVersion: Version?

if let xcresulttoolVersionInt = Int(xcresulttoolVersionString) {
xcresulttoolVersion = Version(xcresulttoolVersionInt, 0, 0)
} else {
xcresulttoolVersion = Version(string: xcresulttoolVersionString)
}

return xcresulttoolVersion
// on some Xcode versions (for example Xcode 26 beta 2),xcresulttoolVersion is coming in as 24038.1
let cleanedVersionString = xcresulttoolVersionString.before(first: ".")
if let cleanedVersionInt = Int(cleanedVersionString) {
xcresulttoolVersion = Version(cleanedVersionInt, 0, 0)
}
}
}

return nil
if xcresulttoolVersion == nil {
print("Failed to parse xcresulttool version: \(xcresultVersionString)")
}
return xcresulttoolVersion

} catch {
print("Failed to parse xcresulttool version with error: \(error)")
return nil
Expand Down
14 changes: 9 additions & 5 deletions xcparse.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/* End PBXAggregateTarget section */

/* Begin PBXBuildFile section */
254333312E21B41700E99D33 /* String+Tokenizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 254333302E21B41700E99D33 /* String+Tokenizer.swift */; };
62525EAE2376350100472F82 /* Version+XCPTooling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62525EAD2376350100472F82 /* Version+XCPTooling.swift */; };
62CC363E23553EA0003C7B68 /* XCResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CC363D23553EA0003C7B68 /* XCResult.swift */; };
62CC36592357C110003C7B68 /* AttachmentsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62CC36582357C110003C7B68 /* AttachmentsCommand.swift */; };
Expand Down Expand Up @@ -328,6 +329,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
254333302E21B41700E99D33 /* String+Tokenizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Tokenizer.swift"; sourceTree = "<group>"; };
62525EAD2376350100472F82 /* Version+XCPTooling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Version+XCPTooling.swift"; sourceTree = "<group>"; };
62CC363D23553EA0003C7B68 /* XCResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCResult.swift; sourceTree = "<group>"; };
62CC36582357C110003C7B68 /* AttachmentsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentsCommand.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -908,6 +910,9 @@
OBJ_13 /* ActionResult.swift */,
OBJ_14 /* ActionRunDestinationRecord.swift */,
OBJ_15 /* ActionSDKRecord.swift */,
OBJ_27 /* ActionsInvocationMetadata.swift */,
OBJ_28 /* ActionsInvocationRecord.swift */,
OBJ_26 /* ActionTestableSummary.swift */,
OBJ_16 /* ActionTestActivitySummary.swift */,
OBJ_17 /* ActionTestAttachment.swift */,
OBJ_18 /* ActionTestFailureSummary.swift */,
Expand All @@ -918,9 +923,6 @@
OBJ_23 /* ActionTestSummary.swift */,
OBJ_24 /* ActionTestSummaryGroup.swift */,
OBJ_25 /* ActionTestSummaryIdentifiableObject.swift */,
OBJ_26 /* ActionTestableSummary.swift */,
OBJ_27 /* ActionsInvocationMetadata.swift */,
OBJ_28 /* ActionsInvocationRecord.swift */,
OBJ_29 /* ActivityLogAnalyzerControlFlowStep.swift */,
OBJ_30 /* ActivityLogAnalyzerControlFlowStepEdge.swift */,
OBJ_31 /* ActivityLogAnalyzerEventStep.swift */,
Expand All @@ -944,12 +946,13 @@
OBJ_49 /* Reference.swift */,
OBJ_50 /* ResultIssueSummaries.swift */,
OBJ_51 /* ResultMetrics.swift */,
254333302E21B41700E99D33 /* String+Tokenizer.swift */,
OBJ_52 /* TestFailureIssueSummary.swift */,
OBJ_53 /* TypeDefinition.swift */,
OBJ_54 /* XCPResultDecoding.swift */,
62525EAD2376350100472F82 /* Version+XCPTooling.swift */,
OBJ_55 /* XCResultToolCommand.swift */,
OBJ_54 /* XCPResultDecoding.swift */,
62CC363D23553EA0003C7B68 /* XCResult.swift */,
OBJ_55 /* XCResultToolCommand.swift */,
);
name = XCParseCore;
path = Sources/XCParseCore;
Expand Down Expand Up @@ -1276,6 +1279,7 @@
OBJ_300 /* ActivityLogAnalyzerControlFlowStepEdge.swift in Sources */,
OBJ_301 /* ActivityLogAnalyzerEventStep.swift in Sources */,
OBJ_302 /* ActivityLogAnalyzerResultMessage.swift in Sources */,
254333312E21B41700E99D33 /* String+Tokenizer.swift in Sources */,
OBJ_303 /* ActivityLogAnalyzerStep.swift in Sources */,
OBJ_304 /* ActivityLogAnalyzerWarningMessage.swift in Sources */,
OBJ_305 /* ActivityLogCommandInvocationSection.swift in Sources */,
Expand Down