Skip to content

Commit 98eb3e1

Browse files
gh-action-runnergh-action-runner
authored andcommitted
Squashed 'apollo-ios/' changes from 4d0845f9..4294a65b
4294a65b fix: Xcode 16.3 CLI installation (#623) git-subtree-dir: apollo-ios git-subtree-split: 4294a65b9ecacc26774e7f5c4ead531d38245e3d
1 parent dde2797 commit 98eb3e1

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

Plugins/InstallCLI/InstallCLIPluginCommand.swift

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import Foundation
22
import PackagePlugin
3+
import os
34

45
@main
56
struct InstallCLIPluginCommand: CommandPlugin {
67

8+
enum Error: Swift.Error {
9+
case CannotDetermineXcodeVersion
10+
}
11+
712
func performCommand(context: PackagePlugin.PluginContext, arguments: [String]) async throws {
813
let dependencies = context.package.dependencies
914
try dependencies.forEach { dep in
@@ -27,14 +32,69 @@ extension InstallCLIPluginCommand: XcodeCommandPlugin {
2732

2833
/// 👇 This entry point is called when operating on an Xcode project.
2934
func performCommand(context: XcodePluginContext, arguments: [String]) throws {
30-
print("Installing Apollo CLI Plugin to Xcode project \(context.xcodeProject.displayName)")
31-
let apolloPath = "\(context.pluginWorkDirectory)/../../checkouts/apollo-ios"
3235
let process = Process()
33-
let path = try context.tool(named: "sh").path
34-
process.executableURL = URL(fileURLWithPath: path.string)
35-
process.arguments = ["\(apolloPath)/scripts/download-cli.sh", context.xcodeProject.directory.string]
36+
let toolPath = try context.tool(named: "sh").path
37+
process.executableURL = URL(fileURLWithPath: toolPath.string)
38+
39+
let downloadScriptPath = try downloadScriptPath(context: context)
40+
process.arguments = [downloadScriptPath, context.xcodeProject.directory.string]
41+
42+
try process.run()
43+
process.waitUntilExit()
44+
}
45+
46+
/// Used to get the location of the CLI download script.
47+
///
48+
/// - Parameter context: Contextual information based on the plugin's stated intent and requirements.
49+
/// - Returns: The path to the download script used to fetch the CLI binary.
50+
private func downloadScriptPath(context: XcodePluginContext) throws -> String {
51+
let xcodeVersion = try xcodeVersion(context: context)
52+
let relativeScriptPath = "SourcePackages/checkouts/apollo-ios/scripts/download-cli.sh"
53+
let absoluteScriptPath: String
54+
55+
if xcodeVersion.lexicographicallyPrecedes("16.3") {
56+
absoluteScriptPath = "\(context.pluginWorkDirectory)/../../../\(relativeScriptPath)"
57+
} else {
58+
absoluteScriptPath = "\(context.pluginWorkDirectory)/../../../../\(relativeScriptPath)"
59+
}
60+
61+
return absoluteScriptPath
62+
}
63+
64+
/// Used to get a string representation of Xcode in the current toolchain.
65+
///
66+
/// - Parameter context: Contextual information based on the plugin's stated intent and requirements.
67+
/// - Returns: A string representation of the Xcode version.
68+
private func xcodeVersion(context: XcodePluginContext) throws -> String {
69+
let process = Process()
70+
let toolPath = try context.tool(named: "xcrun").path
71+
process.executableURL = URL(fileURLWithPath: toolPath.string)
72+
process.arguments = ["xcodebuild", "-version"]
73+
74+
let outputPipe = Pipe()
75+
process.standardOutput = outputPipe
76+
3677
try process.run()
3778
process.waitUntilExit()
79+
80+
guard
81+
let outputData = try outputPipe.fileHandleForReading.readToEnd(),
82+
let output = String(data: outputData, encoding: .utf8)
83+
else {
84+
throw Error.CannotDetermineXcodeVersion
85+
}
86+
87+
let xcodeVersionString = output.components(separatedBy: "\n")[0]
88+
guard !xcodeVersionString.isEmpty else {
89+
throw Error.CannotDetermineXcodeVersion
90+
}
91+
92+
let versionString = xcodeVersionString
93+
.components(separatedBy: CharacterSet.decimalDigits.inverted)
94+
.compactMap({ $0.isEmpty ? nil : $0 })
95+
.joined(separator: ".")
96+
97+
return versionString
3898
}
3999

40100
}

0 commit comments

Comments
 (0)