Last active
March 5, 2021 01:32
-
-
Save zats/b532ed0730037c319494 to your computer and use it in GitHub Desktop.
Update all your plugins for the latest Xcode beta with a single
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env xcrun swift | |
// $ chmod +x script.swift | |
// $ ./script.swift | |
// or $ ./script.swift -xcode=/Applications/Xcode-beta.app | |
import Foundation | |
@noreturn private func failWithError(message: String) { | |
print("🚫 \(message)") | |
exit(EXIT_FAILURE) | |
} | |
private func warnWithMessage(message: String) { | |
print("⚠️ \(message)") | |
} | |
let xcodeCompatibilityUUIDKey = "DVTPlugInCompatibilityUUID" | |
let pluginCompatibilityUUIDsKey = "DVTPlugInCompatibilityUUIDs" | |
let xcodeArgumentPrefix = "-xcode=" | |
let arguments = Process.arguments | |
let xcodeArgument: String = arguments.filter{ $0.hasPrefix(xcodeArgumentPrefix) }.first ?? "\(xcodeArgumentPrefix)/Applications/Xcode.app" | |
let xcodePath = xcodeArgument.substringFromIndex(xcodeArgument.startIndex.advancedBy(xcodeArgumentPrefix.characters.count)) | |
let xcodeInfoURL = NSURL(fileURLWithPath: xcodePath).URLByAppendingPathComponent("Contents/Info.plist") | |
print("Xcode: \(xcodePath)") | |
let fileManager = NSFileManager.defaultManager() | |
// Xcode Info.plist | |
guard let dic = NSDictionary(contentsOfURL: xcodeInfoURL), compatibilityUUIDValue = dic[xcodeCompatibilityUUIDKey] as? String else { | |
failWithError("Failed to read \(xcodeCompatibilityUUIDKey) from \(xcodeInfoURL)") | |
} | |
print("DVTPlugInCompatibilityUUID: \(compatibilityUUIDValue)") | |
// Xcode plugins | |
let pluginsURL = NSURL(fileURLWithPath: ("~/Library/Application Support/Developer/Shared/Xcode/Plug-ins" as NSString).stringByExpandingTildeInPath) | |
guard let pluginURLs = try? fileManager.contentsOfDirectoryAtURL(pluginsURL, includingPropertiesForKeys: nil, options: [.SkipsSubdirectoryDescendants, .SkipsPackageDescendants]) else { | |
failWithError("No Xcode plugins found at \(pluginsURL)") | |
} | |
for pluginURL in pluginURLs { | |
if pluginURL.pathExtension != "xcplugin" { | |
continue | |
} | |
guard let pluginName = (pluginURL.lastPathComponent as NSString?)?.stringByDeletingPathExtension else { | |
continue | |
} | |
let pluginInfoPlistURL = pluginURL.URLByAppendingPathComponent("Contents/Info.plist") | |
guard var pluginInfoPlist = NSMutableDictionary(contentsOfURL: pluginInfoPlistURL) else { | |
warnWithMessage("Failed to read Info.plist at \(pluginInfoPlistURL)") | |
continue | |
} | |
// Updating DVTPlugInCompatibilityUUIDs section if needed | |
if pluginInfoPlist[pluginCompatibilityUUIDsKey] == nil { | |
pluginInfoPlist[pluginCompatibilityUUIDsKey] = [compatibilityUUIDValue] | |
} else if var compatibilityUUIDs = pluginInfoPlist[pluginCompatibilityUUIDsKey] as? [String] { | |
if compatibilityUUIDs.contains(compatibilityUUIDValue) { | |
print("\(pluginName) is already compatible") | |
continue | |
} | |
compatibilityUUIDs.append(compatibilityUUIDValue) | |
pluginInfoPlist[pluginCompatibilityUUIDsKey] = compatibilityUUIDs | |
} | |
guard let infoPlistData = try? NSPropertyListSerialization.dataWithPropertyList(pluginInfoPlist, format: .XMLFormat_v1_0, options: 0) else { | |
failWithError("Failed to write Info.plist at \(pluginInfoPlistURL)") | |
} | |
do { | |
try infoPlistData.writeToURL(pluginInfoPlistURL, options: [.DataWritingAtomic]) | |
print("\(pluginName) ✅") | |
} catch { | |
failWithError("Failed to write plugin Info plist at \(pluginInfoPlistURL)") | |
} | |
} | |
exit(EXIT_SUCCESS) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment