Reputation: 20815
After upgrading to Xcode 11.1
on MacOS Catalina running some commands such as git status
results in Xcode stating that a license must be agreed to. Obviously we could run git status
and grep
for some output but this seems sub-optimal.
Is there a programmatic way (using xcodebuild
for example) to check if the Xcode license needs to be accepted?
Upvotes: 4
Views: 1212
Reputation: 27126
Evaluate Agreed License
Running
defaults read /Library/Preferences/com.apple.dt.Xcode
should give something like:
{
IDELastGMLicenseAgreedTo = EA1647;
IDEXcodeVersionForAgreedToGMLicense = "11.3.1";
}
This can also be evaluated programmatically.
There are several ways to do this, one is to use a shell script, for example you could call it XcodeLicenseAccepted.sh and it will return 0 if the license for the currently installed version of Xcode is already accepted.
Xcode version
To get the version number of the currently installed Xcode, you can take a look at the output of:
xcodebuild -version
which should look something like this:
Xcode 11.3.1
Build version 11C505
XcodeLicenseAccepted.sh
#!/bin/sh
XCODE_VERSION=`xcodebuild -version | grep '^Xcode\s' | sed -E 's/^Xcode[[:space:]]+([0-9\.]+)/\1/'`
ACCEPTED_LICENSE_VERSION=`defaults read /Library/Preferences/com.apple.dt.Xcode 2> /dev/null | grep IDEXcodeVersionForAgreedToGMLicense | cut -d '"' -f 2`
if [ "$XCODE_VERSION" = "$ACCEPTED_LICENSE_VERSION" ]
then
exit 0 #success
else
exit 1
fi
Swift Program
Another possible solution would be to use a small Swift program instead, e.g.:
import Foundation
private var acceptedXcodeVersion: String {
var acceptedXcodeVersion = ""
let licensePlistPath = "/Library/Preferences/com.apple.dt.Xcode.plist"
if FileManager.default.fileExists(atPath: licensePlistPath) {
if let licenseInfo = NSDictionary(contentsOfFile: licensePlistPath) {
if let version = licenseInfo["IDEXcodeVersionForAgreedToGMLicense"] as? String {
acceptedXcodeVersion = version
}
}
}
return acceptedXcodeVersion
}
private var installedXcodeVersion: String {
let process = Process()
process.launchPath = "/bin/sh"
process.arguments = ["-c", "xcodebuild -version"]
let stdoutPipe = Pipe()
process.standardOutput = stdoutPipe
process.launch()
var version = ""
let output = stdoutPipe.fileHandleForReading.readDataToEndOfFile()
if let versionInfo = String(data: output, encoding: .utf8) {
let lines = versionInfo.split { $0.isNewline }
for line in lines {
let parts = line.split { $0 == " " }
if parts.count > 1 && parts[0] == "Xcode" {
version = String(parts[1])
}
}
}
process.waitUntilExit()
return version
}
exit(acceptedXcodeVersion == installedXcodeVersion ? 0 : 1)
Test
To demo the functionality of XcodeLicenseAccepted.sh one can also use a short shell script:
#!/bin/sh
./XcodeLicenseAccepted.sh
if [ $? -eq 0 ]
then
echo "xcode license already accepted"
else
echo "xcode license still needs to be accepted"
fi
Replace the call to XcodeLicenseAccepted.sh
with the Swift program to test the alternative solution.
Finally a screenshot how the result looks before and after accepting the Xcode license:
Upvotes: 8