Skip to content

Commit ef5d7bf

Browse files
committed
Add version info to cli
And also only add the `--kind=DIL` to `generateDil` if version is >= 2.3.0.
1 parent ec98a57 commit ef5d7bf

File tree

3 files changed

+66
-15
lines changed

3 files changed

+66
-15
lines changed

extensions/ql-vscode/src/cli.ts

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import * as child_process from 'child_process';
44
import * as fs from 'fs-extra';
55
import * as path from 'path';
66
import * as sarif from 'sarif';
7+
import { SemVer } from 'semver';
78
import { Readable } from 'stream';
89
import { StringDecoder } from 'string_decoder';
910
import * as tk from 'tree-kill';
10-
import * as util from 'util';
11+
import { promisify } from 'util';
1112
import { CancellationToken, Disposable } from 'vscode';
1213

1314
import { BQRSInfo, DecodedBqrsChunk } from './bqrs-cli-types';
1415
import { CliConfig } from './config';
15-
import { DistributionProvider } from './distribution';
16+
import { DistributionProvider, FindDistributionResultKind } from './distribution';
1617
import { assertNever } from './helpers-pure';
1718
import { QueryMetadata, SortDirection } from './interface-types';
1819
import { Logger, ProgressReporter } from './logging';
@@ -115,6 +116,11 @@ interface BqrsDecodeOptions {
115116
*/
116117
export class CodeQLCliServer implements Disposable {
117118

119+
/**
120+
* CLI version where --kind=DIL was introduced
121+
*/
122+
private static CLI_VERSION_WITH_DECOMPILE_KIND_DIL = new SemVer('2.3.0');
123+
118124
/** The process for the cli server, or undefined if one doesn't exist yet */
119125
process?: child_process.ChildProcessWithoutNullStreams;
120126
/** Queue of future commands*/
@@ -124,6 +130,12 @@ export class CodeQLCliServer implements Disposable {
124130
/** A buffer with a single null byte. */
125131
nullBuffer: Buffer;
126132

133+
/** Version of current cli, lazily computed by the `getVersion()` method */
134+
_version: SemVer | undefined;
135+
136+
/** Path to current codeQL executable, or undefined if not running yet. */
137+
codeQlPath: string | undefined;
138+
127139
constructor(
128140
private distributionProvider: DistributionProvider,
129141
private cliConfig: CliConfig,
@@ -140,11 +152,11 @@ export class CodeQLCliServer implements Disposable {
140152
if (this.cliConfig.onDidChangeConfiguration) {
141153
this.cliConfig.onDidChangeConfiguration(() => {
142154
this.restartCliServer();
155+
this._version = undefined;
143156
});
144157
}
145158
}
146159

147-
148160
dispose(): void {
149161
this.killProcessIfRunning();
150162
}
@@ -210,9 +222,9 @@ export class CodeQLCliServer implements Disposable {
210222
* Launch the cli server
211223
*/
212224
private async launchProcess(): Promise<child_process.ChildProcessWithoutNullStreams> {
213-
const config = await this.getCodeQlPath();
214-
return spawnServer(
215-
config,
225+
const codeQlPath = await this.getCodeQlPath();
226+
return await spawnServer(
227+
codeQlPath,
216228
'CodeQL CLI Server',
217229
['execute', 'cli-server'],
218230
[],
@@ -671,12 +683,37 @@ export class CodeQLCliServer implements Disposable {
671683
}
672684

673685
async generateDil(qloFile: string, outFile: string): Promise<void> {
686+
const extraArgs = (await this.getVersion()).compare(CodeQLCliServer.CLI_VERSION_WITH_DECOMPILE_KIND_DIL) >= 0
687+
? ['--kind', 'dil', '-o', outFile, qloFile]
688+
: ['-o', outFile, qloFile];
674689
await this.runCodeQlCliCommand(
675690
['query', 'decompile'],
676-
['-o', outFile, qloFile],
691+
extraArgs,
677692
'Generating DIL',
678693
);
679694
}
695+
696+
private async getVersion() {
697+
if (!this._version) {
698+
this._version = await this.refreshVersion();
699+
}
700+
return this._version;
701+
}
702+
703+
private async refreshVersion() {
704+
const distribution = await this.distributionProvider.getDistribution();
705+
switch(distribution.kind) {
706+
case FindDistributionResultKind.CompatibleDistribution:
707+
// eslint-disable-next-line no-fallthrough
708+
case FindDistributionResultKind.IncompatibleDistribution:
709+
return distribution.version;
710+
711+
default:
712+
// We should not get here because if no distributions are available, then
713+
// the cli class is never instantiated.
714+
throw new Error('No distribution found');
715+
}
716+
}
680717
}
681718

682719
/**
@@ -734,15 +771,22 @@ export function spawnServer(
734771

735772
/**
736773
* Runs a CodeQL CLI command without invoking the CLI server, returning the output as a string.
737-
* @param config The configuration containing the path to the CLI.
774+
* @param codeQlPath The path to the CLI.
738775
* @param command The `codeql` command to be run, provided as an array of command/subcommand names.
739776
* @param commandArgs The arguments to pass to the `codeql` command.
740777
* @param description Description of the action being run, to be shown in log and error messages.
741778
* @param logger Logger to write command log messages, e.g. to an output channel.
742779
* @param progressReporter Used to output progress messages, e.g. to the status bar.
743780
* @returns The contents of the command's stdout, if the command succeeded.
744781
*/
745-
export async function runCodeQlCliCommand(codeQlPath: string, command: string[], commandArgs: string[], description: string, logger: Logger, progressReporter?: ProgressReporter): Promise<string> {
782+
export async function runCodeQlCliCommand(
783+
codeQlPath: string,
784+
command: string[],
785+
commandArgs: string[],
786+
description: string,
787+
logger: Logger,
788+
progressReporter?: ProgressReporter
789+
): Promise<string> {
746790
// Add logging arguments first, in case commandArgs contains positional parameters.
747791
const args = command.concat(LOGGING_FLAGS).concat(commandArgs);
748792
const argsString = args.join(' ');
@@ -751,7 +795,7 @@ export async function runCodeQlCliCommand(codeQlPath: string, command: string[],
751795
progressReporter.report({ message: description });
752796
}
753797
logger.log(`${description} using CodeQL CLI: ${codeQlPath} ${argsString}...`);
754-
const result = await util.promisify(child_process.execFile)(codeQlPath, args);
798+
const result = await promisify(child_process.execFile)(codeQlPath, args);
755799
logger.log(result.stderr);
756800
logger.log('CLI command succeeded.');
757801
return result.stdout;

extensions/ql-vscode/src/distribution.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const DEFAULT_DISTRIBUTION_VERSION_RANGE: semver.Range = new semver.Range
4545
export interface DistributionProvider {
4646
getCodeQlPathWithoutVersionCheck(): Promise<string | undefined>;
4747
onDidChangeDistribution?: Event<void>;
48+
getDistribution(): Promise<FindDistributionResult>;
4849
}
4950

5051
export class DistributionManager implements DistributionProvider {

extensions/ql-vscode/test/pure-tests/query-test.ts renamed to extensions/ql-vscode/src/vscode-tests/no-workspace/query-test.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import * as path from 'path';
55
import * as tmp from 'tmp';
66
import * as url from 'url';
77
import { CancellationTokenSource } from 'vscode-jsonrpc';
8-
import * as messages from '../../src/messages';
9-
import * as qsClient from '../../src/queryserver-client';
10-
import * as cli from '../../src/cli';
11-
import { ProgressReporter, Logger } from '../../src/logging';
12-
import { ColumnValue } from '../../src/bqrs-cli-types';
8+
import * as messages from '../../messages';
9+
import * as qsClient from '../../queryserver-client';
10+
import * as cli from '../../cli';
11+
import { ProgressReporter, Logger } from '../../logging';
12+
import { ColumnValue } from '../../bqrs-cli-types';
13+
import { FindDistributionResultKind } from '../../distribution';
1314

1415

1516
declare module 'url' {
@@ -114,6 +115,11 @@ describe('using the query server', function() {
114115
async getCodeQlPathWithoutVersionCheck(): Promise<string | undefined> {
115116
return codeQlPath;
116117
},
118+
getDistribution: async () => {
119+
return {
120+
kind: FindDistributionResultKind.NoDistribution
121+
};
122+
}
117123
},
118124
{
119125
numberTestThreads: 2

0 commit comments

Comments
 (0)