Skip to content

Commit bdb2feb

Browse files
committed
Refactor version constraints
A simple refactoring that simplifies and unifies how we check if a feature is supported by a specific cli version.
1 parent 5b08fd0 commit bdb2feb

File tree

7 files changed

+74
-59
lines changed

7 files changed

+74
-59
lines changed

extensions/ql-vscode/src/cli.ts

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -132,26 +132,6 @@ interface BqrsDecodeOptions {
132132
*/
133133
export class CodeQLCliServer implements Disposable {
134134

135-
/**
136-
* CLI version where --kind=DIL was introduced
137-
*/
138-
private static CLI_VERSION_WITH_DECOMPILE_KIND_DIL = new SemVer('2.3.0');
139-
140-
/**
141-
* CLI version where languages are exposed during a `codeql resolve database` command.
142-
*/
143-
private static CLI_VERSION_WITH_LANGUAGE = new SemVer('2.4.1');
144-
145-
/**
146-
* CLI version where `codeql resolve upgrades` supports
147-
* the `--allow-downgrades` flag
148-
*/
149-
private static CLI_VERSION_WITH_DOWNGRADES = new SemVer('2.4.4');
150-
151-
/**
152-
* CLI version where the `codeql resolve qlref` command is available.
153-
*/
154-
public static CLI_VERSION_WITH_RESOLVE_QLREF = new SemVer('2.5.1');
155135

156136
/** The process for the cli server, or undefined if one doesn't exist yet */
157137
process?: child_process.ChildProcessWithoutNullStreams;
@@ -168,6 +148,8 @@ export class CodeQLCliServer implements Disposable {
168148
/** Path to current codeQL executable, or undefined if not running yet. */
169149
codeQlPath: string | undefined;
170150

151+
cliConstraints = new CliVersionConstraint(this);
152+
171153
/**
172154
* When set to true, ignore some modal popups and assume user has clicked "yes".
173155
*/
@@ -716,7 +698,7 @@ export class CodeQLCliServer implements Disposable {
716698
const args = ['--additional-packs', searchPath.join(path.delimiter), '--dbscheme', dbScheme];
717699
if (targetDbScheme) {
718700
args.push('--target-dbscheme', targetDbScheme);
719-
if (allowDowngradesIfPossible && await this.supportsDowngrades()) {
701+
if (allowDowngradesIfPossible && await this.cliConstraints.supportsDowngrades()) {
720702
args.push('--allow-downgrades');
721703
}
722704
}
@@ -769,7 +751,7 @@ export class CodeQLCliServer implements Disposable {
769751
}
770752

771753
async generateDil(qloFile: string, outFile: string): Promise<void> {
772-
const extraArgs = await this.supportsDecompileDil()
754+
const extraArgs = await this.cliConstraints.supportsDecompileDil()
773755
? ['--kind', 'dil', '-o', outFile, qloFile]
774756
: ['-o', outFile, qloFile];
775757
await this.runCodeQlCliCommand(
@@ -786,22 +768,6 @@ export class CodeQLCliServer implements Disposable {
786768
return this._version;
787769
}
788770

789-
private async supportsDecompileDil() {
790-
return (await this.getVersion()).compare(CodeQLCliServer.CLI_VERSION_WITH_DECOMPILE_KIND_DIL) >= 0;
791-
}
792-
793-
public async supportsLanguageName() {
794-
return (await this.getVersion()).compare(CodeQLCliServer.CLI_VERSION_WITH_LANGUAGE) >= 0;
795-
}
796-
797-
public async supportsDowngrades() {
798-
return (await this.getVersion()).compare(CodeQLCliServer.CLI_VERSION_WITH_DOWNGRADES) >= 0;
799-
}
800-
801-
public async supportsResolveQlref() {
802-
return (await this.getVersion()).compare(CodeQLCliServer.CLI_VERSION_WITH_RESOLVE_QLREF) >= 0;
803-
}
804-
805771
private async refreshVersion() {
806772
const distribution = await this.distributionProvider.getDistribution();
807773
switch (distribution.kind) {
@@ -1030,3 +996,60 @@ export function shouldDebugQueryServer() {
1030996
&& process.env.QUERY_SERVER_JAVA_DEBUG !== '0'
1031997
&& process.env.QUERY_SERVER_JAVA_DEBUG?.toLocaleLowerCase() !== 'false';
1032998
}
999+
1000+
export class CliVersionConstraint {
1001+
1002+
/**
1003+
* CLI version where --kind=DIL was introduced
1004+
*/
1005+
public static CLI_VERSION_WITH_DECOMPILE_KIND_DIL = new SemVer('2.3.0');
1006+
1007+
/**
1008+
* CLI version where languages are exposed during a `codeql resolve database` command.
1009+
*/
1010+
public static CLI_VERSION_WITH_LANGUAGE = new SemVer('2.4.1');
1011+
1012+
/**
1013+
* CLI version where `codeql resolve upgrades` supports
1014+
* the `--allow-downgrades` flag
1015+
*/
1016+
public static CLI_VERSION_WITH_DOWNGRADES = new SemVer('2.4.4');
1017+
1018+
/**
1019+
* CLI version where the `codeql resolve qlref` command is available.
1020+
*/
1021+
public static CLI_VERSION_WITH_RESOLVE_QLREF = new SemVer('2.5.1');
1022+
1023+
/**
1024+
* CLI version where database registration was introduced
1025+
*/
1026+
public static CLI_VERSION_WITH_DB_REGISTRATION = new SemVer('2.4.1');
1027+
1028+
constructor(private readonly cli: CodeQLCliServer) {
1029+
/**/
1030+
}
1031+
1032+
private async isVersionAtLeast(v: SemVer) {
1033+
return (await this.cli.getVersion()).compare(v) >= 0;
1034+
}
1035+
1036+
public async supportsDecompileDil() {
1037+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_DECOMPILE_KIND_DIL);
1038+
}
1039+
1040+
public async supportsLanguageName() {
1041+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_LANGUAGE);
1042+
}
1043+
1044+
public async supportsDowngrades() {
1045+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_DOWNGRADES);
1046+
}
1047+
1048+
public async supportsResolveQlref() {
1049+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_RESOLVE_QLREF);
1050+
}
1051+
1052+
async supportsDatabaseRegistration() {
1053+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_DB_REGISTRATION);
1054+
}
1055+
}

extensions/ql-vscode/src/databases.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ export class DatabaseManager extends DisposableObject {
808808
token: vscode.CancellationToken,
809809
dbItem: DatabaseItem,
810810
) {
811-
if (dbItem.contents && (await this.qs.supportsDatabaseRegistration())) {
811+
if (dbItem.contents && (await this.cli.cliConstraints.supportsDatabaseRegistration())) {
812812
const databases: Dataset[] = [{
813813
dbDir: dbItem.contents.datasetUri.fsPath,
814814
workingSet: 'default'
@@ -822,7 +822,7 @@ export class DatabaseManager extends DisposableObject {
822822
token: vscode.CancellationToken,
823823
dbItem: DatabaseItem,
824824
) {
825-
if (dbItem.contents && (await this.qs.supportsDatabaseRegistration())) {
825+
if (dbItem.contents && (await this.cli.cliConstraints.supportsDatabaseRegistration())) {
826826
const databases: Dataset[] = [{
827827
dbDir: dbItem.contents.datasetUri.fsPath,
828828
workingSet: 'default'
@@ -852,7 +852,7 @@ export class DatabaseManager extends DisposableObject {
852852
}
853853

854854
private async getPrimaryLanguage(dbPath: string) {
855-
if (!(await this.cli.supportsLanguageName())) {
855+
if (!(await this.cli.cliConstraints.supportsLanguageName())) {
856856
// return undefined so that we recalculate on restart until the cli is at a version that
857857
// supports this feature. This recalculation is cheap since we avoid calling into the cli
858858
// unless we know it can return the langauges property.

extensions/ql-vscode/src/extension.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { testExplorerExtensionId, TestHub } from 'vscode-test-adapter-api';
1818

1919
import { AstViewer } from './astViewer';
2020
import * as archiveFilesystemProvider from './archive-filesystem-provider';
21-
import { CodeQLCliServer } from './cli';
21+
import { CodeQLCliServer, CliVersionConstraint } from './cli';
2222
import {
2323
CliConfigListener,
2424
DistributionConfigListener,
@@ -484,7 +484,7 @@ async function activateWithInstalledDistribution(
484484
selectedQuery: Uri
485485
): Promise<void> {
486486
if (qs !== undefined) {
487-
if (await cliServer.supportsResolveQlref()) {
487+
if (await cliServer.cliConstraints.supportsResolveQlref()) {
488488
const resolved = await cliServer.resolveQlref(selectedQuery.path);
489489
const uri = Uri.file(resolved.resolvedPath);
490490
await window.showTextDocument(uri, { preview: false });
@@ -493,7 +493,7 @@ async function activateWithInstalledDistribution(
493493
'Jumping from a .qlref file to the .ql file it references is not '
494494
+ 'supported with the CLI version you are running.\n'
495495
+ `Please upgrade your CLI to version ${
496-
CodeQLCliServer.CLI_VERSION_WITH_RESOLVE_QLREF
496+
CliVersionConstraint.CLI_VERSION_WITH_RESOLVE_QLREF
497497
} or later to use this feature.`);
498498
}
499499
}

extensions/ql-vscode/src/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ export class CachedOperation<U> {
367367
* `cli.CodeQLCliServer.resolveDatabase` and use the first entry in the
368368
* `languages` property.
369369
*
370-
* @see cli.CodeQLCliServer.supportsLanguageName
370+
* @see cli.CliVersionConstraint.supportsLanguageName
371371
* @see cli.CodeQLCliServer.resolveDatabase
372372
*/
373373
const dbSchemeToLanguage = {

extensions/ql-vscode/src/queryserver-client.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { QueryServerConfig } from './config';
88
import { Logger, ProgressReporter } from './logging';
99
import { completeQuery, EvaluationResult, progress, ProgressMessage, WithProgressId } from './pure/messages';
1010
import * as messages from './pure/messages';
11-
import { SemVer } from 'semver';
1211
import { ProgressCallback, ProgressTask } from './commandRunner';
1312

1413
type ServerOpts = {
@@ -50,11 +49,6 @@ type WithProgressReporting = (task: (progress: ProgressReporter, token: Cancella
5049
*/
5150
export class QueryServerClient extends DisposableObject {
5251

53-
/**
54-
* Query Server version where database registration was introduced
55-
*/
56-
private static VERSION_WITH_DB_REGISTRATION = new SemVer('2.4.1');
57-
5852
serverProcess?: ServerProcess;
5953
evaluationResultCallbacks: { [key: number]: (res: EvaluationResult) => void };
6054
progressCallbacks: { [key: number]: ((res: ProgressMessage) => void) | undefined };
@@ -145,7 +139,7 @@ export class QueryServerClient extends DisposableObject {
145139
args.push(this.config.cacheSize.toString());
146140
}
147141

148-
if (await this.supportsDatabaseRegistration()) {
142+
if (await this.cliServer.cliConstraints.supportsDatabaseRegistration()) {
149143
args.push('--require-db-registration');
150144
}
151145

@@ -202,10 +196,6 @@ export class QueryServerClient extends DisposableObject {
202196
this.evaluationResultCallbacks = {};
203197
}
204198

205-
async supportsDatabaseRegistration() {
206-
return (await this.cliServer.getVersion()).compare(QueryServerClient.VERSION_WITH_DB_REGISTRATION) >= 0;
207-
}
208-
209199
registerCallback(callback: (res: EvaluationResult) => void): number {
210200
const id = this.nextCallback++;
211201
this.evaluationResultCallbacks[id] = callback;

extensions/ql-vscode/src/vscode-tests/cli-integration/query.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ describe('using the query server', function() {
129129
const parsedResults = new Checkpoint<void>();
130130

131131
it('should register the database if necessary', async () => {
132-
if (await qs.supportsDatabaseRegistration()) {
132+
if (await cliServer.cliConstraints.supportsDatabaseRegistration()) {
133133
await qs.sendRequest(messages.registerDatabases, { databases: [db] }, token, (() => { /**/ }) as any);
134134
}
135135
});

extensions/ql-vscode/src/vscode-tests/minimal-workspace/databases.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,13 @@ describe('databases', () => {
6767
} as unknown as ExtensionContext,
6868
{
6969
sendRequest: sendRequestSpy,
70-
supportsDatabaseRegistration: supportsDatabaseRegistrationSpy,
7170
onDidStartQueryServer: () => { /**/ }
7271
} as unknown as QueryServerClient,
7372
{
74-
supportsLanguageName: supportsLanguageNameSpy,
73+
cliConstraints: {
74+
supportsLanguageName: supportsLanguageNameSpy,
75+
supportsDatabaseRegistration: supportsDatabaseRegistrationSpy,
76+
},
7577
resolveDatabase: resolveDatabaseSpy
7678
} as unknown as CodeQLCliServer,
7779
{} as Logger,

0 commit comments

Comments
 (0)