Files
element-x-ios/Tools/XcodeGen/normalizeSchemes.swift
T
Stefan Ceriu 11651bcd23 Normalize generated schemes to match Xcode's output
XcodeGen (through XcodeProj) serializes schemes slightly differently to
Xcode, so Xcode rewrites them as soon as it touches them (running tests,
switching test plans, opening the scheme editor), leaving recurring local
changes behind.

Add a small Swift script, run from XcodeGen's postGenCommand, that rewrites
the generated schemes the way Xcode saves them: it drops default-valued
attributes and empty CommandLineArguments, orders TestPlanReference
attributes, and moves TestPlans to the end of the TestAction, omitting the
redundant empty Testables.

Regenerated schemes are byte-identical to the copies saved by Xcode. The
script can be removed once https://github.com/tuist/XcodeProj/pull/1189
ships in XcodeGen.
2026-10-15 12:54:48 +03:00

28 lines
1.4 KiB
Swift

import Foundation
// XcodeGen (via XcodeProj) serializes schemes slightly differently to Xcode, so Xcode
// rewrites them as soon as it touches them. Match Xcode's output to avoid the churn.
// Remove once https://github.com/tuist/XcodeProj/pull/1189 ships in XcodeGen.
let schemesDirectory = URL(filePath: CommandLine.arguments[1])
for url in try FileManager.default.contentsOfDirectory(at: schemesDirectory, includingPropertiesForKeys: nil)
where url.pathExtension == "xcscheme" {
var scheme = try String(contentsOf: url, encoding: .utf8)
scheme.replace(#/"\s*(runPostActionsOnFailure|onlyGenerateCoverageForSpecifiedTargets) = "NO">/#, with: "\">")
scheme.replace(#/\s*<CommandLineArguments>\s*<\/CommandLineArguments>/#, with: "")
scheme.replace(#/default = (?<value>"[^"]*")(?<indent>\s*)reference = (?<reference>"[^"]*")/#) { match in
"reference = \(match.reference)\(match.indent)default = \(match.value)"
}
// Xcode writes test plans last and omits the then redundant empty testables.
if let testPlans = scheme.firstMatch(of: #/\s*<TestPlans>.*?<\/TestPlans>/#.dotMatchesNewlines()) {
scheme.removeSubrange(testPlans.range)
scheme.replace(#/\s*<Testables>\s*<\/Testables>/#, with: "")
scheme.replace(#/\s*<\/TestAction>/#) { testPlans.output + $0.output }
}
try scheme.write(to: url, atomically: true, encoding: .utf8)
}