Skip to content

Commit 5ccef82

Browse files
committed
Address review comments
1 parent bab673d commit 5ccef82

4 files changed

Lines changed: 107 additions & 26 deletions

File tree

lib/entry-points.js

Lines changed: 11 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/testing-utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
GitHubVariant,
3333
GitHubVersion,
3434
HTTPError,
35+
resetCachedCodeQlVersion,
3536
} from "./util";
3637

3738
export const SAMPLE_DOTCOM_API_DETAILS = {
@@ -101,6 +102,10 @@ export function setupTests(testFn: TestFn<any>) {
101102
// unless the test explicitly sets one up.
102103
codeql.setCodeQL({});
103104

105+
// Reset the in-process CodeQL version cache so that it doesn't leak between
106+
// tests, which each represent a separate Actions step in production.
107+
resetCachedCodeQlVersion();
108+
104109
// Replace stdout and stderr so we can record output during tests
105110
t.context.testOutput = "";
106111
const processStdoutWrite = process.stdout.write.bind(process.stdout);

src/util.test.ts

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -533,25 +533,57 @@ test("Failure.orElse returns the default value for a failure result", (t) => {
533533
t.is(result.orElse("default value"), "default value");
534534
});
535535

536-
test("getCachedCodeQlVersion reuses a version persisted by an earlier step", (t) => {
537-
process.env[EnvVar.CODEQL_VERSION_INFO] = JSON.stringify({
538-
cmd: "/path/to/codeql",
539-
version: { version: "2.20.0" },
540-
});
541-
t.deepEqual(util.getCachedCodeQlVersion("/path/to/codeql"), {
542-
version: "2.20.0",
543-
});
544-
});
536+
test.serial(
537+
"getCachedCodeQlVersion reuses a version persisted by an earlier step",
538+
(t) => {
539+
process.env[EnvVar.CODEQL_VERSION_INFO] = JSON.stringify({
540+
cmd: "/path/to/codeql",
541+
version: { version: "2.20.0" },
542+
});
543+
t.deepEqual(util.getCachedCodeQlVersion("/path/to/codeql"), {
544+
version: "2.20.0",
545+
});
546+
},
547+
);
545548

546-
test("getCachedCodeQlVersion ignores a persisted version from a different CLI", (t) => {
547-
process.env[EnvVar.CODEQL_VERSION_INFO] = JSON.stringify({
548-
cmd: "/path/to/other-codeql",
549-
version: { version: "2.20.0" },
550-
});
551-
t.is(util.getCachedCodeQlVersion("/path/to/codeql"), undefined);
552-
});
549+
test.serial(
550+
"getCachedCodeQlVersion ignores a persisted version from a different CLI",
551+
(t) => {
552+
process.env[EnvVar.CODEQL_VERSION_INFO] = JSON.stringify({
553+
cmd: "/path/to/other-codeql",
554+
version: { version: "2.20.0" },
555+
});
556+
t.is(util.getCachedCodeQlVersion("/path/to/codeql"), undefined);
557+
},
558+
);
553559

554-
test("getCachedCodeQlVersion ignores a malformed persisted value", (t) => {
555-
process.env[EnvVar.CODEQL_VERSION_INFO] = "not valid json";
556-
t.is(util.getCachedCodeQlVersion("/path/to/codeql"), undefined);
557-
});
560+
test.serial(
561+
"getCachedCodeQlVersion ignores a malformed persisted value",
562+
(t) => {
563+
process.env[EnvVar.CODEQL_VERSION_INFO] = "not valid json";
564+
t.is(util.getCachedCodeQlVersion("/path/to/codeql"), undefined);
565+
},
566+
);
567+
568+
test.serial(
569+
"getCachedCodeQlVersion ignores a persisted value with the wrong structure",
570+
(t) => {
571+
for (const value of [
572+
JSON.stringify({ cmd: "/path/to/codeql" }),
573+
JSON.stringify({ cmd: "/path/to/codeql", version: {} }),
574+
JSON.stringify({ cmd: "/path/to/codeql", version: { version: 2 } }),
575+
JSON.stringify({ version: { version: "2.20.0" } }),
576+
JSON.stringify({
577+
cmd: "/path/to/codeql",
578+
version: { version: "2.20.0", overlayVersion: "1" },
579+
}),
580+
JSON.stringify({
581+
cmd: "/path/to/codeql",
582+
version: { version: "2.20.0", features: "nope" },
583+
}),
584+
]) {
585+
process.env[EnvVar.CODEQL_VERSION_INFO] = value;
586+
t.is(util.getCachedCodeQlVersion("/path/to/codeql"), undefined, value);
587+
}
588+
},
589+
);

src/util.ts

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,44 @@ export function asHTTPError(arg: any): HTTPError | undefined {
619619

620620
let cachedCodeQlVersion: undefined | VersionInfo = undefined;
621621

622+
/**
623+
* Resets the in-process cache of the CodeQL CLI version. Only for use in tests,
624+
* which exercise multiple "steps" within a single process.
625+
*/
626+
export function resetCachedCodeQlVersion(): void {
627+
cachedCodeQlVersion = undefined;
628+
}
629+
622630
/** The persisted version together with the CLI path it was obtained from. */
623631
interface PersistedVersionInfo {
624632
cmd: string;
625633
version: VersionInfo;
626634
}
627635

636+
function isVersionInfo(x: unknown): x is VersionInfo {
637+
const candidate = x as Partial<VersionInfo> | null;
638+
return (
639+
typeof candidate === "object" &&
640+
candidate !== null &&
641+
typeof candidate.version === "string" &&
642+
(candidate.features === undefined ||
643+
(typeof candidate.features === "object" &&
644+
candidate.features !== null)) &&
645+
(candidate.overlayVersion === undefined ||
646+
typeof candidate.overlayVersion === "number")
647+
);
648+
}
649+
650+
function isPersistedVersionInfo(x: unknown): x is PersistedVersionInfo {
651+
const candidate = x as Partial<PersistedVersionInfo> | null;
652+
return (
653+
typeof candidate === "object" &&
654+
candidate !== null &&
655+
typeof candidate.cmd === "string" &&
656+
isVersionInfo(candidate.version)
657+
);
658+
}
659+
628660
export function cacheCodeQlVersion(cmd: string, version: VersionInfo): void {
629661
if (cachedCodeQlVersion !== undefined) {
630662
throw new Error("cacheCodeQlVersion() should be called only once");
@@ -651,19 +683,22 @@ export function getCachedCodeQlVersion(cmd?: string): undefined | VersionInfo {
651683
if (!serialized) {
652684
return undefined;
653685
}
654-
let persisted: PersistedVersionInfo;
686+
let persisted: unknown;
655687
try {
656-
persisted = JSON.parse(serialized) as PersistedVersionInfo;
688+
persisted = JSON.parse(serialized);
657689
} catch {
658690
return undefined;
659691
}
660692
if (
661-
typeof persisted?.version?.version !== "string" ||
693+
!isPersistedVersionInfo(persisted) ||
662694
(cmd !== undefined && persisted.cmd !== cmd)
663695
) {
664696
return undefined;
665697
}
666-
return persisted.version;
698+
// Memoize the parsed value so that subsequent calls in this process don't
699+
// re-parse the environment variable.
700+
cachedCodeQlVersion = persisted.version;
701+
return cachedCodeQlVersion;
667702
}
668703

669704
export async function codeQlVersionAtLeast(

0 commit comments

Comments
 (0)