Skip to content

Commit 9a7489f

Browse files
authored
Merge pull request #1674 from github/aeisenberg/assert-version
Assert VSCode version is high enough
2 parents 846eda5 + 93cc408 commit 9a7489f

File tree

5 files changed

+63
-7
lines changed

5 files changed

+63
-7
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Alternatively, you can build the extension within VS Code via `Terminal > Run Bu
5454

5555
Before running any of the launch commands, be sure to have run the `build` command to ensure that the JavaScript is compiled and the resources are copied to the proper location.
5656

57-
We recommend that you keep `npm run watch` running in the backgound and you only need to re-run `npm run build` in the following situations:
57+
We recommend that you keep `npm run watch` running in the background and you only need to re-run `npm run build` in the following situations:
5858

5959
1. on first checkout
6060
2. whenever any of the non-TypeScript resources have changed
@@ -152,7 +152,7 @@ The CLI integration tests require the CodeQL standard libraries in order to run
152152

153153
#### Using a mock GitHub API server
154154

155-
Multi-Repo Variant Analyses (MRVA) rely on the GitHub API. In order to make development and testing easy, we have functionality that allows us to intercept requests to the GitHub API and provide mock responses.
155+
Multi-Repo Variant Analyses (MRVA) rely on the GitHub API. In order to make development and testing easy, we have functionality that allows us to intercept requests to the GitHub API and provide mock responses.
156156

157157
##### Using a pre-recorded test scenario
158158

extensions/ql-vscode/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## [UNRELEASED]
44

5+
- Warn users when their VS Code version is too old to support all features in the vscode-codeql extension. [#1674](https://github.com/github/vscode-codeql/pull/1674)
6+
57
## 1.7.5 - 8 November 2022
68

79
- Fix a bug where the AST Viewer was not working unless the associated CodeQL library pack is in the workspace. [#1735](https://github.com/github/vscode-codeql/pull/1735)

extensions/ql-vscode/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ When the results are ready, they're displayed in the CodeQL Query Results view.
9999

100100
If there are any problems running a query, a notification is displayed in the bottom right corner of the application. In addition to the error message, the notification includes details of how to fix the problem.
101101

102-
### Keyboad navigation
102+
### Keyboard navigation
103103

104104
If you wish to navigate the query results from your keyboard, you can bind shortcuts to the **CodeQL: Navigate Up/Down/Left/Right in Result Viewer** commands.
105105

extensions/ql-vscode/src/extension.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ import {
1616
QuickPickItem,
1717
Range,
1818
workspace,
19-
ProviderResult
19+
ProviderResult,
20+
version as vscodeVersion
2021
} from 'vscode';
2122
import { LanguageClient } from 'vscode-languageclient';
2223
import * as os from 'os';
2324
import * as fs from 'fs-extra';
2425
import * as path from 'path';
2526
import * as tmp from 'tmp-promise';
2627
import { testExplorerExtensionId, TestHub } from 'vscode-test-adapter-api';
28+
import * as semver from 'semver';
2729

2830
import { AstViewer } from './astViewer';
2931
import * as archiveFilesystemProvider from './archive-filesystem-provider';
@@ -191,6 +193,13 @@ export interface CodeQLExtensionInterface {
191193
readonly dispose: () => void;
192194
}
193195

196+
// This is the minimum version of vscode that we _want_ to support. We want to update the language server library, but that
197+
// requires 1.67 or later. If we change the minimum version in the package.json, then anyone on an older version of vscode
198+
// silently be unable to upgrade. So, the solution is to first bump the minimum version here and release. Then
199+
// bump the version in the package.json and release again. This way, anyone on an older version of vscode will get a warning
200+
// before silently being refused to upgrade.
201+
const MIN_VERSION = '1.67.0';
202+
194203
/**
195204
* Returns the CodeQLExtensionInterface, or an empty object if the interface is not
196205
* available after activation is complete. This will happen if there is no cli
@@ -226,6 +235,9 @@ export async function activate(ctx: ExtensionContext): Promise<CodeQLExtensionIn
226235
void showAndLogErrorMessage(`Can't execute ${command}: waiting to finish loading CodeQL CLI.`);
227236
}));
228237

