Skip to content

Commit afbf762

Browse files
authored
Merge branch 'main' into simpler-location-url
2 parents 2d8c690 + c96fd81 commit afbf762

File tree

111 files changed

+3888
-1471
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3888
-1471
lines changed
Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,40 @@
11
/**
22
* @name Unwanted dependency on vscode API
3-
* @kind problem
3+
* @kind path-problem
44
* @problem.severity error
55
* @id vscode-codeql/assert-pure
66
* @description The modules stored under `pure` and tested in the `pure-tests`
77
* are intended to be "pure".
88
*/
9+
910
import javascript
1011

11-
class VSCodeImport extends ASTNode {
12-
VSCodeImport() {
13-
this.(Import).getImportedPath().getValue() = "vscode"
12+
class VSCodeImport extends ImportDeclaration {
13+
VSCodeImport() { this.getImportedPath().getValue() = "vscode" }
14+
}
15+
16+
class PureFile extends File {
17+
PureFile() {
18+
(
19+
this.getRelativePath().regexpMatch(".*/src/pure/.*") or
20+
this.getRelativePath().regexpMatch(".*/src/common/.*")
21+
) and
22+
not this.getRelativePath().regexpMatch(".*/vscode/.*")
1423
}
1524
}
1625

26+
Import getANonTypeOnlyImport(Module m) {
27+
result = m.getAnImport() and not result.(ImportDeclaration).isTypeOnly()
28+
}
29+
30+
query predicate edges(AstNode a, AstNode b) {
31+
getANonTypeOnlyImport(a) = b or
32+
a.(Import).getImportedModule() = b
33+
}
34+
1735
from Module m, VSCodeImport v
1836
where
19-
m.getFile().getRelativePath().regexpMatch(".*src/pure/.*") and
20-
m.getAnImportedModule*().getAnImport() = v
21-
select m, "This module is not pure: it has a transitive dependency on the vscode API imported $@", v, "here"
37+
m.getFile() instanceof PureFile and
38+
edges+(m, v)
39+
select m, m, v,
40+
"This module is not pure: it has a transitive dependency on the vscode API imported $@", v, "here"

extensions/ql-vscode/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
## [UNRELEASED]
44

55
- Add settings `codeQL.variantAnalysis.defaultResultsFilter` and `codeQL.variantAnalysis.defaultResultsSort` for configuring how variant analysis results are filtered and sorted in the results view. The default is to show all repositories, and to sort by the number of results. [#2392](https://github.com/github/vscode-codeql/pull/2392)
6+
- Fix bug to ensure error messages have complete stack trace in message logs. [#2425](https://github.com/github/vscode-codeql/pull/2425)
7+
- Fix bug where the `CodeQL: Compare Query` command did not work for comparing quick-eval queries. [#2422](https://github.com/github/vscode-codeql/pull/2422)
8+
- Update text of copy and export buttons in variant analysis results view to clarify that they only copy/export the selected/filtered results. [#2427](https://github.com/github/vscode-codeql/pull/2427)
9+
- Add warning when using unsupported CodeQL CLI version. [#2428](https://github.com/github/vscode-codeql/pull/2428)
610

711
## 1.8.4 - 3 May 2023
812

extensions/ql-vscode/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@
516516
"title": "Add new list",
517517
"icon": "$(new-folder)"
518518
},
519+
{
520+
"command": "codeQLVariantAnalysisRepositories.importFromCodeSearch",
521+
"title": "Add repositories with GitHub Code Search"
522+
},
519523
{
520524
"command": "codeQLVariantAnalysisRepositories.setSelectedItem",
521525
"title": "Select"
@@ -961,6 +965,11 @@
961965
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeOpenedOnGitHub/",
962966
"group": "2_qlContextMenu@1"
963967
},
968+
{
969+
"command": "codeQLVariantAnalysisRepositories.importFromCodeSearch",
970+
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canImportCodeSearch/",
971+
"group": "2_qlContextMenu@1"
972+
},
964973
{
965974
"command": "codeQLDatabases.setCurrentDatabase",
966975
"group": "inline",
@@ -1297,6 +1306,10 @@
12971306
"command": "codeQLVariantAnalysisRepositories.removeItemContextMenu",
12981307
"when": "false"
12991308
},
1309+
{
1310+
"command": "codeQLVariantAnalysisRepositories.importFromCodeSearch",
1311+
"when": "false"
1312+
},
13001313
{
13011314
"command": "codeQLDatabases.setCurrentDatabase",
13021315
"when": "false"
@@ -1593,6 +1606,10 @@
15931606
"view": "codeQLQueryHistory",
15941607
"contents": "You have no query history items at the moment.\n\nSelect a database to run a CodeQL query and get your first results."
15951608
},
1609+
{
1610+
"view": "codeQLQueries",
1611+
"contents": "This workspace doesn't contain any CodeQL queries at the moment."
1612+
},
15961613
{
15971614
"view": "codeQLDatabases",
15981615
"contents": "Add a CodeQL database:\n[From a folder](command:codeQLDatabases.chooseDatabaseFolder)\n[From an archive](command:codeQLDatabases.chooseDatabaseArchive)\n[From a URL (as a zip file)](command:codeQLDatabases.chooseDatabaseInternet)\n[From GitHub](command:codeQLDatabases.chooseDatabaseGithub)"

extensions/ql-vscode/src/codeql-cli/cli.ts

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ export interface SourceInfo {
134134
sourceLocationPrefix: string;
135135
}
136136

137+
/**
138+
* The expected output of `codeql resolve queries`.
139+
*/
140+
export type ResolvedQueries = string[];
141+
137142
/**
138143
* The expected output of `codeql resolve tests`.
139144
*/
@@ -213,7 +218,7 @@ export class CodeQLCliServer implements Disposable {
213218
private readonly app: App,
214219
private distributionProvider: DistributionProvider,
215220
private cliConfig: CliConfig,
216-
private logger: Logger,
221+
public readonly logger: Logger,
217222
) {
218223
this.commandQueue = [];
219224
this.commandInProcess = false;
@@ -325,6 +330,7 @@ export class CodeQLCliServer implements Disposable {
325330
commandArgs: string[],
326331
description: string,
327332
onLine?: OnLineCallback,
333+
silent?: boolean,
328334
): Promise<string> {
329335
const stderrBuffers: Buffer[] = [];
330336
if (this.commandInProcess) {
@@ -344,7 +350,12 @@ export class CodeQLCliServer implements Disposable {
344350
// Compute the full args array
345351
const args = command.concat(LOGGING_FLAGS).concat(commandArgs);
346352
const argsString = args.join(" ");
347-
void this.logger.log(`${description} using CodeQL CLI: ${argsString}...`);
353+
// If we are running silently, we don't want to print anything to the console.
354+
if (!silent) {
355+
void this.logger.log(
356+
`${description} using CodeQL CLI: ${argsString}...`,
357+
);
358+
}
348359
try {
349360
await new Promise<void>((resolve, reject) => {
350361
// Start listening to stdout
@@ -390,24 +401,30 @@ export class CodeQLCliServer implements Disposable {
390401
const fullBuffer = Buffer.concat(stdoutBuffers);
391402
// Make sure we remove the terminator;
392403
const data = fullBuffer.toString("utf8", 0, fullBuffer.length - 1);
393-
void this.logger.log("CLI command succeeded.");
404+
if (!silent) {
405+
void this.logger.log("CLI command succeeded.");
406+
}
394407
return data;
395408
} catch (err) {
396409
// Kill the process if it isn't already dead.
397410
this.killProcessIfRunning();
398-
// Report the error (if there is a stderr then use that otherwise just report the error cod or nodejs error)
411+
// Report the error (if there is a stderr then use that otherwise just report the error code or nodejs error)
399412
const newError =
400413
stderrBuffers.length === 0
401-
? new Error(`${description} failed: ${err}`)
414+
? new Error(
415+
`${description} failed with args:${EOL} ${argsString}${EOL}${err}`,
416+
)
402417
: new Error(
403-
`${description} failed: ${Buffer.concat(stderrBuffers).toString(
404-
"utf8",
405-
)}`,
418+
`${description} failed with args:${EOL} ${argsString}${EOL}${Buffer.concat(
419+
stderrBuffers,
420+
).toString("utf8")}`,
406421
);
407422
newError.stack += getErrorStack(err);
408423
throw newError;
409424
} finally {
410-
void this.logger.log(Buffer.concat(stderrBuffers).toString("utf8"));
425+
if (!silent) {
426+
void this.logger.log(Buffer.concat(stderrBuffers).toString("utf8"));
427+
}
411428
// Remove the listeners we set up.
412429
process.stdout.removeAllListeners("data");
413430
process.stderr.removeAllListeners("data");
@@ -544,9 +561,11 @@ export class CodeQLCliServer implements Disposable {
544561
{
545562
progressReporter,
546563
onLine,
564+
silent = false,
547565
}: {
548566
progressReporter?: ProgressReporter;
549567
onLine?: OnLineCallback;
568+
silent?: boolean;
550569
} = {},
551570
): Promise<string> {
552571
if (progressReporter) {
@@ -562,6 +581,7 @@ export class CodeQLCliServer implements Disposable {
562581
commandArgs,
563582
description,
564583
onLine,
584+
silent,
565585
).then(resolve, reject);
566586
} catch (err) {
567587
reject(err);
@@ -595,10 +615,12 @@ export class CodeQLCliServer implements Disposable {
595615
addFormat = true,
596616
progressReporter,
597617
onLine,
618+
silent = false,
598619
}: {
599620
addFormat?: boolean;
600621
progressReporter?: ProgressReporter;
601622
onLine?: OnLineCallback;
623+
silent?: boolean;
602624
} = {},
603625
): Promise<OutputType> {
604626
let args: string[] = [];
@@ -609,6 +631,7 @@ export class CodeQLCliServer implements Disposable {
609631
const result = await this.runCodeQlCliCommand(command, args, description, {
610632
progressReporter,
611633
onLine,
634+
silent,
612635
});
613636
try {
614637
return JSON.parse(result) as OutputType;
@@ -731,6 +754,25 @@ export class CodeQLCliServer implements Disposable {
731754
);
732755
}
733756

757+
/**
758+
* Finds all available queries in a given directory.
759+
* @param queryDir Root of directory tree to search for queries.
760+
* @param silent If true, don't print logs to the CodeQL extension log.
761+
* @returns The list of queries that were found.
762+
*/
763+
public async resolveQueries(
764+
queryDir: string,
765+
silent?: boolean,
766+
): Promise<ResolvedQueries> {
767+
const subcommandArgs = [queryDir];
768+
return await this.runJsonCodeQlCliCommand<ResolvedQueries>(
769+
["resolve", "queries"],
770+
subcommandArgs,
771+
"Resolving queries",
772+
{ silent },
773+
);
774+
}
775+
734776
/**
735777
* Finds all available QL tests in a given directory.
736778
* @param testPath Root of directory tree to search for tests.
@@ -1031,13 +1073,15 @@ export class CodeQLCliServer implements Disposable {
10311073
resultsPath: string,
10321074
interpretedResultsPath: string,
10331075
sourceInfo?: SourceInfo,
1076+
args?: string[],
10341077
): Promise<sarif.Log> {
10351078
const additionalArgs = [
10361079
// TODO: This flag means that we don't group interpreted results
10371080
// by primary location. We may want to revisit whether we call
10381081
// interpretation with and without this flag, or do some
10391082
// grouping client-side.
10401083
"--no-group-results",
1084+
...(args ?? []),
10411085
];
10421086

10431087
await this.runInterpretCommand(
@@ -1737,6 +1781,10 @@ export function shouldDebugCliServer() {
17371781
}
17381782

17391783
export class CliVersionConstraint {
1784+
// The oldest version of the CLI that we support. This is used to determine
1785+
// whether to show a warning about the CLI being too old on startup.
1786+
public static OLDEST_SUPPORTED_CLI_VERSION = new SemVer("2.7.6");
1787+
17401788
/**
17411789
* CLI version where building QLX packs for remote queries is supported.
17421790
* (The options were _accepted_ by a few earlier versions, but only from
@@ -1795,6 +1843,8 @@ export class CliVersionConstraint {
17951843
"2.12.4",
17961844
);
17971845

1846+
public static CLI_VERSION_GLOBAL_CACHE = new SemVer("2.12.4");
1847+
17981848
constructor(private readonly cli: CodeQLCliServer) {
17991849
/**/
18001850
}
@@ -1864,4 +1914,8 @@ export class CliVersionConstraint {
18641914
CliVersionConstraint.CLI_VERSION_WITH_ADDITIONAL_PACKS_INSTALL,
18651915
);
18661916
}
1917+
1918+
async usesGlobalCompilationCache() {
1919+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_GLOBAL_CACHE);
1920+
}
18671921
}

extensions/ql-vscode/src/codeql-cli/distribution.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@ import * as semver from "semver";
66
import { URL } from "url";
77
import { ExtensionContext, Event } from "vscode";
88
import { DistributionConfig } from "../config";
9-
import {
10-
InvocationRateLimiter,
11-
InvocationRateLimiterResultKind,
12-
showAndLogErrorMessage,
13-
showAndLogWarningMessage,
14-
} from "../helpers";
9+
import { showAndLogErrorMessage, showAndLogWarningMessage } from "../helpers";
1510
import { extLogger } from "../common";
1611
import { getCodeQlCliVersion } from "./cli-version";
1712
import {
@@ -24,6 +19,10 @@ import {
2419
extractZipArchive,
2520
getRequiredAssetName,
2621
} from "../pure/distribution";
22+
import {
23+
InvocationRateLimiter,
24+
InvocationRateLimiterResultKind,
25+
} from "../common/invocation-rate-limiter";
2726

2827
/**
2928
* distribution.ts
@@ -76,7 +75,7 @@ export class DistributionManager implements DistributionProvider {
7675
extensionContext,
7776
);
7877
this.updateCheckRateLimiter = new InvocationRateLimiter(
79-
extensionContext,
78+
extensionContext.globalState,
8079
"extensionSpecificDistributionUpdateCheck",
8180
() =>
8281
this.extensionSpecificDistributionManager.checkForUpdatesToDistribution(),

extensions/ql-vscode/src/common/app.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ import { AppEventEmitter } from "./events";
44
import { Logger } from "./logging";
55
import { Memento } from "./memento";
66
import { AppCommandManager } from "./commands";
7+
import type {
8+
WorkspaceFolder,
9+
Event,
10+
WorkspaceFoldersChangeEvent,
11+
} from "vscode";
712

813
export interface App {
914
createEventEmitter<T>(): AppEventEmitter<T>;
@@ -14,6 +19,8 @@ export interface App {
1419
readonly globalStoragePath: string;
1520
readonly workspaceStoragePath?: string;
1621
readonly workspaceState: Memento;
22+
readonly workspaceFolders: readonly WorkspaceFolder[] | undefined;
23+
readonly onDidChangeWorkspaceFolders: Event<WorkspaceFoldersChangeEvent>;
1724
readonly credentials: Credentials;
1825
readonly commands: AppCommandManager;
1926
}

extensions/ql-vscode/src/common/commands.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ export type VariantAnalysisCommands = {
251251
"codeQL.monitorRehydratedVariantAnalysis": (
252252
variantAnalysis: VariantAnalysis,
253253
) => Promise<void>;
254+
"codeQL.monitorReauthenticatedVariantAnalysis": (
255+
variantAnalysis: VariantAnalysis,
256+
) => Promise<void>;
254257
"codeQL.openVariantAnalysisLogs": (
255258
variantAnalysisId: number,
256259
) => Promise<void>;
@@ -272,6 +275,7 @@ export type DatabasePanelCommands = {
272275
"codeQLVariantAnalysisRepositories.openOnGitHubContextMenu": TreeViewContextSingleSelectionCommandFunction<DbTreeViewItem>;
273276
"codeQLVariantAnalysisRepositories.renameItemContextMenu": TreeViewContextSingleSelectionCommandFunction<DbTreeViewItem>;
274277
"codeQLVariantAnalysisRepositories.removeItemContextMenu": TreeViewContextSingleSelectionCommandFunction<DbTreeViewItem>;
278+
"codeQLVariantAnalysisRepositories.importFromCodeSearch": TreeViewContextSingleSelectionCommandFunction<DbTreeViewItem>;
275279
};
276280

277281
export type AstCfgCommands = {

0 commit comments

Comments
 (0)