Remove unnecessary lstatSync call

This commit is contained in:
Michael B. Gale
2026-10-30 11:24:30 +00:00
parent c6cc137b27
commit f583e03df6
4 changed files with 16 additions and 139 deletions

15
lib/entry-points.js generated
View File

@@ -183450,21 +183450,8 @@ var XCODE_APP_FILENAME_PATTERN = new RegExp(
);
function xcodeVersion(logger2) {
try {
const stats = import_fs.default.lstatSync(XCODE_SELECT_LINK_PATH, {
throwIfNoEntry: false
});
if (stats === void 0) {
logger2.debug(`'${XCODE_SELECT_LINK_PATH}' does not exist.`);
return void 0;
}
if (!stats.isSymbolicLink()) {
logger2.debug(
`${XCODE_SELECT_LINK_PATH} exists, but is not a symbolic link.`
);
return void 0;
}
const xcodePath = import_fs.default.readlinkSync(XCODE_SELECT_LINK_PATH);
if (xcodePath === "") {
if (xcodePath.trim() === "") {
logger2.debug(
`Resolving ${XCODE_SELECT_LINK_PATH} unexpectedly returned nothing.`
);

View File

@@ -386,9 +386,6 @@ test.serial(
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const features = createFeatures([Feature.CheckUnsupportedTracedAnalysis]);
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_26.0.app/Contents/Developer");
@@ -418,11 +415,6 @@ test.serial(
codeql,
);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
@@ -444,9 +436,6 @@ test.serial(
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const features = createFeatures([Feature.CheckUnsupportedTracedAnalysis]);
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_27.0.app/Contents/Developer");
@@ -476,11 +465,6 @@ test.serial(
codeql,
);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
@@ -521,9 +505,6 @@ test.serial(
const env = getTestEnv();
env.set(ActionsEnvVars.RUNNER_TEMP, tmpDir);
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_27.0.app/Contents/Developer");
@@ -560,11 +541,6 @@ test.serial(
),
);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);

View File

@@ -74,53 +74,32 @@ test("darwinVersion returns semver if parsing succeeds", (t) => {
test.serial("xcodeVersion returns undefined if symlink doesn't exist", (t) => {
const logger = new RecordingLogger();
const lstatSync = sinon.stub(fs, "lstatSync").returns(undefined);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.throws(new Error("ENOENT: no such file or directory"));
t.is(xcodeVersion(logger), undefined);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"'/private/var/db/xcode_select_link' does not exist",
]);
});
test.serial("xcodeVersion returns undefined if lstatSync throws", (t) => {
const logger = new RecordingLogger();
const lstatSync = sinon.stub(fs, "lstatSync").throws(new Error("ENOENT"));
t.is(xcodeVersion(logger), undefined);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
checkExpectedLogMessages(t, logger.messages, [
"Unable to determine Xcode version: ENOENT",
"Unable to determine Xcode version: ENOENT: no such file or directory",
]);
});
test.serial("xcodeVersion returns undefined if file is not a symlink", (t) => {
const logger = new RecordingLogger();
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => false } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.throws(new Error("EINVAL: invalid argument"));
t.is(xcodeVersion(logger), undefined);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
checkExpectedLogMessages(t, logger.messages, [
"exists, but is not a symbolic link",
"Unable to determine Xcode version: EINVAL: invalid argument",
]);
});
@@ -129,17 +108,9 @@ test.serial(
(t) => {
const logger = new RecordingLogger();
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon.stub(fs, "readlinkSync").returns("");
t.is(xcodeVersion(logger), undefined);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
@@ -154,19 +125,11 @@ test.serial(
(t) => {
const logger = new RecordingLogger();
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode.app/Contents/Developer");
t.is(xcodeVersion(logger), undefined);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
@@ -179,19 +142,11 @@ test.serial(
test.serial("xcodeVersion returns undefined if match can't be parsed", (t) => {
const logger = new RecordingLogger();
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_00.0.app/Contents/Developer");
t.is(xcodeVersion(logger), undefined);
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
@@ -203,9 +158,6 @@ test.serial("xcodeVersion returns undefined if match can't be parsed", (t) => {
test.serial("xcodeVersion returns version from resolved path", (t) => {
const logger = new RecordingLogger();
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_16.4.app/Contents/Developer");
@@ -217,11 +169,6 @@ test.serial("xcodeVersion returns version from resolved path", (t) => {
t.is(result.minor, 4);
}
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
});
@@ -229,9 +176,6 @@ test.serial("xcodeVersion returns version from resolved path", (t) => {
test.serial("xcodeVersion returns major version from resolved path", (t) => {
const logger = new RecordingLogger();
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_16.app/Contents/Developer");
@@ -243,11 +187,6 @@ test.serial("xcodeVersion returns major version from resolved path", (t) => {
t.is(result.minor, 0);
}
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
});
@@ -257,9 +196,6 @@ test.serial(
(t) => {
const logger = new RecordingLogger();
const lstatSync = sinon
.stub(fs, "lstatSync")
.returns({ isSymbolicLink: () => true } as fs.Stats);
const readlinkSync = sinon
.stub(fs, "readlinkSync")
.returns("/Applications/Xcode_16.5.9.app/Contents/Developer");
@@ -271,11 +207,6 @@ test.serial(
t.is(result.minor, 5);
}
t.is(lstatSync.callCount, 1);
t.deepEqual(lstatSync.args[0], [
XCODE_SELECT_LINK_PATH,
{ throwIfNoEntry: false },
]);
t.is(readlinkSync.callCount, 1);
t.deepEqual(readlinkSync.args[0], [XCODE_SELECT_LINK_PATH]);
},

View File

@@ -75,28 +75,11 @@ export const XCODE_APP_FILENAME_PATTERN = new RegExp(
*/
export function xcodeVersion(logger: Logger): semver.SemVer | undefined {
try {
// Stat the expected symbolic link to check that it exists and is a symbolic link.
// The `readlinkSync` call below returns an empty string in either case and so
// this check allows us to distinguish between the two cases.
const stats = fs.lstatSync(XCODE_SELECT_LINK_PATH, {
throwIfNoEntry: false,
});
if (stats === undefined) {
logger.debug(`'${XCODE_SELECT_LINK_PATH}' does not exist.`);
return undefined;
}
if (!stats.isSymbolicLink()) {
logger.debug(
`${XCODE_SELECT_LINK_PATH} exists, but is not a symbolic link.`,
);
return undefined;
}
// Read what the symbolic link points to.
// Read what the symbolic link points to. This will throw if `XCODE_SELECT_LINK_PATH` does not
// exist (`ENOENT`) or is not a symbolic link (`EINVAL`).
const xcodePath = fs.readlinkSync(XCODE_SELECT_LINK_PATH);
if (xcodePath === "") {
if (xcodePath.trim() === "") {
logger.debug(
`Resolving ${XCODE_SELECT_LINK_PATH} unexpectedly returned nothing.`,
);