238+
// Checking the vscode version should not block extension activation.
239+
void assertVSCodeVersionGreaterThan(MIN_VERSION, ctx);
240+
229241
interface DistributionUpdateConfig {
230242
isUserInitiated: boolean;
231243
shouldDisplayMessageWhenNoUpdates: boolean;
@@ -1348,3 +1360,43 @@ function registerRemoteQueryTextProvider() {
13481360
},
13491361
});
13501362
}
1363+
1364+
const avoidVersionCheck = 'avoid-version-check-at-startup';
1365+
const lastVersionChecked = 'last-version-checked';
1366+
async function assertVSCodeVersionGreaterThan(minVersion: string, ctx: ExtensionContext) {
1367+
1368+
// Check if we should reset the version check.
1369+
const lastVersion = await ctx.globalState.get(lastVersionChecked);
1370+
await ctx.globalState.update(lastVersionChecked, vscodeVersion);
1371+
1372+
if (lastVersion !== minVersion) {
1373+
// In this case, the version has changed since the last time we checked.
1374+
// If the user has previously opted out of this check, then user has updated their
1375+
// vscode instance since then, so we should check again. Any future warning would
1376+
// be for a different version of vscode.
1377+
await ctx.globalState.update(avoidVersionCheck, false);
1378+
}
1379+
if (await ctx.globalState.get(avoidVersionCheck)) {
1380+
return;
1381+
}
1382+
try {
1383+
const parsedVersion = semver.parse(vscodeVersion);
1384+
const parsedMinVersion = semver.parse(minVersion);
1385+
if (!parsedVersion || !parsedMinVersion) {
1386+
void showAndLogWarningMessage(
1387+
`Could not do a version check of vscode because could not parse version number: actual vscode version ${vscodeVersion} or minimum supported vscode version ${minVersion}.`
1388+
);
1389+
return;
1390+
}
1391+
1392+
if (semver.lt(parsedVersion, parsedMinVersion)) {
1393+
const message = `The CodeQL extension requires VS Code version ${minVersion} or later. Current version is ${vscodeVersion}. Please update VS Code to get the latest features of CodeQL.`;
1394+
const result = await showBinaryChoiceDialog(message, false, 'OK', 'Don\'t show again');
1395+
if (!result) {
1396+
await ctx.globalState.update(avoidVersionCheck, true);
1397+
}
1398+
}
1399+
} catch (e) {
1400+
void showAndLogWarningMessage(`Could not do a version check because of an error: ${getErrorMessage(e)}`);
1401+
}
1402+
}

extensions/ql-vscode/src/helpers.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,17 @@ async function internalShowAndLog(
110110
* @param message The message to show.
111111
* @param modal If true (the default), show a modal dialog box, otherwise dialog is non-modal and can
112112
* be closed even if the user does not make a choice.
113+
* @param yesTitle The text in the box indicating the affirmative choice.
114+
* @param noTitle The text in the box indicating the negative choice.
113115
*
114116
* @return
115117
* `true` if the user clicks 'Yes',
116118
* `false` if the user clicks 'No' or cancels the dialog,
117119
* `undefined` if the dialog is closed without the user making a choice.
118120
*/
119-
export async function showBinaryChoiceDialog(message: string, modal = true): Promise<boolean | undefined> {
120-
const yesItem = { title: 'Yes', isCloseAffordance: false };
121-
const noItem = { title: 'No', isCloseAffordance: true };
121+
export async function showBinaryChoiceDialog(message: string, modal = true, yesTitle = 'Yes', noTitle = 'No'): Promise<boolean | undefined> {
122+
const yesItem = { title: yesTitle, isCloseAffordance: false };
123+
const noItem = { title: noTitle, isCloseAffordance: true };
122124
const chosenItem = await Window.showInformationMessage(message, { modal }, yesItem, noItem);
123125
if (!chosenItem) {
124126
return undefined;

0 commit comments

Comments
 (0)