From f583e03df677f0c871214f2a65023d68eba889fb Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 30 Oct 2026 11:24:30 +0000 Subject: [PATCH] Remove unnecessary `lstatSync` call --- lib/entry-points.js | 15 +----- src/languages/traced.test.ts | 24 ---------- src/platform.test.ts | 93 +++++------------------------------- src/platform.ts | 23 ++------- 4 files changed, 16 insertions(+), 139 deletions(-) diff --git a/lib/entry-points.js b/lib/entry-points.js index 2cb33152f..b2bb9c183 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -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.` ); diff --git a/src/languages/traced.test.ts b/src/languages/traced.test.ts index b8fa7b937..2aa931843 100644 --- a/src/languages/traced.test.ts +++ b/src/languages/traced.test.ts @@ -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]); diff --git a/src/platform.test.ts b/src/platform.test.ts index 43108c422..58c41408e 100644 --- a/src/platform.test.ts +++ b/src/platform.test.ts @@ -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]); }, diff --git a/src/platform.ts b/src/platform.ts index 070f30a8f..e5c0e6ac6 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -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.`, );