Add xcodeVersionFromXcodeBuild

This commit is contained in:
Michael B. Gale
2026-10-30 16:14:50 +00:00
parent 8f2596eca1
commit efea0445d3
5 changed files with 233 additions and 7 deletions

View File

@@ -115,6 +115,76 @@ export function xcodeVersionFromLink(
}
}
/**
* Tries to determine the version of Xcode that is installed by running `xcrun xcodebuild -version`.
*
* @param logger The logger to use.
* @returns The Xcode version or `undefined` if it couldn't be determined.
*/
export async function xcodeVersionFromXcodeBuild(
logger: Logger,
): Promise<semver.SemVer | undefined> {
try {
const xcrun = await io.which("xcrun", true);
let stdout = "";
let stderr = "";
const exitCode = await new toolrunner.ToolRunner(
xcrun,
["xcodebuild", "-version"],
{
silent: true,
ignoreReturnCode: true,
listeners: {
stdout: (data: Buffer) => {
stdout += data.toString("utf-8");
},
stderr: (data: Buffer) => {
stderr += data.toString("utf-8");
},
},
},
).exec();
if (exitCode !== 0) {
logger.debug(`xcodebuild returned exit code ${exitCode}`);
logger.debug(`stdout:\n${stdout}`);
logger.debug(`stderr:\n${stderr}`);
return undefined;
}
// The output contains a couple of lines, but we only care about the product version.
const match = stdout.match(/^Xcode (\d+(\.\d+)?)/);
if (match === null) {
logger.debug(
`Output doesn't appear to contain the Xcode product version.`,
);
logger.debug(`stdout:\n${stdout}`);
logger.debug(`stderr:\n${stderr}`);
return undefined;
}
// We expect the output to only be a version string. Try to parse it into a semver.
const version = semver.coerce(match[1].trim());
if (version === null) {
logger.debug(
`xcodebuild's output couldn't be parsed as a version:\n${stdout}`,
);
logger.debug(`stderr:\n${stderr}`);
return undefined;
}
return version;
} catch (err) {
logger.debug(
`Unable to determine Xcode version from xcodebuild: ${getErrorMessage(err)}`,
);
return undefined;
}
}
/**
* Tries to determine the version of Xcode that is installed by running `xcrun --sdk macosx --show-sdk-version`.
*