diff --git a/lib/entry-points.js b/lib/entry-points.js index 7a739846f..2c0d5ff81 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -149867,6 +149867,10 @@ var toolrunner3 = __toESM(require_toolrunner()); var fs6 = __toESM(require("fs")); var path6 = __toESM(require("path")); var COMMAND_CACHE_FILENAME = "codeql-action-command-cache.json"; +var CommandCacheKey = { + Version: "version", + ResolveLanguages: "resolveLanguages" +}; var inMemoryCache = /* @__PURE__ */ new Map(); function getCommandCacheFilePath() { return path6.join(getTemporaryDirectory(), COMMAND_CACHE_FILENAME); @@ -153769,7 +153773,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { }, async getVersion() { return getCachedOrRun( - "version" /* Version */, + CommandCacheKey.Version, cmd, () => runCliJson(cmd, ["version", "--format=json"], { noStreamStdout: true @@ -153931,7 +153935,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { }, async resolveLanguages() { return getCachedOrRun( - "resolveLanguages" /* ResolveLanguages */, + CommandCacheKey.ResolveLanguages, cmd, async () => { const isFilterToLanguagesWithQueriesSupported = await this.supportsFeature( @@ -155212,7 +155216,7 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCommandOutput( - "version" /* Version */, + CommandCacheKey.Version, void 0, isVersionInfo ); diff --git a/src/cache.test.ts b/src/cache.test.ts index b4b72ecea..6f9757e03 100644 --- a/src/cache.test.ts +++ b/src/cache.test.ts @@ -174,7 +174,7 @@ test.serial( "cacheCommandOutput persists the output to both the memo and the file", async (t) => { await withCacheDir((cacheFilePath) => { - cacheCommandOutput("some-command", "/path/to/codeql", { + cacheCommandOutput(CommandCacheKey.Version, "/path/to/codeql", { hello: "world", }); @@ -182,16 +182,17 @@ test.serial( const onDisk = JSON.parse( fs.readFileSync(cacheFilePath, "utf8"), ) as Record; - t.deepEqual(onDisk["some-command"], { + t.deepEqual(onDisk[CommandCacheKey.Version], { cmd: "/path/to/codeql", output: { hello: "world" }, }); // Tier 1: the value is served from the memo even after the file is gone. fs.rmSync(cacheFilePath); - t.deepEqual(getCachedCommandOutput("some-command", "/path/to/codeql"), { - hello: "world", - }); + t.deepEqual( + getCachedCommandOutput(CommandCacheKey.Version, "/path/to/codeql"), + { hello: "world" }, + ); }); }, ); @@ -200,15 +201,18 @@ test.serial( "getCachedCommandOutput prefers the in-memory memo over the file", async (t) => { await withCacheDir((cacheFilePath) => { - cacheCommandOutput("some-command", "/path/to/codeql", { value: 1 }); + cacheCommandOutput(CommandCacheKey.Version, "/path/to/codeql", { + value: 1, + }); // Overwrite the file with a different value; the memo (tier 1) should win. writeCacheFile(cacheFilePath, { - "some-command": { cmd: "/path/to/codeql", output: { value: 2 } }, - }); - t.deepEqual(getCachedCommandOutput("some-command", "/path/to/codeql"), { - value: 1, + [CommandCacheKey.Version]: { cmd: "/path/to/codeql", output: { value: 2 } }, }); + t.deepEqual( + getCachedCommandOutput(CommandCacheKey.Version, "/path/to/codeql"), + { value: 1 }, + ); }); }, ); @@ -217,9 +221,13 @@ test.serial( "cacheCommandOutput throws if called twice for the same key", async (t) => { await withCacheDir(() => { - cacheCommandOutput("some-command", "/path/to/codeql", { value: 1 }); + cacheCommandOutput(CommandCacheKey.Version, "/path/to/codeql", { + value: 1, + }); t.throws(() => - cacheCommandOutput("some-command", "/path/to/codeql", { value: 2 }), + cacheCommandOutput(CommandCacheKey.Version, "/path/to/codeql", { + value: 2, + }), ); }); }, diff --git a/src/cache.ts b/src/cache.ts index c094bf17b..e0d50c0cd 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -10,11 +10,15 @@ import * as json from "./json"; */ const COMMAND_CACHE_FILENAME = "codeql-action-command-cache.json"; -/** The keys for cached CLI commands. */ -export enum CommandCacheKey { - Version = "version", - ResolveLanguages = "resolveLanguages", -} +/** Named keys for the CLI command-output cache. */ +export const CommandCacheKey = { + Version: "version", + ResolveLanguages: "resolveLanguages", +} as const; + +/** A key used to identify cached command output. */ +export type CommandCacheKey = + (typeof CommandCacheKey)[keyof typeof CommandCacheKey]; /** A single cached command output together with the CLI path it came from. */ interface CacheEntry { @@ -32,7 +36,7 @@ interface CacheEntry { * whenever a value is read from the file (tier 2) or computed via the CLI * (tier 3). */ -const inMemoryCache = new Map(); +const inMemoryCache = new Map(); function getCommandCacheFilePath(): string { return path.join(getTemporaryDirectory(), COMMAND_CACHE_FILENAME); @@ -81,7 +85,7 @@ function writeCommandCacheFile(data: Record): void { * served from the memo rather than recomputed. */ export function cacheCommandOutput( - key: string, + key: CommandCacheKey, cmd: string, output: unknown, ): void { @@ -110,7 +114,7 @@ export function cacheCommandOutput( * CLI). */ export function getCachedCommandOutput( - key: string, + key: CommandCacheKey, cmd?: string, validate?: (output: unknown) => output is T, ): T | undefined { diff --git a/src/codeql.ts b/src/codeql.ts index 6ade356e0..0a00cda61 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -548,7 +548,7 @@ export async function getCodeQLForTesting( * @param validate Optional type guard for values loaded from the temporary file. */ async function getCachedOrRun( - key: string, + key: CommandCacheKey, cmd: string, run: () => Promise, validate?: (output: unknown) => output is T,