Merge remote-tracking branch 'origin/main' into koesie10/deprecate-lgtm-download
This commit is contained in:
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -18,4 +18,8 @@ yarn.lock merge=binary
|
||||
# https://mirrors.edge.kernel.org/pub/software/scm/git/docs/gitattributes.html
|
||||
# suggests that this might interleave lines arbitrarily, but empirically
|
||||
# it keeps added chunks contiguous
|
||||
CHANGELOG.md merge=union
|
||||
CHANGELOG.md merge=union
|
||||
|
||||
# Mark some JSON files containing test data as generated so they are not included
|
||||
# as part of diffs or language statistics.
|
||||
extensions/ql-vscode/src/stories/remote-queries/data/*.json linguist-generated
|
||||
|
||||
8
.github/workflows/main.yml
vendored
8
.github/workflows/main.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '16.13.0'
|
||||
node-version: '16.14.0'
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: extensions/ql-vscode
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '16.13.0'
|
||||
node-version: '16.14.0'
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: extensions/ql-vscode
|
||||
@@ -139,7 +139,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
version: ['v2.6.3', 'v2.7.6', 'v2.8.5', 'v2.9.4', 'v2.10.3', 'nightly']
|
||||
version: ['v2.6.3', 'v2.7.6', 'v2.8.5', 'v2.9.4', 'v2.10.4', 'nightly']
|
||||
env:
|
||||
CLI_VERSION: ${{ matrix.version }}
|
||||
NIGHTLY_URL: ${{ needs.find-nightly.outputs.url }}
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '16.13.0'
|
||||
node-version: '16.14.0'
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: extensions/ql-vscode
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '16.13.0'
|
||||
node-version: '16.14.0'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
||||
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@@ -124,6 +124,14 @@
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/extensions/ql-vscode/out/**/*.js",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Launch Storybook",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}/extensions/ql-vscode",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "storybook"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -77,6 +77,20 @@ $ vscode/scripts/code-cli.sh --install-extension dist/vscode-codeql-*.vsix # if
|
||||
|
||||
You can use VS Code to debug the extension without explicitly installing it. Just open this directory as a workspace in VS Code, and hit `F5` to start a debugging session.
|
||||
|
||||
### Storybook
|
||||
|
||||
You can use [Storybook](https://storybook.js.org/) to preview React components outside VSCode. Inside the `extensions/ql-vscode` directory, run:
|
||||
|
||||
```shell
|
||||
npm run storybook
|
||||
```
|
||||
|
||||
Your browser should automatically open to the Storybook UI. Stories live in the `src/stories` directory.
|
||||
|
||||
Alternatively, you can start Storybook inside of VSCode. There is a VSCode launch configuration for starting Storybook. It can be found in the debug view.
|
||||
|
||||
More information about Storybook can be found inside the **Overview** page once you have launched Storybook.
|
||||
|
||||
### Running the unit tests and integration tests that do not require a CLI instance
|
||||
|
||||
Unit tests and many integration tests do not require a copy of the CodeQL CLI.
|
||||
|
||||
2
extensions/ql-vscode/.npmrc
Normal file
2
extensions/ql-vscode/.npmrc
Normal file
@@ -0,0 +1,2 @@
|
||||
# Storybook requires this option to be set. See https://github.com/storybookjs/storybook/issues/18298
|
||||
legacy-peer-deps=true
|
||||
@@ -1 +1 @@
|
||||
v16.13.0
|
||||
v16.14.0
|
||||
|
||||
19
extensions/ql-vscode/.storybook/main.ts
Normal file
19
extensions/ql-vscode/.storybook/main.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { StorybookConfig } from '@storybook/core-common';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: [
|
||||
'../src/**/*.stories.mdx',
|
||||
'../src/**/*.stories.@(js|jsx|ts|tsx)'
|
||||
],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-interactions'
|
||||
],
|
||||
framework: '@storybook/react',
|
||||
core: {
|
||||
builder: '@storybook/builder-webpack5'
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
7
extensions/ql-vscode/.storybook/manager.ts
Normal file
7
extensions/ql-vscode/.storybook/manager.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { addons } from '@storybook/addons';
|
||||
import { themes } from '@storybook/theming';
|
||||
|
||||
addons.setConfig({
|
||||
theme: themes.dark,
|
||||
enableShortcuts: false,
|
||||
});
|
||||
37
extensions/ql-vscode/.storybook/preview.ts
Normal file
37
extensions/ql-vscode/.storybook/preview.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { themes } from '@storybook/theming';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
// Allow all stories/components to use Codicons
|
||||
import '@vscode/codicons/dist/codicon.css';
|
||||
|
||||
import '../src/stories/vscode-theme.css';
|
||||
|
||||
// https://storybook.js.org/docs/react/configure/overview#configure-story-rendering
|
||||
export const parameters = {
|
||||
// All props starting with `on` will automatically receive an action as a prop
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
// All props matching these names will automatically get the correct control
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
// Use a dark theme to be aligned with VSCode
|
||||
docs: {
|
||||
theme: themes.dark,
|
||||
},
|
||||
backgrounds: {
|
||||
default: 'dark',
|
||||
values: [
|
||||
{
|
||||
name: 'dark',
|
||||
value: '#1e1e1e',
|
||||
},
|
||||
],
|
||||
}
|
||||
};
|
||||
|
||||
(window as any).acquireVsCodeApi = () => ({
|
||||
postMessage: action('post-vscode-message')
|
||||
});
|
||||
@@ -2,8 +2,19 @@
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
- Add ability for users to download databases directly from GitHub. [#1466](https://github.com/github/vscode-codeql/pull/1466)
|
||||
- Remove ability to download databases from LGTM. [#1467](https://github.com/github/vscode-codeql/pull/1467)
|
||||
- Removed the ability to manually upgrade databases from the context menu on databases. Databases are non-destructively upgraded automatically so
|
||||
for most users this was not needed. For advanced users this is still available in the Command Palette. [#1501](https://github.com/github/vscode-codeql/pull/1501)
|
||||
|
||||
## 1.6.12 - 1 September 2022
|
||||
|
||||
- Add ability for users to download databases directly from GitHub. [#1485](https://github.com/github/vscode-codeql/pull/1485)
|
||||
- Fix a race condition that could cause a failure to open the evaluator log when running a query. [#1490](https://github.com/github/vscode-codeql/pull/1490)
|
||||
- Fix an error when running a query with an older version of the CodeQL CLI. [#1490](https://github.com/github/vscode-codeql/pull/1490)
|
||||
|
||||
## 1.6.11 - 25 August 2022
|
||||
|
||||
No user facing changes.
|
||||
|
||||
## 1.6.10 - 9 August 2022
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as gulp from 'gulp';
|
||||
import { compileTypeScript, watchTypeScript, copyViewCss, cleanOutput, watchCss } from './typescript';
|
||||
import { compileTypeScript, watchTypeScript, cleanOutput } from './typescript';
|
||||
import { compileTextMateGrammar } from './textmate';
|
||||
import { copyTestData } from './tests';
|
||||
import { compileView, watchView } from './webpack';
|
||||
@@ -10,7 +10,7 @@ export const buildWithoutPackage =
|
||||
gulp.series(
|
||||
cleanOutput,
|
||||
gulp.parallel(
|
||||
compileTypeScript, compileTextMateGrammar, compileView, copyTestData, copyViewCss
|
||||
compileTypeScript, compileTextMateGrammar, compileView, copyTestData
|
||||
)
|
||||
);
|
||||
|
||||
@@ -23,6 +23,5 @@ export {
|
||||
copyTestData,
|
||||
injectAppInsightsKey,
|
||||
compileView,
|
||||
watchCss
|
||||
};
|
||||
export default gulp.series(buildWithoutPackage, injectAppInsightsKey, packageExtension);
|
||||
|
||||
@@ -39,13 +39,3 @@ export function compileTypeScript() {
|
||||
export function watchTypeScript() {
|
||||
gulp.watch('src/**/*.ts', compileTypeScript);
|
||||
}
|
||||
|
||||
export function watchCss() {
|
||||
gulp.watch('src/**/*.css', copyViewCss);
|
||||
}
|
||||
|
||||
/** Copy CSS files for the results view into the output directory. */
|
||||
export function copyViewCss() {
|
||||
return gulp.src('src/**/view/*.css')
|
||||
.pipe(gulp.dest('out'));
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import * as path from 'path';
|
||||
import * as webpack from 'webpack';
|
||||
import * as MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
|
||||
export const config: webpack.Configuration = {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
resultsView: './src/view/results.tsx',
|
||||
compareView: './src/compare/view/Compare.tsx',
|
||||
remoteQueriesView: './src/remote-queries/view/RemoteQueries.tsx',
|
||||
webview: './src/view/webview.tsx'
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, '..', 'out'),
|
||||
@@ -31,9 +30,7 @@ export const config: webpack.Configuration = {
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader'
|
||||
},
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
@@ -53,17 +50,31 @@ export const config: webpack.Configuration = {
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'style-loader'
|
||||
},
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf|eot)$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]',
|
||||
outputPath: 'fonts/',
|
||||
// We need this to make Webpack use the correct path for the fonts.
|
||||
// Without this, the CSS file will use `url([object Module])`
|
||||
esModule: false
|
||||
}
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
}
|
||||
},
|
||||
plugins: [new MiniCssExtractPlugin()],
|
||||
};
|
||||
|
||||
33567
extensions/ql-vscode/package-lock.json
generated
33567
extensions/ql-vscode/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
"description": "CodeQL for Visual Studio Code",
|
||||
"author": "GitHub",
|
||||
"private": true,
|
||||
"version": "1.6.11",
|
||||
"version": "1.6.13",
|
||||
"publisher": "GitHub",
|
||||
"license": "MIT",
|
||||
"icon": "media/VS-marketplace-CodeQL-icon.png",
|
||||
@@ -288,7 +288,7 @@
|
||||
"default": "",
|
||||
"pattern": "^$|^(?:[a-zA-Z0-9]+-)*[a-zA-Z0-9]+/[a-zA-Z0-9-_]+$",
|
||||
"patternErrorMessage": "Please enter a valid GitHub repository",
|
||||
"markdownDescription": "[For internal use only] The name of the GitHub repository where you can view the progress and results of the \"Run Variant Analysis\" command. The repository should be of the form `<owner>/<repo>`)."
|
||||
"markdownDescription": "[For internal use only] The name of the GitHub repository in which the GitHub Actions workflow is run when using the \"Run Variant Analysis\" command. The repository should be of the form `<owner>/<repo>`)."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -724,11 +724,6 @@
|
||||
"group": "9_qlCommands",
|
||||
"when": "view == codeQLDatabases"
|
||||
},
|
||||
{
|
||||
"command": "codeQLDatabases.upgradeDatabase",
|
||||
"group": "9_qlCommands",
|
||||
"when": "view == codeQLDatabases"
|
||||
},
|
||||
{
|
||||
"command": "codeQLDatabases.renameDatabase",
|
||||
"group": "9_qlCommands",
|
||||
@@ -752,7 +747,7 @@
|
||||
{
|
||||
"command": "codeQLQueryHistory.removeHistoryItem",
|
||||
"group": "9_qlCommands",
|
||||
"when": "viewItem == interpretedResultsItem || viewItem == rawResultsItem || viewItem == remoteResultsItem || viewItem == cancelledResultsItem"
|
||||
"when": "viewItem == interpretedResultsItem || viewItem == rawResultsItem || viewItem == remoteResultsItem || viewItem == cancelledResultsItem || viewItem == cancelledRemoteResultsItem"
|
||||
},
|
||||
{
|
||||
"command": "codeQLQueryHistory.setLabel",
|
||||
@@ -827,7 +822,7 @@
|
||||
{
|
||||
"command": "codeQLQueryHistory.openOnGithub",
|
||||
"group": "9_qlCommands",
|
||||
"when": "viewItem == remoteResultsItem || viewItem == inProgressRemoteResultsItem || viewItem == cancelledResultsItem"
|
||||
"when": "viewItem == remoteResultsItem || viewItem == inProgressRemoteResultsItem || viewItem == cancelledRemoteResultsItem"
|
||||
},
|
||||
{
|
||||
"command": "codeQLQueryHistory.copyRepoList",
|
||||
@@ -878,6 +873,10 @@
|
||||
}
|
||||
],
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "codeQL.authenticateToGitHub",
|
||||
"when": "config.codeQL.canary"
|
||||
},
|
||||
{
|
||||
"command": "codeQL.runQuery",
|
||||
"when": "resourceLangId == ql && resourceExtname == .ql"
|
||||
@@ -1184,7 +1183,6 @@
|
||||
"watch": "npm-run-all -p watch:*",
|
||||
"watch:extension": "tsc --watch",
|
||||
"watch:webpack": "gulp watchView",
|
||||
"watch:css": "gulp watchCss",
|
||||
"test": "mocha --exit -r ts-node/register test/pure-tests/**/*.ts",
|
||||
"preintegration": "rm -rf ./out/vscode-tests && gulp",
|
||||
"integration": "node ./out/vscode-tests/run-integration-tests.js no-workspace,minimal-workspace",
|
||||
@@ -1192,18 +1190,20 @@
|
||||
"update-vscode": "node ./node_modules/vscode/bin/install",
|
||||
"format": "tsfmt -r && eslint src test --ext .ts,.tsx --fix",
|
||||
"lint": "eslint src test --ext .ts,.tsx --max-warnings=0",
|
||||
"format-staged": "lint-staged"
|
||||
"format-staged": "lint-staged",
|
||||
"storybook": "start-storybook -p 6006",
|
||||
"build-storybook": "build-storybook"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/rest": "^18.5.6",
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/rest": "^18.5.6",
|
||||
"@primer/octicons-react": "^16.3.0",
|
||||
"@primer/react": "^35.0.0",
|
||||
"@vscode/codicons": "^0.0.31",
|
||||
"@vscode/webview-ui-toolkit": "^1.0.0",
|
||||
"@vscode/webview-ui-toolkit": "^1.0.1",
|
||||
"child-process-promise": "^2.2.1",
|
||||
"classnames": "~2.2.6",
|
||||
"d3": "^6.3.1",
|
||||
"d3": "^7.6.1",
|
||||
"d3-graphviz": "^2.6.1",
|
||||
"fs-extra": "^10.0.1",
|
||||
"glob-promise": "^4.2.2",
|
||||
@@ -1234,11 +1234,20 @@
|
||||
"zip-a-folder": "~1.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.13",
|
||||
"@storybook/addon-actions": "^6.5.10",
|
||||
"@storybook/addon-essentials": "^6.5.10",
|
||||
"@storybook/addon-interactions": "^6.5.10",
|
||||
"@storybook/addon-links": "^6.5.10",
|
||||
"@storybook/builder-webpack5": "^6.5.10",
|
||||
"@storybook/manager-webpack5": "^6.5.10",
|
||||
"@storybook/react": "^6.5.10",
|
||||
"@storybook/testing-library": "^0.0.13",
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/chai-as-promised": "~7.1.2",
|
||||
"@types/child-process-promise": "^2.2.1",
|
||||
"@types/classnames": "~2.2.9",
|
||||
"@types/d3": "^6.2.0",
|
||||
"@types/d3": "^7.4.0",
|
||||
"@types/d3-graphviz": "^2.6.6",
|
||||
"@types/del": "^4.0.0",
|
||||
"@types/fs-extra": "^9.0.6",
|
||||
@@ -1267,17 +1276,21 @@
|
||||
"@types/unzipper": "~0.10.1",
|
||||
"@types/vscode": "^1.59.0",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"@types/webpack-env": "^1.18.0",
|
||||
"@types/xml2js": "~0.4.4",
|
||||
"@typescript-eslint/eslint-plugin": "^4.26.0",
|
||||
"@typescript-eslint/parser": "^4.26.0",
|
||||
"ansi-colors": "^4.1.1",
|
||||
"applicationinsights": "^1.8.7",
|
||||
"babel-loader": "^8.2.5",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "~7.1.1",
|
||||
"css-loader": "~3.1.0",
|
||||
"del": "^6.0.0",
|
||||
"eslint": "~6.8.0",
|
||||
"eslint-plugin-react": "~7.19.0",
|
||||
"eslint-plugin-storybook": "^0.6.4",
|
||||
"file-loader": "^6.2.0",
|
||||
"glob": "^7.1.4",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-replace": "^1.1.3",
|
||||
@@ -1285,6 +1298,7 @@
|
||||
"gulp-typescript": "^5.0.1",
|
||||
"husky": "~4.3.8",
|
||||
"lint-staged": "~10.2.2",
|
||||
"mini-css-extract-plugin": "^2.6.1",
|
||||
"mocha": "^10.0.0",
|
||||
"mocha-sinon": "~2.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
@@ -1292,7 +1306,6 @@
|
||||
"proxyquire": "~2.1.3",
|
||||
"sinon": "~13.0.1",
|
||||
"sinon-chai": "~3.5.0",
|
||||
"style-loader": "~3.3.1",
|
||||
"through2": "^4.0.2",
|
||||
"ts-loader": "^8.1.0",
|
||||
"ts-node": "^10.7.0",
|
||||
|
||||
118
extensions/ql-vscode/src/abstract-interface-manager.ts
Normal file
118
extensions/ql-vscode/src/abstract-interface-manager.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import {
|
||||
WebviewPanel,
|
||||
ExtensionContext,
|
||||
window as Window,
|
||||
ViewColumn,
|
||||
Uri,
|
||||
WebviewPanelOptions,
|
||||
WebviewOptions
|
||||
} from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
import { DisposableObject } from './pure/disposable-object';
|
||||
import { tmpDir } from './helpers';
|
||||
import { getHtmlForWebview, WebviewMessage, WebviewView } from './interface-utils';
|
||||
|
||||
export type InterfacePanelConfig = {
|
||||
viewId: string;
|
||||
title: string;
|
||||
viewColumn: ViewColumn;
|
||||
view: WebviewView;
|
||||
preserveFocus?: boolean;
|
||||
additionalOptions?: WebviewPanelOptions & WebviewOptions;
|
||||
}
|
||||
|
||||
export abstract class AbstractInterfaceManager<ToMessage extends WebviewMessage, FromMessage extends WebviewMessage> extends DisposableObject {
|
||||
protected panel: WebviewPanel | undefined;
|
||||
protected panelLoaded = false;
|
||||
protected panelLoadedCallBacks: (() => void)[] = [];
|
||||
|
||||
constructor(
|
||||
protected readonly ctx: ExtensionContext
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected get isShowingPanel() {
|
||||
return !!this.panel;
|
||||
}
|
||||
|
||||
protected getPanel(): WebviewPanel {
|
||||
if (this.panel == undefined) {
|
||||
const { ctx } = this;
|
||||
|
||||
const config = this.getPanelConfig();
|
||||
|
||||
this.panel = Window.createWebviewPanel(
|
||||
config.viewId,
|
||||
config.title,
|
||||
{ viewColumn: ViewColumn.Active, preserveFocus: true },
|
||||
{
|
||||
enableScripts: true,
|
||||
enableFindWidget: true,
|
||||
retainContextWhenHidden: true,
|
||||
...config.additionalOptions,
|
||||
localResourceRoots: [
|
||||
...(config.additionalOptions?.localResourceRoots ?? []),
|
||||
Uri.file(tmpDir.name),
|
||||
Uri.file(path.join(ctx.extensionPath, 'out'))
|
||||
],
|
||||
}
|
||||
);
|
||||
this.push(
|
||||
this.panel.onDidDispose(
|
||||
() => {
|
||||
this.panel = undefined;
|
||||
this.panelLoaded = false;
|
||||
this.onPanelDispose();
|
||||
},
|
||||
null,
|
||||
ctx.subscriptions
|
||||
)
|
||||
);
|
||||
|
||||
this.panel.webview.html = getHtmlForWebview(
|
||||
ctx,
|
||||
this.panel.webview,
|
||||
config.view,
|
||||
{
|
||||
allowInlineStyles: true,
|
||||
}
|
||||
);
|
||||
this.push(
|
||||
this.panel.webview.onDidReceiveMessage(
|
||||
async (e) => this.onMessage(e),
|
||||
undefined,
|
||||
ctx.subscriptions
|
||||
)
|
||||
);
|
||||
}
|
||||
return this.panel;
|
||||
}
|
||||
|
||||
protected abstract getPanelConfig(): InterfacePanelConfig;
|
||||
|
||||
protected abstract onPanelDispose(): void;
|
||||
|
||||
protected abstract onMessage(msg: FromMessage): Promise<void>;
|
||||
|
||||
protected waitForPanelLoaded(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
if (this.panelLoaded) {
|
||||
resolve();
|
||||
} else {
|
||||
this.panelLoadedCallBacks.push(resolve);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected onWebViewLoaded(): void {
|
||||
this.panelLoaded = true;
|
||||
this.panelLoadedCallBacks.forEach((cb) => cb());
|
||||
this.panelLoadedCallBacks = [];
|
||||
}
|
||||
|
||||
protected postMessage(msg: ToMessage): Thenable<boolean> {
|
||||
return this.getPanel().webview.postMessage(msg);
|
||||
}
|
||||
}
|
||||
@@ -76,16 +76,27 @@ export class Credentials {
|
||||
}));
|
||||
}
|
||||
|
||||
async getOctokit(): Promise<Octokit.Octokit> {
|
||||
/**
|
||||
* Creates or returns an instance of Octokit.
|
||||
*
|
||||
* @param requireAuthentication Whether the Octokit instance needs to be authenticated as user.
|
||||
* @returns An instance of Octokit.
|
||||
*/
|
||||
async getOctokit(requireAuthentication = true): Promise<Octokit.Octokit> {
|
||||
if (this.octokit) {
|
||||
return this.octokit;
|
||||
}
|
||||
|
||||
this.octokit = await this.createOctokit(true);
|
||||
// octokit shouldn't be undefined, since we've set "createIfNone: true".
|
||||
// The following block is mainly here to prevent a compiler error.
|
||||
this.octokit = await this.createOctokit(requireAuthentication);
|
||||
|
||||
if (!this.octokit) {
|
||||
throw new Error('Did not initialize Octokit.');
|
||||
if (requireAuthentication) {
|
||||
throw new Error('Did not initialize Octokit.');
|
||||
}
|
||||
|
||||
// We don't want to set this in this.octokit because that would prevent
|
||||
// authenticating when requireCredentials is true.
|
||||
return new Octokit.Octokit({ retry });
|
||||
}
|
||||
return this.octokit;
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ export class CodeQLCliServer implements Disposable {
|
||||
/**
|
||||
* Restart the server when the current command terminates
|
||||
*/
|
||||
private restartCliServer(): void {
|
||||
restartCliServer(): void {
|
||||
const callback = (): void => {
|
||||
try {
|
||||
this.killProcessIfRunning();
|
||||
@@ -683,7 +683,7 @@ export class CodeQLCliServer implements Disposable {
|
||||
const subcommandArgs = [
|
||||
'--format=text',
|
||||
`--end-summary=${endSummaryPath}`,
|
||||
'--sourcemap',
|
||||
...(await this.cliConstraints.supportsSourceMap() ? ['--sourcemap'] : []),
|
||||
inputPath,
|
||||
outputPath
|
||||
];
|
||||
@@ -1261,9 +1261,17 @@ export class CliVersionConstraint {
|
||||
|
||||
/**
|
||||
* CLI version where database registration was introduced
|
||||
*/
|
||||
*/
|
||||
public static CLI_VERSION_WITH_DB_REGISTRATION = new SemVer('2.4.1');
|
||||
|
||||
/**
|
||||
* CLI version where non destructive upgrades were introduced.
|
||||
*
|
||||
* This was landed in multiple parts so this is the version where all necessary feature were supported.
|
||||
*/
|
||||
public static CLI_VERSION_WITH_NON_DESTRUCTIVE_UPGRADES = new SemVer('2.4.2');
|
||||
|
||||
|
||||
/**
|
||||
* CLI version where the `--allow-library-packs` option to `codeql resolve queries` was
|
||||
* introduced.
|
||||
@@ -1322,6 +1330,11 @@ export class CliVersionConstraint {
|
||||
*/
|
||||
public static CLI_VERSION_WITH_PER_QUERY_EVAL_LOG = new SemVer('2.9.0');
|
||||
|
||||
/**
|
||||
* CLI version that supports the `--sourcemap` option for log generation.
|
||||
*/
|
||||
public static CLI_VERSION_WITH_SOURCEMAP = new SemVer('2.10.3');
|
||||
|
||||
constructor(private readonly cli: CodeQLCliServer) {
|
||||
/**/
|
||||
}
|
||||
@@ -1354,6 +1367,10 @@ export class CliVersionConstraint {
|
||||
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_DB_REGISTRATION);
|
||||
}
|
||||
|
||||
async supportsNonDestructiveUpgrades(): Promise<boolean> {
|
||||
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_NON_DESTRUCTIVE_UPGRADES);
|
||||
}
|
||||
|
||||
async supportsDatabaseUnbundle() {
|
||||
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_DATABASE_UNBUNDLE);
|
||||
}
|
||||
@@ -1389,4 +1406,8 @@ export class CliVersionConstraint {
|
||||
async supportsPerQueryEvalLog() {
|
||||
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_PER_QUERY_EVAL_LOG);
|
||||
}
|
||||
|
||||
async supportsSourceMap() {
|
||||
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_SOURCEMAP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import { DisposableObject } from '../pure/disposable-object';
|
||||
import {
|
||||
WebviewPanel,
|
||||
ExtensionContext,
|
||||
window as Window,
|
||||
ViewColumn,
|
||||
Uri,
|
||||
} from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
import { tmpDir } from '../helpers';
|
||||
import {
|
||||
FromCompareViewMessage,
|
||||
ToCompareViewMessage,
|
||||
@@ -17,26 +11,24 @@ import {
|
||||
import { Logger } from '../logging';
|
||||
import { CodeQLCliServer } from '../cli';
|
||||
import { DatabaseManager } from '../databases';
|
||||
import { getHtmlForWebview, jumpToLocation } from '../interface-utils';
|
||||
import { jumpToLocation } from '../interface-utils';
|
||||
import { transformBqrsResultSet, RawResultSet, BQRSInfo } from '../pure/bqrs-cli-types';
|
||||
import resultsDiff from './resultsDiff';
|
||||
import { CompletedLocalQueryInfo } from '../query-results';
|
||||
import { getErrorMessage } from '../pure/helpers-pure';
|
||||
import { HistoryItemLabelProvider } from '../history-item-label-provider';
|
||||
import { AbstractInterfaceManager, InterfacePanelConfig } from '../abstract-interface-manager';
|
||||
|
||||
interface ComparePair {
|
||||
from: CompletedLocalQueryInfo;
|
||||
to: CompletedLocalQueryInfo;
|
||||
}
|
||||
|
||||
export class CompareInterfaceManager extends DisposableObject {
|
||||
export class CompareInterfaceManager extends AbstractInterfaceManager<ToCompareViewMessage, FromCompareViewMessage> {
|
||||
private comparePair: ComparePair | undefined;
|
||||
private panel: WebviewPanel | undefined;
|
||||
private panelLoaded = false;
|
||||
private panelLoadedCallBacks: (() => void)[] = [];
|
||||
|
||||
constructor(
|
||||
private ctx: ExtensionContext,
|
||||
ctx: ExtensionContext,
|
||||
private databaseManager: DatabaseManager,
|
||||
private cliServer: CodeQLCliServer,
|
||||
private logger: Logger,
|
||||
@@ -45,7 +37,7 @@ export class CompareInterfaceManager extends DisposableObject {
|
||||
item: CompletedLocalQueryInfo
|
||||
) => Promise<void>
|
||||
) {
|
||||
super();
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
async showResults(
|
||||
@@ -103,73 +95,24 @@ export class CompareInterfaceManager extends DisposableObject {
|
||||
}
|
||||
}
|
||||
|
||||
getPanel(): WebviewPanel {
|
||||
if (this.panel == undefined) {
|
||||
const { ctx } = this;
|
||||
const panel = (this.panel = Window.createWebviewPanel(
|
||||
'compareView',
|
||||
'Compare CodeQL Query Results',
|
||||
{ viewColumn: ViewColumn.Active, preserveFocus: true },
|
||||
{
|
||||
enableScripts: true,
|
||||
enableFindWidget: true,
|
||||
retainContextWhenHidden: true,
|
||||
localResourceRoots: [
|
||||
Uri.file(tmpDir.name),
|
||||
Uri.file(path.join(this.ctx.extensionPath, 'out')),
|
||||
],
|
||||
}
|
||||
));
|
||||
this.push(this.panel.onDidDispose(
|
||||
() => {
|
||||
this.panel = undefined;
|
||||
this.comparePair = undefined;
|
||||
},
|
||||
null,
|
||||
ctx.subscriptions
|
||||
));
|
||||
|
||||
const scriptPathOnDisk = Uri.file(
|
||||
ctx.asAbsolutePath('out/compareView.js')
|
||||
);
|
||||
|
||||
const stylesheetPathOnDisk = Uri.file(
|
||||
ctx.asAbsolutePath('out/view/resultsView.css')
|
||||
);
|
||||
|
||||
panel.webview.html = getHtmlForWebview(
|
||||
panel.webview,
|
||||
scriptPathOnDisk,
|
||||
[stylesheetPathOnDisk],
|
||||
false
|
||||
);
|
||||
this.push(panel.webview.onDidReceiveMessage(
|
||||
async (e) => this.handleMsgFromView(e),
|
||||
undefined,
|
||||
ctx.subscriptions
|
||||
));
|
||||
}
|
||||
return this.panel;
|
||||
protected getPanelConfig(): InterfacePanelConfig {
|
||||
return {
|
||||
viewId: 'compareView',
|
||||
title: 'Compare CodeQL Query Results',
|
||||
viewColumn: ViewColumn.Active,
|
||||
preserveFocus: true,
|
||||
view: 'compare',
|
||||
};
|
||||
}
|
||||
|
||||
private waitForPanelLoaded(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
if (this.panelLoaded) {
|
||||
resolve();
|
||||
} else {
|
||||
this.panelLoadedCallBacks.push(resolve);
|
||||
}
|
||||
});
|
||||
protected onPanelDispose(): void {
|
||||
this.comparePair = undefined;
|
||||
}
|
||||
|
||||
private async handleMsgFromView(
|
||||
msg: FromCompareViewMessage
|
||||
): Promise<void> {
|
||||
protected async onMessage(msg: FromCompareViewMessage): Promise<void> {
|
||||
switch (msg.t) {
|
||||
case 'compareViewLoaded':
|
||||
this.panelLoaded = true;
|
||||
this.panelLoadedCallBacks.forEach((cb) => cb());
|
||||
this.panelLoadedCallBacks = [];
|
||||
this.onWebViewLoaded();
|
||||
break;
|
||||
|
||||
case 'changeCompare':
|
||||
@@ -186,10 +129,6 @@ export class CompareInterfaceManager extends DisposableObject {
|
||||
}
|
||||
}
|
||||
|
||||
private postMessage(msg: ToCompareViewMessage): Thenable<boolean> {
|
||||
return this.getPanel().webview.postMessage(msg);
|
||||
}
|
||||
|
||||
private async findCommonResultSetNames(
|
||||
from: CompletedLocalQueryInfo,
|
||||
to: CompletedLocalQueryInfo,
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
import { CodeQLCliServer } from './cli';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import * as Octokit from '@octokit/rest';
|
||||
import { retry } from '@octokit/plugin-retry';
|
||||
|
||||
import { DatabaseManager, DatabaseItem } from './databases';
|
||||
import {
|
||||
@@ -76,7 +78,7 @@ export async function promptImportInternetDatabase(
|
||||
export async function promptImportGithubDatabase(
|
||||
databaseManager: DatabaseManager,
|
||||
storagePath: string,
|
||||
credentials: Credentials,
|
||||
credentials: Credentials | undefined,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
cli?: CodeQLCliServer
|
||||
@@ -99,14 +101,15 @@ export async function promptImportGithubDatabase(
|
||||
throw new Error(`Invalid GitHub repository: ${githubRepo}`);
|
||||
}
|
||||
|
||||
const result = await convertGithubNwoToDatabaseUrl(githubRepo, credentials, progress);
|
||||
const octokit = credentials ? await credentials.getOctokit(true) : new Octokit.Octokit({ retry });
|
||||
|
||||
const result = await convertGithubNwoToDatabaseUrl(githubRepo, octokit, progress);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { databaseUrl, name, owner } = result;
|
||||
|
||||
const octokit = await credentials.getOctokit();
|
||||
/**
|
||||
* The 'token' property of the token object returned by `octokit.auth()`.
|
||||
* The object is undocumented, but looks something like this:
|
||||
@@ -118,14 +121,9 @@ export async function promptImportGithubDatabase(
|
||||
* We only need the actual token string.
|
||||
*/
|
||||
const octokitToken = (await octokit.auth() as { token: string })?.token;
|
||||
if (!octokitToken) {
|
||||
// Just print a generic error message for now. Ideally we could show more debugging info, like the
|
||||
// octokit object, but that would expose a user token.
|
||||
throw new Error('Unable to get GitHub token.');
|
||||
}
|
||||
const item = await databaseArchiveFetcher(
|
||||
databaseUrl,
|
||||
{ 'Accept': 'application/zip', 'Authorization': `Bearer ${octokitToken}` },
|
||||
{ 'Accept': 'application/zip', 'Authorization': octokitToken ? `Bearer ${octokitToken}` : '' },
|
||||
databaseManager,
|
||||
storagePath,
|
||||
`${owner}/${name}`,
|
||||
@@ -523,7 +521,7 @@ function convertGitHubUrlToNwo(githubUrl: string): string | undefined {
|
||||
|
||||
export async function convertGithubNwoToDatabaseUrl(
|
||||
githubRepo: string,
|
||||
credentials: Credentials,
|
||||
octokit: Octokit.Octokit,
|
||||
progress: ProgressCallback): Promise<{
|
||||
databaseUrl: string,
|
||||
owner: string,
|
||||
@@ -533,7 +531,6 @@ export async function convertGithubNwoToDatabaseUrl(
|
||||
const nwo = convertGitHubUrlToNwo(githubRepo) || githubRepo;
|
||||
const [owner, repo] = nwo.split('/');
|
||||
|
||||
const octokit = await credentials.getOctokit();
|
||||
const response = await octokit.request('GET /repos/:owner/:repo/code-scanning/codeql/databases', { owner, repo });
|
||||
|
||||
const languages = response.data.map((db: any) => db.language);
|
||||
|
||||
@@ -40,6 +40,7 @@ import {
|
||||
import { CancellationToken } from 'vscode';
|
||||
import { asyncFilter, getErrorMessage } from './pure/helpers-pure';
|
||||
import { Credentials } from './authentication';
|
||||
import { isCanary } from './config';
|
||||
|
||||
type ThemableIconPath = { light: string; dark: string } | string;
|
||||
|
||||
@@ -301,7 +302,7 @@ export class DatabaseUI extends DisposableObject {
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken
|
||||
) => {
|
||||
const credentials = await this.getCredentials();
|
||||
const credentials = isCanary() ? await this.getCredentials() : undefined;
|
||||
await this.handleChooseDatabaseGithub(credentials, progress, token);
|
||||
},
|
||||
{
|
||||
@@ -480,7 +481,7 @@ export class DatabaseUI extends DisposableObject {
|
||||
};
|
||||
|
||||
handleChooseDatabaseGithub = async (
|
||||
credentials: Credentials,
|
||||
credentials: Credentials | undefined,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken
|
||||
): Promise<DatabaseItem | undefined> => {
|
||||
|
||||
@@ -782,7 +782,7 @@ async function activateWithInstalledDistribution(
|
||||
});
|
||||
}
|
||||
|
||||
if (queryUris.length > 1) {
|
||||
if (queryUris.length > 1 && !await cliServer.cliConstraints.supportsNonDestructiveUpgrades()) {
|
||||
// Try to upgrade the current database before running any queries
|
||||
// so that the user isn't confronted with multiple upgrade
|
||||
// requests for each query to run.
|
||||
@@ -938,6 +938,8 @@ async function activateWithInstalledDistribution(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken
|
||||
) => {
|
||||
// We restart the CLI server too, to ensure they are the same version
|
||||
cliServer.restartCliServer();
|
||||
await qs.restartQueryServer(progress, token);
|
||||
void showAndLogInformationMessage('CodeQL Query Server restarted.', {
|
||||
outputLogger: queryServerLogger,
|
||||
@@ -970,7 +972,7 @@ async function activateWithInstalledDistribution(
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken
|
||||
) => {
|
||||
const credentials = await Credentials.initialize(ctx);
|
||||
const credentials = isCanary() ? await Credentials.initialize(ctx) : undefined;
|
||||
await databaseUI.handleChooseDatabaseGithub(credentials, progress, token);
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Uri,
|
||||
Location,
|
||||
Range,
|
||||
ExtensionContext,
|
||||
WebviewPanel,
|
||||
Webview,
|
||||
workspace,
|
||||
@@ -111,16 +112,36 @@ export function tryResolveLocation(
|
||||
}
|
||||
}
|
||||
|
||||
export type WebviewView = 'results' | 'compare' | 'remote-queries';
|
||||
|
||||
export interface WebviewMessage {
|
||||
t: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML to populate the given webview.
|
||||
* Uses a content security policy that only loads the given script.
|
||||
*/
|
||||
export function getHtmlForWebview(
|
||||
ctx: ExtensionContext,
|
||||
webview: Webview,
|
||||
scriptUriOnDisk: Uri,
|
||||
stylesheetUrisOnDisk: Uri[],
|
||||
allowInlineStyles: boolean
|
||||
view: WebviewView,
|
||||
{
|
||||
allowInlineStyles,
|
||||
}: {
|
||||
allowInlineStyles?: boolean;
|
||||
} = {
|
||||
allowInlineStyles: false,
|
||||
}
|
||||
): string {
|
||||
const scriptUriOnDisk = Uri.file(
|
||||
ctx.asAbsolutePath('out/webview.js')
|
||||
);
|
||||
|
||||
const stylesheetUrisOnDisk = [
|
||||
Uri.file(ctx.asAbsolutePath('out/webview.css'))
|
||||
];
|
||||
|
||||
// Convert the on-disk URIs into webview URIs.
|
||||
const scriptWebviewUri = webview.asWebviewUri(scriptUriOnDisk);
|
||||
const stylesheetWebviewUris = stylesheetUrisOnDisk.map(stylesheetUriOnDisk =>
|
||||
@@ -155,7 +176,7 @@ export function getHtmlForWebview(
|
||||
${stylesheetsHtmlLines.join(` ${os.EOL}`)}
|
||||
</head>
|
||||
<body>
|
||||
<div id=root>
|
||||
<div id=root data-view="${view}">
|
||||
</div>
|
||||
<script nonce="${nonce}" src="${scriptWebviewUri}">
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import * as path from 'path';
|
||||
import * as Sarif from 'sarif';
|
||||
import { DisposableObject } from './pure/disposable-object';
|
||||
import * as vscode from 'vscode';
|
||||
import {
|
||||
Diagnostic,
|
||||
@@ -14,7 +12,7 @@ import {
|
||||
import * as cli from './cli';
|
||||
import { CodeQLCliServer } from './cli';
|
||||
import { DatabaseEventKind, DatabaseItem, DatabaseManager } from './databases';
|
||||
import { showAndLogErrorMessage, tmpDir } from './helpers';
|
||||
import { showAndLogErrorMessage } from './helpers';
|
||||
import { assertNever, getErrorMessage, getErrorStack } from './pure/helpers-pure';
|
||||
import {
|
||||
FromResultsViewMsg,
|
||||
@@ -40,13 +38,13 @@ import {
|
||||
WebviewReveal,
|
||||
fileUriToWebviewUri,
|
||||
tryResolveLocation,
|
||||
getHtmlForWebview,
|
||||
shownLocationDecoration,
|
||||
shownLocationLineDecoration,
|
||||
jumpToLocation,
|
||||
} from './interface-utils';
|
||||
import { getDefaultResultSetName, ParsedResultSets } from './pure/interface-types';
|
||||
import { RawResultSet, transformBqrsResultSet, ResultSetSchema } from './pure/bqrs-cli-types';
|
||||
import { AbstractInterfaceManager, InterfacePanelConfig } from './abstract-interface-manager';
|
||||
import { PAGE_SIZE } from './config';
|
||||
import { CompletedLocalQueryInfo } from './query-results';
|
||||
import { HistoryItemLabelProvider } from './history-item-label-provider';
|
||||
@@ -122,12 +120,9 @@ function numInterpretedPages(interpretation: Interpretation | undefined): number
|
||||
return Math.ceil(n / pageSize);
|
||||
}
|
||||
|
||||
export class InterfaceManager extends DisposableObject {
|
||||
export class InterfaceManager extends AbstractInterfaceManager<IntoResultsViewMsg, FromResultsViewMsg> {
|
||||
private _displayedQuery?: CompletedLocalQueryInfo;
|
||||
private _interpretation?: Interpretation;
|
||||
private _panel: vscode.WebviewPanel | undefined;
|
||||
private _panelLoaded = false;
|
||||
private _panelLoadedCallBacks: (() => void)[] = [];
|
||||
|
||||
private readonly _diagnosticCollection = languages.createDiagnosticCollection(
|
||||
'codeql-query-results'
|
||||
@@ -140,7 +135,7 @@ export class InterfaceManager extends DisposableObject {
|
||||
public logger: Logger,
|
||||
private labelProvider: HistoryItemLabelProvider
|
||||
) {
|
||||
super();
|
||||
super(ctx);
|
||||
this.push(this._diagnosticCollection);
|
||||
this.push(
|
||||
vscode.window.onDidChangeTextEditorSelection(
|
||||
@@ -165,7 +160,7 @@ export class InterfaceManager extends DisposableObject {
|
||||
this.databaseManager.onDidChangeDatabaseItem(({ kind }) => {
|
||||
if (kind === DatabaseEventKind.Remove) {
|
||||
this._diagnosticCollection.clear();
|
||||
if (this.isShowingPanel()) {
|
||||
if (this.isShowingPanel) {
|
||||
void this.postMessage({
|
||||
t: 'untoggleShowProblems'
|
||||
});
|
||||
@@ -179,59 +174,81 @@ export class InterfaceManager extends DisposableObject {
|
||||
await this.postMessage({ t: 'navigatePath', direction });
|
||||
}
|
||||
|
||||
private isShowingPanel() {
|
||||
return !!this._panel;
|
||||
protected getPanelConfig(): InterfacePanelConfig {
|
||||
return {
|
||||
viewId: 'resultsView',
|
||||
title: 'CodeQL Query Results',
|
||||
viewColumn: this.chooseColumnForWebview(),
|
||||
preserveFocus: true,
|
||||
view: 'results',
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the webview panel, creating it if it doesn't already
|
||||
// exist.
|
||||
getPanel(): vscode.WebviewPanel {
|
||||
if (this._panel == undefined) {
|
||||
const { ctx } = this;
|
||||
const webViewColumn = this.chooseColumnForWebview();
|
||||
const panel = (this._panel = Window.createWebviewPanel(
|
||||
'resultsView', // internal name
|
||||
'CodeQL Query Results', // user-visible name
|
||||
{ viewColumn: webViewColumn, preserveFocus: true },
|
||||
{
|
||||
enableScripts: true,
|
||||
enableFindWidget: true,
|
||||
retainContextWhenHidden: true,
|
||||
localResourceRoots: [
|
||||
vscode.Uri.file(tmpDir.name),
|
||||
vscode.Uri.file(path.join(this.ctx.extensionPath, 'out'))
|
||||
]
|
||||
}
|
||||
));
|
||||
protected onPanelDispose(): void {
|
||||
this._displayedQuery = undefined;
|
||||
}
|
||||
|
||||
this.push(this._panel.onDidDispose(
|
||||
() => {
|
||||
this._panel = undefined;
|
||||
this._displayedQuery = undefined;
|
||||
this._panelLoaded = false;
|
||||
},
|
||||
null,
|
||||
ctx.subscriptions
|
||||
));
|
||||
const scriptPathOnDisk = vscode.Uri.file(
|
||||
ctx.asAbsolutePath('out/resultsView.js')
|
||||
);
|
||||
const stylesheetPathOnDisk = vscode.Uri.file(
|
||||
ctx.asAbsolutePath('out/view/resultsView.css')
|
||||
);
|
||||
panel.webview.html = getHtmlForWebview(
|
||||
panel.webview,
|
||||
scriptPathOnDisk,
|
||||
[stylesheetPathOnDisk],
|
||||
false
|
||||
);
|
||||
this.push(panel.webview.onDidReceiveMessage(
|
||||
async (e) => this.handleMsgFromView(e),
|
||||
undefined,
|
||||
ctx.subscriptions
|
||||
));
|
||||
protected async onMessage(msg: FromResultsViewMsg): Promise<void> {
|
||||
try {
|
||||
switch (msg.t) {
|
||||
case 'resultViewLoaded':
|
||||
this.onWebViewLoaded();
|
||||
break;
|
||||
case 'viewSourceFile': {
|
||||
await jumpToLocation(msg, this.databaseManager, this.logger);
|
||||
break;
|
||||
}
|
||||
case 'toggleDiagnostics': {
|
||||
if (msg.visible) {
|
||||
const databaseItem = this.databaseManager.findDatabaseItem(
|
||||
Uri.parse(msg.databaseUri)
|
||||
);
|
||||
if (databaseItem !== undefined) {
|
||||
await this.showResultsAsDiagnostics(
|
||||
msg.origResultsPaths,
|
||||
msg.metadata,
|
||||
databaseItem
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// TODO: Only clear diagnostics on the same database.
|
||||
this._diagnosticCollection.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'changeSort':
|
||||
await this.changeRawSortState(msg.resultSetName, msg.sortState);
|
||||
break;
|
||||
case 'changeInterpretedSort':
|
||||
await this.changeInterpretedSortState(msg.sortState);
|
||||
break;
|
||||
case 'changePage':
|
||||
if (msg.selectedTable === ALERTS_TABLE_NAME || msg.selectedTable === GRAPH_TABLE_NAME) {
|
||||
await this.showPageOfInterpretedResults(msg.pageNumber);
|
||||
}
|
||||
else {
|
||||
await this.showPageOfRawResults(
|
||||
msg.selectedTable,
|
||||
msg.pageNumber,
|
||||
// When we are in an unsorted state, we guarantee that
|
||||
// sortedResultsInfo doesn't have an entry for the current
|
||||
// result set. Use this to determine whether or not we use
|
||||
// the sorted bqrs file.
|
||||
!!this._displayedQuery?.completedQuery.sortedResultsInfo[msg.selectedTable]
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'openFile':
|
||||
await this.openFile(msg.filePath);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
} catch (e) {
|
||||
void showAndLogErrorMessage(getErrorMessage(e), {
|
||||
fullMessage: getErrorStack(e)
|
||||
});
|
||||
}
|
||||
return this._panel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,85 +313,6 @@ export class InterfaceManager extends DisposableObject {
|
||||
await this.showPageOfRawResults(resultSetName, 0, true);
|
||||
}
|
||||
|
||||
private async handleMsgFromView(msg: FromResultsViewMsg): Promise<void> {
|
||||
try {
|
||||
switch (msg.t) {
|
||||
case 'viewSourceFile': {
|
||||
await jumpToLocation(msg, this.databaseManager, this.logger);
|
||||
break;
|
||||
}
|
||||
case 'toggleDiagnostics': {
|
||||
if (msg.visible) {
|
||||
const databaseItem = this.databaseManager.findDatabaseItem(
|
||||
Uri.parse(msg.databaseUri)
|
||||
);
|
||||
if (databaseItem !== undefined) {
|
||||
await this.showResultsAsDiagnostics(
|
||||
msg.origResultsPaths,
|
||||
msg.metadata,
|
||||
databaseItem
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// TODO: Only clear diagnostics on the same database.
|
||||
this._diagnosticCollection.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'resultViewLoaded':
|
||||
this._panelLoaded = true;
|
||||
this._panelLoadedCallBacks.forEach((cb) => cb());
|
||||
this._panelLoadedCallBacks = [];
|
||||
break;
|
||||
case 'changeSort':
|
||||
await this.changeRawSortState(msg.resultSetName, msg.sortState);
|
||||
break;
|
||||
case 'changeInterpretedSort':
|
||||
await this.changeInterpretedSortState(msg.sortState);
|
||||
break;
|
||||
case 'changePage':
|
||||
if (msg.selectedTable === ALERTS_TABLE_NAME || msg.selectedTable === GRAPH_TABLE_NAME) {
|
||||
await this.showPageOfInterpretedResults(msg.pageNumber);
|
||||
}
|
||||
else {
|
||||
await this.showPageOfRawResults(
|
||||
msg.selectedTable,
|
||||
msg.pageNumber,
|
||||
// When we are in an unsorted state, we guarantee that
|
||||
// sortedResultsInfo doesn't have an entry for the current
|
||||
// result set. Use this to determine whether or not we use
|
||||
// the sorted bqrs file.
|
||||
!!this._displayedQuery?.completedQuery.sortedResultsInfo[msg.selectedTable]
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'openFile':
|
||||
await this.openFile(msg.filePath);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
} catch (e) {
|
||||
void showAndLogErrorMessage(getErrorMessage(e), {
|
||||
fullMessage: getErrorStack(e)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
postMessage(msg: IntoResultsViewMsg): Thenable<boolean> {
|
||||
return this.getPanel().webview.postMessage(msg);
|
||||
}
|
||||
|
||||
private waitForPanelLoaded(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
if (this._panelLoaded) {
|
||||
resolve();
|
||||
} else {
|
||||
this._panelLoadedCallBacks.push(resolve);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show query results in webview panel.
|
||||
* @param fullQuery Evaluation info for the executed query.
|
||||
|
||||
@@ -189,7 +189,7 @@ export class HistoryTreeDataProvider extends DisposableObject implements TreeDat
|
||||
break;
|
||||
case QueryStatus.Failed:
|
||||
treeItem.iconPath = this.failedIconPath;
|
||||
treeItem.contextValue = 'cancelledResultsItem';
|
||||
treeItem.contextValue = element.t === 'local' ? 'cancelledResultsItem' : 'cancelledRemoteResultsItem';
|
||||
break;
|
||||
default:
|
||||
assertNever(element.status);
|
||||
|
||||
@@ -10,6 +10,8 @@ import { RemoteQuery } from './remote-query';
|
||||
import { RemoteQueryFailureIndexItem, RemoteQueryResultIndex, RemoteQuerySuccessIndexItem } from './remote-query-result-index';
|
||||
import { getErrorMessage } from '../pure/helpers-pure';
|
||||
|
||||
export const RESULT_INDEX_ARTIFACT_NAME = 'result-index';
|
||||
|
||||
interface ApiSuccessIndexItem {
|
||||
nwo: string;
|
||||
id: string;
|
||||
@@ -44,7 +46,7 @@ export async function getRemoteQueryIndex(
|
||||
const artifactsUrlPath = `/repos/${owner}/${repoName}/actions/artifacts`;
|
||||
|
||||
const artifactList = await listWorkflowRunArtifacts(credentials, owner, repoName, workflowRunId);
|
||||
const resultIndexArtifactId = tryGetArtifactIDfromName('result-index', artifactList);
|
||||
const resultIndexArtifactId = tryGetArtifactIDfromName(RESULT_INDEX_ARTIFACT_NAME, artifactList);
|
||||
if (!resultIndexArtifactId) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -116,6 +118,27 @@ export async function downloadArtifactFromLink(
|
||||
return path.join(extractedPath, downloadLink.innerFilePath || '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a specific artifact is present in the list of artifacts of a workflow run.
|
||||
* @param credentials Credentials for authenticating to the GitHub API.
|
||||
* @param owner
|
||||
* @param repo
|
||||
* @param workflowRunId The ID of the workflow run to get the artifact for.
|
||||
* @param artifactName The artifact name, as a string.
|
||||
* @returns A boolean indicating if the artifact is available.
|
||||
*/
|
||||
export async function isArtifactAvailable(
|
||||
credentials: Credentials,
|
||||
owner: string,
|
||||
repo: string,
|
||||
workflowRunId: number,
|
||||
artifactName: string,
|
||||
): Promise<boolean> {
|
||||
const artifactList = await listWorkflowRunArtifacts(credentials, owner, repo, workflowRunId);
|
||||
|
||||
return tryGetArtifactIDfromName(artifactName, artifactList) !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the result index artifact and extracts the result index items.
|
||||
* @param credentials Credentials for authenticating to the GitHub API.
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {
|
||||
WebviewPanel,
|
||||
ExtensionContext,
|
||||
window as Window,
|
||||
ViewColumn,
|
||||
Uri,
|
||||
workspace,
|
||||
commands
|
||||
commands,
|
||||
} from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
@@ -16,7 +15,6 @@ import {
|
||||
RemoteQueryDownloadAllAnalysesResultsMessage
|
||||
} from '../pure/interface-types';
|
||||
import { Logger } from '../logging';
|
||||
import { getHtmlForWebview } from '../interface-utils';
|
||||
import { assertNever } from '../pure/helpers-pure';
|
||||
import {
|
||||
AnalysisSummary,
|
||||
@@ -34,18 +32,17 @@ import { SHOW_QUERY_TEXT_MSG } from '../query-history';
|
||||
import { AnalysesResultsManager } from './analyses-results-manager';
|
||||
import { AnalysisResults } from './shared/analysis-result';
|
||||
import { humanizeUnit } from '../pure/time';
|
||||
import { AbstractInterfaceManager, InterfacePanelConfig } from '../abstract-interface-manager';
|
||||
|
||||
export class RemoteQueriesInterfaceManager {
|
||||
private panel: WebviewPanel | undefined;
|
||||
private panelLoaded = false;
|
||||
export class RemoteQueriesInterfaceManager extends AbstractInterfaceManager<ToRemoteQueriesMessage, FromRemoteQueriesMessage> {
|
||||
private currentQueryId: string | undefined;
|
||||
private panelLoadedCallBacks: (() => void)[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly ctx: ExtensionContext,
|
||||
ctx: ExtensionContext,
|
||||
private readonly logger: Logger,
|
||||
private readonly analysesResultsManager: AnalysesResultsManager
|
||||
) {
|
||||
super(ctx);
|
||||
this.panelLoadedCallBacks.push(() => {
|
||||
void logger.log('Variant analysis results view loaded');
|
||||
});
|
||||
@@ -103,111 +100,29 @@ export class RemoteQueriesInterfaceManager {
|
||||
};
|
||||
}
|
||||
|
||||
getPanel(): WebviewPanel {
|
||||
if (this.panel == undefined) {
|
||||
const { ctx } = this;
|
||||
const panel = (this.panel = Window.createWebviewPanel(
|
||||
'remoteQueriesView',
|
||||
'CodeQL Query Results',
|
||||
{ viewColumn: ViewColumn.Active, preserveFocus: true },
|
||||
{
|
||||
enableScripts: true,
|
||||
enableFindWidget: true,
|
||||
retainContextWhenHidden: true,
|
||||
localResourceRoots: [
|
||||
Uri.file(this.analysesResultsManager.storagePath),
|
||||
Uri.file(path.join(this.ctx.extensionPath, 'out')),
|
||||
Uri.file(path.join(this.ctx.extensionPath, 'node_modules/@vscode/codicons/dist')),
|
||||
],
|
||||
}
|
||||
));
|
||||
this.panel.onDidDispose(
|
||||
() => {
|
||||
this.panel = undefined;
|
||||
this.currentQueryId = undefined;
|
||||
},
|
||||
null,
|
||||
ctx.subscriptions
|
||||
);
|
||||
|
||||
const scriptPathOnDisk = Uri.file(
|
||||
ctx.asAbsolutePath('out/remoteQueriesView.js')
|
||||
);
|
||||
|
||||
const baseStylesheetUriOnDisk = Uri.file(
|
||||
ctx.asAbsolutePath('out/remote-queries/view/baseStyles.css')
|
||||
);
|
||||
|
||||
const stylesheetPathOnDisk = Uri.file(
|
||||
ctx.asAbsolutePath('out/remote-queries/view/remoteQueries.css')
|
||||
);
|
||||
|
||||
// Allows use of the VS Code "codicons" icon set.
|
||||
// See https://github.com/microsoft/vscode-codicons
|
||||
const codiconsPathOnDisk = Uri.file(
|
||||
ctx.asAbsolutePath('node_modules/@vscode/codicons/dist/codicon.css')
|
||||
);
|
||||
|
||||
panel.webview.html = getHtmlForWebview(
|
||||
panel.webview,
|
||||
scriptPathOnDisk,
|
||||
[baseStylesheetUriOnDisk, stylesheetPathOnDisk, codiconsPathOnDisk],
|
||||
true
|
||||
);
|
||||
ctx.subscriptions.push(
|
||||
panel.webview.onDidReceiveMessage(
|
||||
async (e) => this.handleMsgFromView(e),
|
||||
undefined,
|
||||
ctx.subscriptions
|
||||
)
|
||||
);
|
||||
}
|
||||
return this.panel;
|
||||
}
|
||||
|
||||
private waitForPanelLoaded(): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
if (this.panelLoaded) {
|
||||
resolve();
|
||||
} else {
|
||||
this.panelLoadedCallBacks.push(resolve);
|
||||
protected getPanelConfig(): InterfacePanelConfig {
|
||||
return {
|
||||
viewId: 'remoteQueriesView',
|
||||
title: 'CodeQL Query Results',
|
||||
viewColumn: ViewColumn.Active,
|
||||
preserveFocus: true,
|
||||
view: 'remote-queries',
|
||||
additionalOptions: {
|
||||
localResourceRoots: [
|
||||
Uri.file(this.analysesResultsManager.storagePath)
|
||||
]
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private async openFile(filePath: string) {
|
||||
try {
|
||||
const textDocument = await workspace.openTextDocument(filePath);
|
||||
await Window.showTextDocument(textDocument, ViewColumn.One);
|
||||
} catch (error) {
|
||||
void showAndLogWarningMessage(`Could not open file: ${filePath}`);
|
||||
}
|
||||
protected onPanelDispose(): void {
|
||||
this.currentQueryId = undefined;
|
||||
}
|
||||
|
||||
private async openVirtualFile(text: string) {
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
queryText: encodeURIComponent(SHOW_QUERY_TEXT_MSG + text)
|
||||
});
|
||||
const uri = Uri.parse(
|
||||
`remote-query:query-text.ql?${params.toString()}`,
|
||||
true
|
||||
);
|
||||
const doc = await workspace.openTextDocument(uri);
|
||||
await Window.showTextDocument(doc, { preview: false });
|
||||
} catch (error) {
|
||||
void showAndLogWarningMessage('Could not open query text');
|
||||
}
|
||||
}
|
||||
|
||||
private async handleMsgFromView(
|
||||
msg: FromRemoteQueriesMessage
|
||||
): Promise<void> {
|
||||
protected async onMessage(msg: FromRemoteQueriesMessage): Promise<void> {
|
||||
switch (msg.t) {
|
||||
case 'remoteQueryLoaded':
|
||||
this.panelLoaded = true;
|
||||
this.panelLoadedCallBacks.forEach((cb) => cb());
|
||||
this.panelLoadedCallBacks = [];
|
||||
this.onWebViewLoaded();
|
||||
break;
|
||||
case 'remoteQueryError':
|
||||
void this.logger.log(
|
||||
@@ -237,6 +152,31 @@ export class RemoteQueriesInterfaceManager {
|
||||
}
|
||||
}
|
||||
|
||||
private async openFile(filePath: string) {
|
||||
try {
|
||||
const textDocument = await workspace.openTextDocument(filePath);
|
||||
await Window.showTextDocument(textDocument, ViewColumn.One);
|
||||
} catch (error) {
|
||||
void showAndLogWarningMessage(`Could not open file: ${filePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async openVirtualFile(text: string) {
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
queryText: encodeURIComponent(SHOW_QUERY_TEXT_MSG + text)
|
||||
});
|
||||
const uri = Uri.parse(
|
||||
`remote-query:query-text.ql?${params.toString()}`,
|
||||
true
|
||||
);
|
||||
const doc = await workspace.openTextDocument(uri);
|
||||
await Window.showTextDocument(doc, { preview: false });
|
||||
} catch (error) {
|
||||
void showAndLogWarningMessage('Could not open query text');
|
||||
}
|
||||
}
|
||||
|
||||
private async downloadAnalysisResults(msg: RemoteQueryDownloadAnalysisResultsMessage): Promise<void> {
|
||||
const queryId = this.currentQueryId;
|
||||
await this.analysesResultsManager.downloadAnalysisResults(
|
||||
@@ -261,10 +201,6 @@ export class RemoteQueriesInterfaceManager {
|
||||
}
|
||||
}
|
||||
|
||||
private postMessage(msg: ToRemoteQueriesMessage): Thenable<boolean> {
|
||||
return this.getPanel().webview.postMessage(msg);
|
||||
}
|
||||
|
||||
private getDuration(startTime: number, endTime: number): string {
|
||||
const diffInMs = startTime - endTime;
|
||||
return humanizeUnit(diffInMs);
|
||||
|
||||
@@ -75,6 +75,8 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
this.onRemoteQueryAdded = this.remoteQueryAddedEventEmitter.event;
|
||||
this.onRemoteQueryRemoved = this.remoteQueryRemovedEventEmitter.event;
|
||||
this.onRemoteQueryStatusUpdate = this.remoteQueryStatusUpdateEventEmitter.event;
|
||||
|
||||
this.push(this.interfaceManager);
|
||||
}
|
||||
|
||||
public async rehydrateRemoteQuery(queryId: string, query: RemoteQuery, status: QueryStatus) {
|
||||
@@ -125,7 +127,7 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
|
||||
if (querySubmission?.query) {
|
||||
const query = querySubmission.query;
|
||||
const queryId = this.createQueryId(query.queryName);
|
||||
const queryId = this.createQueryId();
|
||||
|
||||
await this.prepareStorageDirectory(queryId);
|
||||
await this.storeJsonFile(queryId, 'query.json', query);
|
||||
@@ -262,11 +264,10 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
|
||||
/**
|
||||
* Generates a unique id for this query, suitable for determining the storage location for the downloaded query artifacts.
|
||||
* @param queryName
|
||||
* @returns
|
||||
* @returns A unique id for this query.
|
||||
*/
|
||||
private createQueryId(queryName: string): string {
|
||||
return `${queryName}-${nanoid()}`;
|
||||
private createQueryId(): string {
|
||||
return nanoid();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { Credentials } from '../authentication';
|
||||
import { Logger } from '../logging';
|
||||
import { getWorkflowStatus } from './gh-actions-api-client';
|
||||
import { getWorkflowStatus, isArtifactAvailable, RESULT_INDEX_ARTIFACT_NAME } from './gh-actions-api-client';
|
||||
import { RemoteQuery } from './remote-query';
|
||||
import { RemoteQueryWorkflowResult } from './remote-query-workflow-result';
|
||||
|
||||
@@ -42,7 +42,25 @@ export class RemoteQueriesMonitor {
|
||||
remoteQuery.controllerRepository.name,
|
||||
remoteQuery.actionsWorkflowRunId);
|
||||
|
||||
if (workflowStatus.status !== 'InProgress') {
|
||||
// Even if the workflow indicates it has completed, artifacts
|
||||
// might still take a while to become available. So we need to
|
||||
// check for the artifact before we can declare the workflow
|
||||
// as having completed.
|
||||
if (workflowStatus.status === 'CompletedSuccessfully') {
|
||||
const resultIndexAvailable = await isArtifactAvailable(
|
||||
credentials,
|
||||
remoteQuery.controllerRepository.owner,
|
||||
remoteQuery.controllerRepository.name,
|
||||
remoteQuery.actionsWorkflowRunId,
|
||||
RESULT_INDEX_ARTIFACT_NAME
|
||||
);
|
||||
|
||||
if (resultIndexAvailable) {
|
||||
return workflowStatus;
|
||||
}
|
||||
|
||||
// We don't have a result-index yet, so we'll keep monitoring.
|
||||
} else if (workflowStatus.status !== 'InProgress') {
|
||||
return workflowStatus;
|
||||
}
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ export async function runRemoteQuery(
|
||||
if (!controllerRepo || !REPO_REGEX.test(controllerRepo)) {
|
||||
void logger.log(controllerRepo ? 'Invalid controller repository name.' : 'No controller repository defined.');
|
||||
controllerRepo = await window.showInputBox({
|
||||
title: 'Controller repository in which to display progress and results of variant analysis',
|
||||
title: 'Controller repository in which to run the GitHub Actions workflow for this variant analysis',
|
||||
placeHolder: '<owner>/<repo>',
|
||||
prompt: 'Enter the name of a GitHub repository in the format <owner>/<repo>',
|
||||
ignoreFocusOut: true,
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true
|
||||
},
|
||||
extends: [
|
||||
"plugin:react/recommended"
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"lib": ["ES2021", "dom"],
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"rootDir": "..",
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -32,11 +32,11 @@ import * as messages from './pure/messages';
|
||||
import { InitialQueryInfo, LocalQueryInfo } from './query-results';
|
||||
import * as qsClient from './queryserver-client';
|
||||
import { isQuickQueryPath } from './quick-query';
|
||||
import { compileDatabaseUpgradeSequence, hasNondestructiveUpgradeCapabilities, upgradeDatabaseExplicit } from './upgrades';
|
||||
import { compileDatabaseUpgradeSequence, upgradeDatabaseExplicit } from './upgrades';
|
||||
import { ensureMetadataIsComplete } from './query-results';
|
||||
import { SELECT_QUERY_NAME } from './contextual/locationFinder';
|
||||
import { DecodedBqrsChunk } from './pure/bqrs-cli-types';
|
||||
import { getErrorMessage } from './pure/helpers-pure';
|
||||
import { asError, getErrorMessage } from './pure/helpers-pure';
|
||||
import { generateSummarySymbolsFile } from './log-insights/summary-parser';
|
||||
|
||||
/**
|
||||
@@ -207,7 +207,10 @@ export class QueryEvaluationInfo {
|
||||
logPath: this.evalLogPath,
|
||||
});
|
||||
if (await this.hasEvalLog()) {
|
||||
this.displayHumanReadableLogSummary(queryInfo, qs);
|
||||
queryInfo.evalLogLocation = this.evalLogPath;
|
||||
queryInfo.evalLogSummaryLocation = await this.generateHumanReadableLogSummary(qs);
|
||||
void this.logEndSummary(queryInfo.evalLogSummaryLocation, qs); // Logged asynchrnously
|
||||
|
||||
if (config.isCanary()) { // Generate JSON summary for viewer.
|
||||
await qs.cliServer.generateJsonLogSummary(this.evalLogPath, this.jsonEvalLogSummaryPath);
|
||||
queryInfo.jsonEvalLogSummaryLocation = this.jsonEvalLogSummaryPath;
|
||||
@@ -340,25 +343,40 @@ export class QueryEvaluationInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the appropriate CLI command to generate a human-readable log summary
|
||||
* and logs to the Query Server console and query log file.
|
||||
* Calls the appropriate CLI command to generate a human-readable log summary.
|
||||
* @param qs The query server client.
|
||||
* @returns The path to the log summary, or `undefined` if the summary could not be generated.
|
||||
*/
|
||||
displayHumanReadableLogSummary(queryInfo: LocalQueryInfo, qs: qsClient.QueryServerClient): void {
|
||||
queryInfo.evalLogLocation = this.evalLogPath;
|
||||
void qs.cliServer.generateLogSummary(this.evalLogPath, this.evalLogSummaryPath, this.evalLogEndSummaryPath)
|
||||
.then(() => {
|
||||
queryInfo.evalLogSummaryLocation = this.evalLogSummaryPath;
|
||||
fs.readFile(this.evalLogEndSummaryPath, (err, buffer) => {
|
||||
if (err) {
|
||||
throw new Error(`Could not read structured evaluator log end of summary file at ${this.evalLogEndSummaryPath}.`);
|
||||
}
|
||||
void qs.logger.log(' --- Evaluator Log Summary --- ', { additionalLogLocation: this.logPath });
|
||||
void qs.logger.log(buffer.toString(), { additionalLogLocation: this.logPath });
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
void showAndLogWarningMessage(`Failed to generate human-readable structured evaluator log summary. Reason: ${err.message}`);
|
||||
});
|
||||
private async generateHumanReadableLogSummary(qs: qsClient.QueryServerClient): Promise<string | undefined> {
|
||||
try {
|
||||
await qs.cliServer.generateLogSummary(this.evalLogPath, this.evalLogSummaryPath, this.evalLogEndSummaryPath);
|
||||
return this.evalLogSummaryPath;
|
||||
|
||||
} catch (e) {
|
||||
const err = asError(e);
|
||||
void showAndLogWarningMessage(`Failed to generate human-readable structured evaluator log summary. Reason: ${err.message}`);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the end summary to the Output window and log file.
|
||||
* @param logSummaryPath Path to the human-readable log summary
|
||||
* @param qs The query server client.
|
||||
*/
|
||||
private async logEndSummary(logSummaryPath: string | undefined, qs: qsClient.QueryServerClient): Promise<void> {
|
||||
if (logSummaryPath === undefined) {
|
||||
// Failed to generate the log, so we don't expect an end summary either.
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const endSummaryContent = await fs.readFile(this.evalLogEndSummaryPath, 'utf-8');
|
||||
void qs.logger.log(' --- Evaluator Log Summary --- ', { additionalLogLocation: this.logPath });
|
||||
void qs.logger.log(endSummaryContent, { additionalLogLocation: this.logPath });
|
||||
} catch (e) {
|
||||
void showAndLogWarningMessage(`Could not read structured evaluator log end of summary file at ${this.evalLogEndSummaryPath}.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -844,7 +862,7 @@ export async function compileAndRunQueryAgainstDatabase(
|
||||
let upgradeDir: tmp.DirectoryResult | undefined;
|
||||
try {
|
||||
let upgradeQlo;
|
||||
if (await hasNondestructiveUpgradeCapabilities(qs)) {
|
||||
if (await qs.cliServer.cliConstraints.supportsNonDestructiveUpgrades()) {
|
||||
upgradeDir = await tmp.dir({ dir: upgradesTmpDir, unsafeCleanup: true });
|
||||
upgradeQlo = await compileNonDestructiveUpgrade(qs, upgradeDir, query, qlProgram, dbItem, progress, token);
|
||||
} else {
|
||||
|
||||
@@ -3,7 +3,8 @@ module.exports = {
|
||||
browser: true
|
||||
},
|
||||
extends: [
|
||||
"plugin:react/recommended"
|
||||
"plugin:react/recommended",
|
||||
"plugin:storybook/recommended",
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
55
extensions/ql-vscode/src/stories/Overview.stories.mdx
Normal file
55
extensions/ql-vscode/src/stories/Overview.stories.mdx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Canvas, Meta, Story } from '@storybook/addon-docs';
|
||||
|
||||
import { VSCodeButton } from '@vscode/webview-ui-toolkit/react';
|
||||
|
||||
import iframeImage from './images/update-css-variables-iframe.png';
|
||||
import stylesImage from './images/update-css-variables-styles.png';
|
||||
import bodyImage from './images/update-css-variables-body.png';
|
||||
|
||||
<Meta title="Overview" />
|
||||
|
||||
Welcome to the Storybook for **CodeQL for Visual Studio Code**! This Storybook contains stories for components and pages in the extension.
|
||||
|
||||
### Writing stories
|
||||
|
||||
To create new stories, copy an existing story in the `src/stories` directory and modify it to use your component or page. Please note that
|
||||
you are not able to access any VSCode specific APIs or receive messages from VSCode so an ideal component would use generic props. The
|
||||
`vscode.postMessage` API is mocked but no message will be sent.
|
||||
|
||||
You are able to use all VSCode CSS variables; these are injected into the Storybook preview. However, only the Dark+ theme is supported. It
|
||||
is currently not possible to preview your component in another theme.
|
||||
|
||||
For more information about how to write stories and how to add controls, please see the
|
||||
[Storybook documentation](https://storybook.js.org/docs/react/writing-stories/introduction).
|
||||
|
||||
### WebView UI Toolkit
|
||||
|
||||
As much as possible, we try to make use of the [WebView UI Toolkit](https://github.com/microsoft/vscode-webview-ui-toolkit). The Storybook
|
||||
for the WebView UI Toolkit can be found [here](https://microsoft.github.io/vscode-webview-ui-toolkit/).
|
||||
|
||||
### Updating VSCode CSS variables
|
||||
|
||||
The VSCode CSS variables that are injected into the Storybook preview are defined in the `src/stories/vscode-theme.css` file. They need to be
|
||||
updated manually if new variables are added to VSCode. It can also be updated if you would like to manually preview a different theme. To update
|
||||
these variables, follow these steps:
|
||||
|
||||
1. Make sure you have selected the correct theme. If you want to use a variable which is currently not available and will be committed, please
|
||||
select the **Dark+** theme. You can use **Preferences: Color Theme** in the *Command Palette* to select the theme.
|
||||
2. Open a WebView in VSCode (for example the results of a query)
|
||||
3. Open the *Command Palette* (Ctrl/Cmd+Shift+P)
|
||||
4. Select **Developer: Open WebView Developer Tools**
|
||||
5. Now, you will need to find the `<html>` element in the lowest-level `<iframe>`. See the image below:
|
||||
|
||||
<img src={iframeImage} />
|
||||
|
||||
6. Once you have selected the `<html>` element as in the image above, click on **Show All Properties (... more)** (see image below). This will
|
||||
expand all CSS variables.
|
||||
|
||||
<img src={stylesImage} />
|
||||
|
||||
7. Copy all variables to the `src/stories/vscode-theme.css` file.
|
||||
8. Now, select the `<body>` element which is a direct child of the `<html>` element.
|
||||
9. This time, you do not need to copy the variables. Instead, copy the styles on the `<body>` element to the `src/stories/vscode-theme.css` file.
|
||||
See the image below for which styles need to be copied.
|
||||
|
||||
<img src={bodyImage} />
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 625 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 425 KiB |
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import AnalysisAlertResult from '../../view/remote-queries/AnalysisAlertResult';
|
||||
import type { AnalysisAlert } from '../../remote-queries/shared/analysis-result';
|
||||
|
||||
export default {
|
||||
title: 'Analysis Alert Result',
|
||||
component: AnalysisAlertResult,
|
||||
} as ComponentMeta<typeof AnalysisAlertResult>;
|
||||
|
||||
const Template: ComponentStory<typeof AnalysisAlertResult> = (args) => (
|
||||
<AnalysisAlertResult {...args} />
|
||||
);
|
||||
|
||||
export const Warning = Template.bind({});
|
||||
|
||||
const warningAlert: AnalysisAlert = {
|
||||
message: {
|
||||
tokens: [
|
||||
{
|
||||
t: 'text',
|
||||
text: 'This is an empty block.'
|
||||
}
|
||||
]
|
||||
},
|
||||
shortDescription: 'This is an empty block.',
|
||||
fileLink: {
|
||||
fileLinkPrefix: 'https://github.com/expressjs/express/blob/33e8dc303af9277f8a7e4f46abfdcb5e72f6797b',
|
||||
filePath: 'test/app.options.js'
|
||||
},
|
||||
severity: 'Warning',
|
||||
codeSnippet: {
|
||||
startLine: 10,
|
||||
endLine: 14,
|
||||
text: ' app.del(\'/\', function(){});\n app.get(\'/users\', function(req, res){});\n app.put(\'/users\', function(req, res){});\n\n request(app)\n'
|
||||
},
|
||||
highlightedRegion: {
|
||||
startLine: 12,
|
||||
startColumn: 41,
|
||||
endLine: 12,
|
||||
endColumn: 43
|
||||
},
|
||||
codeFlows: []
|
||||
};
|
||||
|
||||
Warning.args = {
|
||||
alert: warningAlert,
|
||||
};
|
||||
@@ -0,0 +1,121 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
import { ThemeProvider } from '@primer/react';
|
||||
|
||||
import CodePaths from '../../view/remote-queries/CodePaths';
|
||||
import type { CodeFlow } from '../../remote-queries/shared/analysis-result';
|
||||
|
||||
export default {
|
||||
title: 'Code Paths',
|
||||
component: CodePaths,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<ThemeProvider colorMode="auto">
|
||||
<Story />
|
||||
</ThemeProvider>
|
||||
)
|
||||
]
|
||||
} as ComponentMeta<typeof CodePaths>;
|
||||
|
||||
const Template: ComponentStory<typeof CodePaths> = (args) => (
|
||||
<CodePaths {...args} />
|
||||
);
|
||||
|
||||
export const PowerShell = Template.bind({});
|
||||
|
||||
const codeFlows: CodeFlow[] = [
|
||||
{
|
||||
'threadFlows': [
|
||||
{
|
||||
fileLink: {
|
||||
fileLinkPrefix: 'https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff',
|
||||
filePath: 'src/System.Management.Automation/help/UpdatableHelpSystem.cs'
|
||||
},
|
||||
codeSnippet: {
|
||||
startLine: 1260,
|
||||
endLine: 1260,
|
||||
text: ' string extractPath = Path.Combine(destination, entry.FullName);'
|
||||
},
|
||||
highlightedRegion: {
|
||||
startLine: 1260,
|
||||
startColumn: 72,
|
||||
endLine: 1260,
|
||||
endColumn: 86,
|
||||
},
|
||||
message: {
|
||||
tokens: [
|
||||
{
|
||||
t: 'text',
|
||||
text: 'access to property FullName : String'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
fileLink: {
|
||||
fileLinkPrefix: 'https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff',
|
||||
filePath: 'src/System.Management.Automation/help/UpdatableHelpSystem.cs'
|
||||
},
|
||||
codeSnippet: {
|
||||
startLine: 1260,
|
||||
endLine: 1260,
|
||||
text: ' string extractPath = Path.Combine(destination, entry.FullName);'
|
||||
},
|
||||
highlightedRegion: {
|
||||
startLine: 1260,
|
||||
startColumn: 46,
|
||||
endLine: 1260,
|
||||
endColumn: 87,
|
||||
},
|
||||
message: {
|
||||
tokens: [
|
||||
{
|
||||
t: 'text',
|
||||
text: 'call to method Combine : String'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
fileLink: {
|
||||
fileLinkPrefix: 'https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff',
|
||||
filePath: 'src/System.Management.Automation/help/UpdatableHelpSystem.cs'
|
||||
},
|
||||
codeSnippet: {
|
||||
startLine: 1261,
|
||||
endLine: 1261,
|
||||
text: ' entry.ExtractToFile(extractPath);'
|
||||
},
|
||||
highlightedRegion: {
|
||||
startLine: 1261,
|
||||
startColumn: 45,
|
||||
endLine: 1261,
|
||||
endColumn: 56,
|
||||
},
|
||||
message: {
|
||||
tokens: [
|
||||
{
|
||||
t: 'text',
|
||||
text: 'access to local variable extractPath'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
PowerShell.args = {
|
||||
codeFlows: codeFlows,
|
||||
ruleDescription: 'ZipSlip vulnerability',
|
||||
message: {
|
||||
tokens: [
|
||||
{
|
||||
type: 'text',
|
||||
t: 'This zip file may have a dangerous path'
|
||||
}
|
||||
]
|
||||
},
|
||||
severity: 'Warning',
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import DownloadButtonComponent from '../../view/remote-queries/DownloadButton';
|
||||
|
||||
export default {
|
||||
title: 'Download Button',
|
||||
component: DownloadButtonComponent,
|
||||
argTypes: {
|
||||
onClick: {
|
||||
action: 'clicked',
|
||||
table: {
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
} as ComponentMeta<typeof DownloadButtonComponent>;
|
||||
|
||||
const Template: ComponentStory<typeof DownloadButtonComponent> = (args) => (
|
||||
<DownloadButtonComponent {...args} />
|
||||
);
|
||||
|
||||
export const DownloadButton = Template.bind({});
|
||||
DownloadButton.args = {
|
||||
text: 'Download',
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
|
||||
import DownloadSpinnerComponent from '../../view/remote-queries/DownloadSpinner';
|
||||
|
||||
export default {
|
||||
title: 'Download Spinner',
|
||||
component: DownloadSpinnerComponent,
|
||||
} as ComponentMeta<typeof DownloadSpinnerComponent>;
|
||||
|
||||
export const DownloadSpinner = <DownloadSpinnerComponent />;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import FileCodeSnippet from '../../view/remote-queries/FileCodeSnippet';
|
||||
|
||||
export default {
|
||||
title: 'File Code Snippet',
|
||||
component: FileCodeSnippet
|
||||
} as ComponentMeta<typeof FileCodeSnippet>;
|
||||
|
||||
const Template: ComponentStory<typeof FileCodeSnippet> = (args) => (
|
||||
<FileCodeSnippet {...args} />
|
||||
);
|
||||
|
||||
export const WithCodeSnippet = Template.bind({});
|
||||
WithCodeSnippet.args = {
|
||||
fileLink: {
|
||||
fileLinkPrefix: 'https://github.com/PowerShell/PowerShell/blob/450d884668ca477c6581ce597958f021fac30bff',
|
||||
filePath: 'src/System.Management.Automation/help/UpdatableHelpSystem.cs'
|
||||
},
|
||||
codeSnippet: {
|
||||
startLine: 1261,
|
||||
endLine: 1261,
|
||||
text: ' entry.ExtractToFile(extractPath);'
|
||||
},
|
||||
highlightedRegion: {
|
||||
startLine: 1261,
|
||||
startColumn: 45,
|
||||
endLine: 1261,
|
||||
endColumn: 56,
|
||||
},
|
||||
message: {
|
||||
tokens: [
|
||||
{
|
||||
t: 'text',
|
||||
text: 'access to local variable extractPath'
|
||||
}
|
||||
]
|
||||
},
|
||||
severity: 'Warning',
|
||||
};
|
||||
|
||||
export const WithoutCodeSnippet = Template.bind({});
|
||||
WithoutCodeSnippet.args = {
|
||||
...WithCodeSnippet.args,
|
||||
codeSnippet: undefined,
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import LastUpdatedComponent from '../../view/remote-queries/LastUpdated';
|
||||
|
||||
export default {
|
||||
title: 'Last Updated',
|
||||
component: LastUpdatedComponent,
|
||||
} as ComponentMeta<typeof LastUpdatedComponent>;
|
||||
|
||||
const Template: ComponentStory<typeof LastUpdatedComponent> = (args) => (
|
||||
<LastUpdatedComponent {...args} />
|
||||
);
|
||||
|
||||
export const LastUpdated = Template.bind({});
|
||||
|
||||
LastUpdated.args = {
|
||||
lastUpdated: -3_600_000, // 1 hour ago
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import { RemoteQueries } from '../../view/remote-queries/RemoteQueries';
|
||||
|
||||
import remoteQueryResult from './data/remoteQueryResultMessage.json';
|
||||
import analysesResults from './data/analysesResultsMessage.json';
|
||||
|
||||
export default {
|
||||
title: 'MRVA/Remote Queries',
|
||||
component: RemoteQueries
|
||||
} as ComponentMeta<typeof RemoteQueries>;
|
||||
|
||||
const Template: ComponentStory<typeof RemoteQueries> = () => {
|
||||
useEffect(() => {
|
||||
window.postMessage(remoteQueryResult);
|
||||
window.postMessage(analysesResults);
|
||||
});
|
||||
|
||||
return <RemoteQueries />;
|
||||
};
|
||||
|
||||
export const Top10JavaScript = Template.bind({});
|
||||
@@ -0,0 +1,25 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
|
||||
import RepositoriesSearchComponent from '../../view/remote-queries/RepositoriesSearch';
|
||||
|
||||
export default {
|
||||
title: 'Repositories Search',
|
||||
component: RepositoriesSearchComponent,
|
||||
argTypes: {
|
||||
filterValue: {
|
||||
control: {
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
} as ComponentMeta<typeof RepositoriesSearchComponent>;
|
||||
|
||||
export const RepositoriesSearch = () => {
|
||||
const [filterValue, setFilterValue] = useState('');
|
||||
|
||||
return (
|
||||
<RepositoriesSearchComponent filterValue={filterValue} setFilterValue={setFilterValue} />
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import StarCountComponent from '../../view/remote-queries/StarCount';
|
||||
|
||||
export default {
|
||||
title: 'Star Count',
|
||||
component: StarCountComponent,
|
||||
} as ComponentMeta<typeof StarCountComponent>;
|
||||
|
||||
const Template: ComponentStory<typeof StarCountComponent> = (args) => (
|
||||
<StarCountComponent {...args} />
|
||||
);
|
||||
|
||||
export const LessThan1000 = Template.bind({});
|
||||
LessThan1000.args = {
|
||||
starCount: 100,
|
||||
};
|
||||
|
||||
export const MoreThan1000 = Template.bind({});
|
||||
MoreThan1000.args = {
|
||||
starCount: 7532,
|
||||
};
|
||||
|
||||
export const MoreThan10000 = Template.bind({});
|
||||
MoreThan10000.args = {
|
||||
starCount: 65287,
|
||||
};
|
||||
|
||||
export const MoreThan100000 = Template.bind({});
|
||||
MoreThan100000.args = {
|
||||
starCount: 1234234,
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import TextButtonComponent from '../../view/remote-queries/TextButton';
|
||||
|
||||
export default {
|
||||
title: 'Text Button',
|
||||
component: TextButtonComponent,
|
||||
argTypes: {
|
||||
onClick: {
|
||||
action: 'clicked',
|
||||
table: {
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
} as ComponentMeta<typeof TextButtonComponent>;
|
||||
|
||||
const Template: ComponentStory<typeof TextButtonComponent> = (args) => (
|
||||
<TextButtonComponent {...args} />
|
||||
);
|
||||
|
||||
export const TextButton = Template.bind({});
|
||||
|
||||
TextButton.args = {
|
||||
children: 'Show more',
|
||||
size: 'x-small',
|
||||
};
|
||||
15515
extensions/ql-vscode/src/stories/remote-queries/data/analysesResultsMessage.json
generated
Normal file
15515
extensions/ql-vscode/src/stories/remote-queries/data/analysesResultsMessage.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
170
extensions/ql-vscode/src/stories/remote-queries/data/remoteQueryResultMessage.json
generated
Normal file
170
extensions/ql-vscode/src/stories/remote-queries/data/remoteQueryResultMessage.json
generated
Normal file
@@ -0,0 +1,170 @@
|
||||
{
|
||||
"t": "setRemoteQueryResult",
|
||||
"queryResult": {
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j",
|
||||
"queryTitle": "Empty block",
|
||||
"queryFileName": "example.ql",
|
||||
"queryFilePath": "/home/octocat/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
"queryText": "/**\n * @name Empty block\n * @kind problem\n * @problem.severity warning\n * @id javascript/example/empty-block\n */\n\nimport javascript\n\nfrom BlockStmt b\nwhere b.getNumStmt() = 0\nselect b, \"This is an empty block.\"\n",
|
||||
"language": "javascript",
|
||||
"workflowRunUrl": "https://github.com/octocat/octo-repo/actions/runs/2955404400",
|
||||
"totalRepositoryCount": 10,
|
||||
"affectedRepositoryCount": 10,
|
||||
"totalResultCount": 16338,
|
||||
"executionTimestamp": "30 Aug at 0:14 pm",
|
||||
"executionDuration": "1 minute",
|
||||
"analysisSummaries": [
|
||||
{
|
||||
"nwo": "angular/angular",
|
||||
"databaseSha": "a360309f31afa97c4268a94fbd6a5108362a7182",
|
||||
"resultCount": 8436,
|
||||
"downloadLink": {
|
||||
"id": "346232925",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232925",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "5.67 MB",
|
||||
"starCount": 83537,
|
||||
"lastUpdated": -1066284
|
||||
},
|
||||
{
|
||||
"nwo": "babel/babel",
|
||||
"databaseSha": "0f62c58c79830cfe0afb26161e96e0e1b0482c01",
|
||||
"resultCount": 5502,
|
||||
"downloadLink": {
|
||||
"id": "346232926",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232926",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "3.80 MB",
|
||||
"starCount": 41292,
|
||||
"lastUpdated": -1600284
|
||||
},
|
||||
{
|
||||
"nwo": "facebook/react",
|
||||
"databaseSha": "e25648b0a89eab6f82bea2c2a1ef90866ac82b33",
|
||||
"resultCount": 1205,
|
||||
"downloadLink": {
|
||||
"id": "346232919",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232919",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "905.24 KB",
|
||||
"starCount": 194007,
|
||||
"lastUpdated": -379284
|
||||
},
|
||||
{
|
||||
"nwo": "facebook/jest",
|
||||
"databaseSha": "187566a70aa4b6aa5f74952b504bbeddb5854aef",
|
||||
"resultCount": 643,
|
||||
"downloadLink": {
|
||||
"id": "346232921",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232921",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "441.60 KB",
|
||||
"starCount": 39987,
|
||||
"lastUpdated": -113284
|
||||
},
|
||||
{
|
||||
"nwo": "facebook/create-react-app",
|
||||
"databaseSha": "f34d88e30c7d8be7181f728d1abc4fd8d5cd07d3",
|
||||
"resultCount": 198,
|
||||
"downloadLink": {
|
||||
"id": "346232928",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232928",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "132.28 KB",
|
||||
"starCount": 96698,
|
||||
"lastUpdated": -126284
|
||||
},
|
||||
{
|
||||
"nwo": "vuejs/vue",
|
||||
"databaseSha": "810f6d12edea47cde7f39eaf7ec3ae1b7300d40c",
|
||||
"resultCount": 140,
|
||||
"downloadLink": {
|
||||
"id": "346232920",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232920",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "89.99 KB",
|
||||
"starCount": 198970,
|
||||
"lastUpdated": -167284
|
||||
},
|
||||
{
|
||||
"nwo": "lodash/lodash",
|
||||
"databaseSha": "2da024c3b4f9947a48517639de7560457cd4ec6c",
|
||||
"resultCount": 108,
|
||||
"downloadLink": {
|
||||
"id": "346232927",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232927",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "70.43 KB",
|
||||
"starCount": 54215,
|
||||
"lastUpdated": -9080284
|
||||
},
|
||||
{
|
||||
"nwo": "jquery/jquery",
|
||||
"databaseSha": "d2436df36a4b2ef556907e734a90771f0dbdbcaf",
|
||||
"resultCount": 67,
|
||||
"downloadLink": {
|
||||
"id": "346232922",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232922",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/jquery/jquery",
|
||||
"fileSize": "45.07 KB",
|
||||
"starCount": 56629,
|
||||
"lastUpdated": -23284
|
||||
},
|
||||
{
|
||||
"nwo": "expressjs/express",
|
||||
"databaseSha": "33e8dc303af9277f8a7e4f46abfdcb5e72f6797b",
|
||||
"resultCount": 26,
|
||||
"downloadLink": {
|
||||
"id": "346232924",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232924",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bulk-builder/bulk-builder",
|
||||
"fileSize": "16.96 KB",
|
||||
"starCount": 58125,
|
||||
"lastUpdated": -236284
|
||||
},
|
||||
{
|
||||
"nwo": "twbs/bootstrap",
|
||||
"databaseSha": "af1bd974bba7f6e7f90c5ed3f42738bd101926cb",
|
||||
"resultCount": 13,
|
||||
"downloadLink": {
|
||||
"id": "346232923",
|
||||
"urlPath": "/repos/octocat/octo-repo/actions/artifacts/346232923",
|
||||
"innerFilePath": "results.sarif",
|
||||
"queryId": "Empty block-LUzMYbSaBM4Lv6YP8GQ8j"
|
||||
},
|
||||
"sourceLocationPrefix": "/home/runner/work/bootstrap/bootstrap",
|
||||
"fileSize": "8.50 KB",
|
||||
"starCount": 159230,
|
||||
"lastUpdated": -1754284
|
||||
}
|
||||
],
|
||||
"analysisFailures": []
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,9 @@
|
||||
"noUnusedLocals": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"experimentalDecorators": true
|
||||
"experimentalDecorators": true,
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
630
extensions/ql-vscode/src/stories/vscode-theme.css
Normal file
630
extensions/ql-vscode/src/stories/vscode-theme.css
Normal file
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
* These were copied from VSCode Dark+ theme.
|
||||
*
|
||||
* To update these, open a webview in VSCode, open the webview developer tools and find the
|
||||
* iframe hosting the webview. The <html> element will have a style attribute that contains
|
||||
* the CSS variables. Copy these to this file.
|
||||
*/
|
||||
:root {
|
||||
--vscode-font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--vscode-font-weight: normal;
|
||||
--vscode-font-size: 13px;
|
||||
--vscode-editor-font-family: Menlo, Monaco, "Courier New", monospace;
|
||||
--vscode-editor-font-weight: normal;
|
||||
--vscode-editor-font-size: 12px;
|
||||
--vscode-foreground: #cccccc;
|
||||
--vscode-disabledForeground: rgba(204, 204, 204, 0.5);
|
||||
--vscode-errorForeground: #f48771;
|
||||
--vscode-descriptionForeground: rgba(204, 204, 204, 0.7);
|
||||
--vscode-icon-foreground: #c5c5c5;
|
||||
--vscode-focusBorder: #007fd4;
|
||||
--vscode-textSeparator-foreground: rgba(255, 255, 255, 0.18);
|
||||
--vscode-textLink-foreground: #3794ff;
|
||||
--vscode-textLink-activeForeground: #3794ff;
|
||||
--vscode-textPreformat-foreground: #d7ba7d;
|
||||
--vscode-textBlockQuote-background: rgba(127, 127, 127, 0.1);
|
||||
--vscode-textBlockQuote-border: rgba(0, 122, 204, 0.5);
|
||||
--vscode-textCodeBlock-background: rgba(10, 10, 10, 0.4);
|
||||
--vscode-widget-shadow: rgba(0, 0, 0, 0.36);
|
||||
--vscode-input-background: #3c3c3c;
|
||||
--vscode-input-foreground: #cccccc;
|
||||
--vscode-inputOption-activeBorder: rgba(0, 122, 204, 0);
|
||||
--vscode-inputOption-hoverBackground: rgba(90, 93, 94, 0.5);
|
||||
--vscode-inputOption-activeBackground: rgba(0, 127, 212, 0.4);
|
||||
--vscode-inputOption-activeForeground: #ffffff;
|
||||
--vscode-input-placeholderForeground: #a6a6a6;
|
||||
--vscode-inputValidation-infoBackground: #063b49;
|
||||
--vscode-inputValidation-infoBorder: #007acc;
|
||||
--vscode-inputValidation-warningBackground: #352a05;
|
||||
--vscode-inputValidation-warningBorder: #b89500;
|
||||
--vscode-inputValidation-errorBackground: #5a1d1d;
|
||||
--vscode-inputValidation-errorBorder: #be1100;
|
||||
--vscode-dropdown-background: #3c3c3c;
|
||||
--vscode-dropdown-foreground: #f0f0f0;
|
||||
--vscode-dropdown-border: #3c3c3c;
|
||||
--vscode-checkbox-background: #3c3c3c;
|
||||
--vscode-checkbox-foreground: #f0f0f0;
|
||||
--vscode-checkbox-border: #3c3c3c;
|
||||
--vscode-button-foreground: #ffffff;
|
||||
--vscode-button-separator: rgba(255, 255, 255, 0.4);
|
||||
--vscode-button-background: #0e639c;
|
||||
--vscode-button-hoverBackground: #1177bb;
|
||||
--vscode-button-secondaryForeground: #ffffff;
|
||||
--vscode-button-secondaryBackground: #3a3d41;
|
||||
--vscode-button-secondaryHoverBackground: #45494e;
|
||||
--vscode-badge-background: #4d4d4d;
|
||||
--vscode-badge-foreground: #ffffff;
|
||||
--vscode-scrollbar-shadow: #000000;
|
||||
--vscode-scrollbarSlider-background: rgba(121, 121, 121, 0.4);
|
||||
--vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7);
|
||||
--vscode-scrollbarSlider-activeBackground: rgba(191, 191, 191, 0.4);
|
||||
--vscode-progressBar-background: #0e70c0;
|
||||
--vscode-editorError-foreground: #f14c4c;
|
||||
--vscode-editorWarning-foreground: #cca700;
|
||||
--vscode-editorInfo-foreground: #3794ff;
|
||||
--vscode-editorHint-foreground: rgba(238, 238, 238, 0.7);
|
||||
--vscode-sash-hoverBorder: #007fd4;
|
||||
--vscode-editor-background: #1e1e1e;
|
||||
--vscode-editor-foreground: #d4d4d4;
|
||||
--vscode-editorStickyScroll-background: #1e1e1e;
|
||||
--vscode-editorStickyScrollHover-background: #2a2d2e;
|
||||
--vscode-editorWidget-background: #252526;
|
||||
--vscode-editorWidget-foreground: #cccccc;
|
||||
--vscode-editorWidget-border: #454545;
|
||||
--vscode-quickInput-background: #252526;
|
||||
--vscode-quickInput-foreground: #cccccc;
|
||||
--vscode-quickInputTitle-background: rgba(255, 255, 255, 0.1);
|
||||
--vscode-pickerGroup-foreground: #3794ff;
|
||||
--vscode-pickerGroup-border: #3f3f46;
|
||||
--vscode-keybindingLabel-background: rgba(128, 128, 128, 0.17);
|
||||
--vscode-keybindingLabel-foreground: #cccccc;
|
||||
--vscode-keybindingLabel-border: rgba(51, 51, 51, 0.6);
|
||||
--vscode-keybindingLabel-bottomBorder: rgba(68, 68, 68, 0.6);
|
||||
--vscode-editor-selectionBackground: #264f78;
|
||||
--vscode-editor-inactiveSelectionBackground: #3a3d41;
|
||||
--vscode-editor-selectionHighlightBackground: rgba(173, 214, 255, 0.15);
|
||||
--vscode-editor-findMatchBackground: #515c6a;
|
||||
--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);
|
||||
--vscode-editor-findRangeHighlightBackground: rgba(58, 61, 65, 0.4);
|
||||
--vscode-searchEditor-findMatchBackground: rgba(234, 92, 0, 0.22);
|
||||
--vscode-editor-hoverHighlightBackground: rgba(38, 79, 120, 0.25);
|
||||
--vscode-editorHoverWidget-background: #252526;
|
||||
--vscode-editorHoverWidget-foreground: #cccccc;
|
||||
--vscode-editorHoverWidget-border: #454545;
|
||||
--vscode-editorHoverWidget-statusBarBackground: #2c2c2d;
|
||||
--vscode-editorLink-activeForeground: #4e94ce;
|
||||
--vscode-editorInlayHint-foreground: rgba(255, 255, 255, 0.8);
|
||||
--vscode-editorInlayHint-background: rgba(77, 77, 77, 0.6);
|
||||
--vscode-editorInlayHint-typeForeground: rgba(255, 255, 255, 0.8);
|
||||
--vscode-editorInlayHint-typeBackground: rgba(77, 77, 77, 0.6);
|
||||
--vscode-editorInlayHint-parameterForeground: rgba(255, 255, 255, 0.8);
|
||||
--vscode-editorInlayHint-parameterBackground: rgba(77, 77, 77, 0.6);
|
||||
--vscode-editorLightBulb-foreground: #ffcc00;
|
||||
--vscode-editorLightBulbAutoFix-foreground: #75beff;
|
||||
--vscode-diffEditor-insertedTextBackground: rgba(156, 204, 44, 0.2);
|
||||
--vscode-diffEditor-removedTextBackground: rgba(255, 0, 0, 0.4);
|
||||
--vscode-diffEditor-insertedLineBackground: rgba(155, 185, 85, 0.2);
|
||||
--vscode-diffEditor-removedLineBackground: rgba(255, 0, 0, 0.2);
|
||||
--vscode-diffEditor-diagonalFill: rgba(204, 204, 204, 0.2);
|
||||
--vscode-list-focusOutline: #007fd4;
|
||||
--vscode-list-activeSelectionBackground: #04395e;
|
||||
--vscode-list-activeSelectionForeground: #ffffff;
|
||||
--vscode-list-activeSelectionIconForeground: #ffffff;
|
||||
--vscode-list-inactiveSelectionBackground: #37373d;
|
||||
--vscode-list-hoverBackground: #2a2d2e;
|
||||
--vscode-list-dropBackground: #383b3d;
|
||||
--vscode-list-highlightForeground: #2aaaff;
|
||||
--vscode-list-focusHighlightForeground: #2aaaff;
|
||||
--vscode-list-invalidItemForeground: #b89500;
|
||||
--vscode-list-errorForeground: #f88070;
|
||||
--vscode-list-warningForeground: #cca700;
|
||||
--vscode-listFilterWidget-background: #252526;
|
||||
--vscode-listFilterWidget-outline: rgba(0, 0, 0, 0);
|
||||
--vscode-listFilterWidget-noMatchesOutline: #be1100;
|
||||
--vscode-listFilterWidget-shadow: rgba(0, 0, 0, 0.36);
|
||||
--vscode-list-filterMatchBackground: rgba(234, 92, 0, 0.33);
|
||||
--vscode-tree-indentGuidesStroke: #585858;
|
||||
--vscode-tree-tableColumnsBorder: rgba(204, 204, 204, 0.13);
|
||||
--vscode-tree-tableOddRowsBackground: rgba(204, 204, 204, 0.04);
|
||||
--vscode-list-deemphasizedForeground: #8c8c8c;
|
||||
--vscode-quickInputList-focusForeground: #ffffff;
|
||||
--vscode-quickInputList-focusIconForeground: #ffffff;
|
||||
--vscode-quickInputList-focusBackground: #04395e;
|
||||
--vscode-menu-foreground: #cccccc;
|
||||
--vscode-menu-background: #303031;
|
||||
--vscode-menu-selectionForeground: #ffffff;
|
||||
--vscode-menu-selectionBackground: #04395e;
|
||||
--vscode-menu-separatorBackground: #606060;
|
||||
--vscode-toolbar-hoverBackground: rgba(90, 93, 94, 0.31);
|
||||
--vscode-toolbar-activeBackground: rgba(99, 102, 103, 0.31);
|
||||
--vscode-editor-snippetTabstopHighlightBackground: rgba(124, 124, 124, 0.3);
|
||||
--vscode-editor-snippetFinalTabstopHighlightBorder: #525252;
|
||||
--vscode-breadcrumb-foreground: rgba(204, 204, 204, 0.8);
|
||||
--vscode-breadcrumb-background: #1e1e1e;
|
||||
--vscode-breadcrumb-focusForeground: #e0e0e0;
|
||||
--vscode-breadcrumb-activeSelectionForeground: #e0e0e0;
|
||||
--vscode-breadcrumbPicker-background: #252526;
|
||||
--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, 0.5);
|
||||
--vscode-merge-currentContentBackground: rgba(64, 200, 174, 0.2);
|
||||
--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, 0.5);
|
||||
--vscode-merge-incomingContentBackground: rgba(64, 166, 255, 0.2);
|
||||
--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, 0.4);
|
||||
--vscode-merge-commonContentBackground: rgba(96, 96, 96, 0.16);
|
||||
--vscode-editorOverviewRuler-currentContentForeground: rgba(
|
||||
64,
|
||||
200,
|
||||
174,
|
||||
0.5
|
||||
);
|
||||
--vscode-editorOverviewRuler-incomingContentForeground: rgba(
|
||||
64,
|
||||
166,
|
||||
255,
|
||||
0.5
|
||||
);
|
||||
--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, 0.4);
|
||||
--vscode-editorOverviewRuler-findMatchForeground: rgba(209, 134, 22, 0.49);
|
||||
--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(
|
||||
160,
|
||||
160,
|
||||
160,
|
||||
0.8
|
||||
);
|
||||
--vscode-minimap-findMatchHighlight: #d18616;
|
||||
--vscode-minimap-selectionOccurrenceHighlight: #676767;
|
||||
--vscode-minimap-selectionHighlight: #264f78;
|
||||
--vscode-minimap-errorHighlight: rgba(255, 18, 18, 0.7);
|
||||
--vscode-minimap-warningHighlight: #cca700;
|
||||
--vscode-minimap-foregroundOpacity: #000000;
|
||||
--vscode-minimapSlider-background: rgba(121, 121, 121, 0.2);
|
||||
--vscode-minimapSlider-hoverBackground: rgba(100, 100, 100, 0.35);
|
||||
--vscode-minimapSlider-activeBackground: rgba(191, 191, 191, 0.2);
|
||||
--vscode-problemsErrorIcon-foreground: #f14c4c;
|
||||
--vscode-problemsWarningIcon-foreground: #cca700;
|
||||
--vscode-problemsInfoIcon-foreground: #3794ff;
|
||||
--vscode-charts-foreground: #cccccc;
|
||||
--vscode-charts-lines: rgba(204, 204, 204, 0.5);
|
||||
--vscode-charts-red: #f14c4c;
|
||||
--vscode-charts-blue: #3794ff;
|
||||
--vscode-charts-yellow: #cca700;
|
||||
--vscode-charts-orange: #d18616;
|
||||
--vscode-charts-green: #89d185;
|
||||
--vscode-charts-purple: #b180d7;
|
||||
--vscode-editor-lineHighlightBorder: #282828;
|
||||
--vscode-editor-rangeHighlightBackground: rgba(255, 255, 255, 0.04);
|
||||
--vscode-editor-symbolHighlightBackground: rgba(234, 92, 0, 0.33);
|
||||
--vscode-editorCursor-foreground: #aeafad;
|
||||
--vscode-editorWhitespace-foreground: rgba(227, 228, 226, 0.16);
|
||||
--vscode-editorIndentGuide-background: #404040;
|
||||
--vscode-editorIndentGuide-activeBackground: #707070;
|
||||
--vscode-editorLineNumber-foreground: #858585;
|
||||
--vscode-editorActiveLineNumber-foreground: #c6c6c6;
|
||||
--vscode-editorLineNumber-activeForeground: #c6c6c6;
|
||||
--vscode-editorRuler-foreground: #5a5a5a;
|
||||
--vscode-editorCodeLens-foreground: #999999;
|
||||
--vscode-editorBracketMatch-background: rgba(0, 100, 0, 0.1);
|
||||
--vscode-editorBracketMatch-border: #888888;
|
||||
--vscode-editorOverviewRuler-border: rgba(127, 127, 127, 0.3);
|
||||
--vscode-editorGutter-background: #1e1e1e;
|
||||
--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, 0.67);
|
||||
--vscode-editorGhostText-foreground: rgba(255, 255, 255, 0.34);
|
||||
--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, 0.7);
|
||||
--vscode-editorOverviewRuler-warningForeground: #cca700;
|
||||
--vscode-editorOverviewRuler-infoForeground: #3794ff;
|
||||
--vscode-editorBracketHighlight-foreground1: #ffd700;
|
||||
--vscode-editorBracketHighlight-foreground2: #da70d6;
|
||||
--vscode-editorBracketHighlight-foreground3: #179fff;
|
||||
--vscode-editorBracketHighlight-foreground4: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketHighlight-foreground5: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketHighlight-foreground6: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketHighlight-unexpectedBracket\.foreground: rgba(
|
||||
255,
|
||||
18,
|
||||
18,
|
||||
0.8
|
||||
);
|
||||
--vscode-editorBracketPairGuide-background1: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-background2: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-background3: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-background4: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-background5: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-background6: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-activeBackground1: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-activeBackground2: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-activeBackground3: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-activeBackground4: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-activeBackground5: rgba(0, 0, 0, 0);
|
||||
--vscode-editorBracketPairGuide-activeBackground6: rgba(0, 0, 0, 0);
|
||||
--vscode-editorUnicodeHighlight-border: #bd9b03;
|
||||
--vscode-editorUnicodeHighlight-background: rgba(189, 155, 3, 0.15);
|
||||
--vscode-symbolIcon-arrayForeground: #cccccc;
|
||||
--vscode-symbolIcon-booleanForeground: #cccccc;
|
||||
--vscode-symbolIcon-classForeground: #ee9d28;
|
||||
--vscode-symbolIcon-colorForeground: #cccccc;
|
||||
--vscode-symbolIcon-constantForeground: #cccccc;
|
||||
--vscode-symbolIcon-constructorForeground: #b180d7;
|
||||
--vscode-symbolIcon-enumeratorForeground: #ee9d28;
|
||||
--vscode-symbolIcon-enumeratorMemberForeground: #75beff;
|
||||
--vscode-symbolIcon-eventForeground: #ee9d28;
|
||||
--vscode-symbolIcon-fieldForeground: #75beff;
|
||||
--vscode-symbolIcon-fileForeground: #cccccc;
|
||||
--vscode-symbolIcon-folderForeground: #cccccc;
|
||||
--vscode-symbolIcon-functionForeground: #b180d7;
|
||||
--vscode-symbolIcon-interfaceForeground: #75beff;
|
||||
--vscode-symbolIcon-keyForeground: #cccccc;
|
||||
--vscode-symbolIcon-keywordForeground: #cccccc;
|
||||
--vscode-symbolIcon-methodForeground: #b180d7;
|
||||
--vscode-symbolIcon-moduleForeground: #cccccc;
|
||||
--vscode-symbolIcon-namespaceForeground: #cccccc;
|
||||
--vscode-symbolIcon-nullForeground: #cccccc;
|
||||
--vscode-symbolIcon-numberForeground: #cccccc;
|
||||
--vscode-symbolIcon-objectForeground: #cccccc;
|
||||
--vscode-symbolIcon-operatorForeground: #cccccc;
|
||||
--vscode-symbolIcon-packageForeground: #cccccc;
|
||||
--vscode-symbolIcon-propertyForeground: #cccccc;
|
||||
--vscode-symbolIcon-referenceForeground: #cccccc;
|
||||
--vscode-symbolIcon-snippetForeground: #cccccc;
|
||||
--vscode-symbolIcon-stringForeground: #cccccc;
|
||||
--vscode-symbolIcon-structForeground: #cccccc;
|
||||
--vscode-symbolIcon-textForeground: #cccccc;
|
||||
--vscode-symbolIcon-typeParameterForeground: #cccccc;
|
||||
--vscode-symbolIcon-unitForeground: #cccccc;
|
||||
--vscode-symbolIcon-variableForeground: #75beff;
|
||||
--vscode-editorHoverWidget-highlightForeground: #2aaaff;
|
||||
--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;
|
||||
--vscode-editor-foldBackground: rgba(38, 79, 120, 0.3);
|
||||
--vscode-editorGutter-foldingControlForeground: #c5c5c5;
|
||||
--vscode-editor-linkedEditingBackground: rgba(255, 0, 0, 0.3);
|
||||
--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, 0.72);
|
||||
--vscode-editor-wordHighlightStrongBackground: rgba(0, 73, 114, 0.72);
|
||||
--vscode-editorOverviewRuler-wordHighlightForeground: rgba(
|
||||
160,
|
||||
160,
|
||||
160,
|
||||
0.8
|
||||
);
|
||||
--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(
|
||||
192,
|
||||
160,
|
||||
192,
|
||||
0.8
|
||||
);
|
||||
--vscode-peekViewTitle-background: rgba(55, 148, 255, 0.1);
|
||||
--vscode-peekViewTitleLabel-foreground: #ffffff;
|
||||
--vscode-peekViewTitleDescription-foreground: rgba(204, 204, 204, 0.7);
|
||||
--vscode-peekView-border: #3794ff;
|
||||
--vscode-peekViewResult-background: #252526;
|
||||
--vscode-peekViewResult-lineForeground: #bbbbbb;
|
||||
--vscode-peekViewResult-fileForeground: #ffffff;
|
||||
--vscode-peekViewResult-selectionBackground: rgba(51, 153, 255, 0.2);
|
||||
--vscode-peekViewResult-selectionForeground: #ffffff;
|
||||
--vscode-peekViewEditor-background: #001f33;
|
||||
--vscode-peekViewEditorGutter-background: #001f33;
|
||||
--vscode-peekViewResult-matchHighlightBackground: rgba(234, 92, 0, 0.3);
|
||||
--vscode-peekViewEditor-matchHighlightBackground: rgba(255, 143, 0, 0.6);
|
||||
--vscode-editorMarkerNavigationError-background: #f14c4c;
|
||||
--vscode-editorMarkerNavigationError-headerBackground: rgba(241, 76, 76, 0.1);
|
||||
--vscode-editorMarkerNavigationWarning-background: #cca700;
|
||||
--vscode-editorMarkerNavigationWarning-headerBackground: rgba(
|
||||
204,
|
||||
167,
|
||||
0,
|
||||
0.1
|
||||
);
|
||||
--vscode-editorMarkerNavigationInfo-background: #3794ff;
|
||||
--vscode-editorMarkerNavigationInfo-headerBackground: rgba(55, 148, 255, 0.1);
|
||||
--vscode-editorMarkerNavigation-background: #1e1e1e;
|
||||
--vscode-editorSuggestWidget-background: #252526;
|
||||
--vscode-editorSuggestWidget-border: #454545;
|
||||
--vscode-editorSuggestWidget-foreground: #d4d4d4;
|
||||
--vscode-editorSuggestWidget-selectedForeground: #ffffff;
|
||||
--vscode-editorSuggestWidget-selectedIconForeground: #ffffff;
|
||||
--vscode-editorSuggestWidget-selectedBackground: #04395e;
|
||||
--vscode-editorSuggestWidget-highlightForeground: #2aaaff;
|
||||
--vscode-editorSuggestWidget-focusHighlightForeground: #2aaaff;
|
||||
--vscode-editorSuggestWidgetStatus-foreground: rgba(212, 212, 212, 0.5);
|
||||
--vscode-tab-activeBackground: #1e1e1e;
|
||||
--vscode-tab-unfocusedActiveBackground: #1e1e1e;
|
||||
--vscode-tab-inactiveBackground: #2d2d2d;
|
||||
--vscode-tab-unfocusedInactiveBackground: #2d2d2d;
|
||||
--vscode-tab-activeForeground: #ffffff;
|
||||
--vscode-tab-inactiveForeground: rgba(255, 255, 255, 0.5);
|
||||
--vscode-tab-unfocusedActiveForeground: rgba(255, 255, 255, 0.5);
|
||||
--vscode-tab-unfocusedInactiveForeground: rgba(255, 255, 255, 0.25);
|
||||
--vscode-tab-border: #252526;
|
||||
--vscode-tab-lastPinnedBorder: rgba(204, 204, 204, 0.2);
|
||||
--vscode-tab-activeModifiedBorder: #3399cc;
|
||||
--vscode-tab-inactiveModifiedBorder: rgba(51, 153, 204, 0.5);
|
||||
--vscode-tab-unfocusedActiveModifiedBorder: rgba(51, 153, 204, 0.5);
|
||||
--vscode-tab-unfocusedInactiveModifiedBorder: rgba(51, 153, 204, 0.25);
|
||||
--vscode-editorPane-background: #1e1e1e;
|
||||
--vscode-editorGroupHeader-tabsBackground: #252526;
|
||||
--vscode-editorGroupHeader-noTabsBackground: #1e1e1e;
|
||||
--vscode-editorGroup-border: #444444;
|
||||
--vscode-editorGroup-dropBackground: rgba(83, 89, 93, 0.5);
|
||||
--vscode-editorGroup-dropIntoPromptForeground: #cccccc;
|
||||
--vscode-editorGroup-dropIntoPromptBackground: #252526;
|
||||
--vscode-sideBySideEditor-horizontalBorder: #444444;
|
||||
--vscode-sideBySideEditor-verticalBorder: #444444;
|
||||
--vscode-panel-background: #1e1e1e;
|
||||
--vscode-panel-border: rgba(128, 128, 128, 0.35);
|
||||
--vscode-panelTitle-activeForeground: #e7e7e7;
|
||||
--vscode-panelTitle-inactiveForeground: rgba(231, 231, 231, 0.6);
|
||||
--vscode-panelTitle-activeBorder: #e7e7e7;
|
||||
--vscode-panel-dropBorder: #e7e7e7;
|
||||
--vscode-panelSection-dropBackground: rgba(83, 89, 93, 0.5);
|
||||
--vscode-panelSectionHeader-background: rgba(128, 128, 128, 0.2);
|
||||
--vscode-panelSection-border: rgba(128, 128, 128, 0.35);
|
||||
--vscode-banner-background: #04395e;
|
||||
--vscode-banner-foreground: #ffffff;
|
||||
--vscode-banner-iconForeground: #3794ff;
|
||||
--vscode-statusBar-foreground: #ffffff;
|
||||
--vscode-statusBar-noFolderForeground: #ffffff;
|
||||
--vscode-statusBar-background: #007acc;
|
||||
--vscode-statusBar-noFolderBackground: #68217a;
|
||||
--vscode-statusBar-focusBorder: #ffffff;
|
||||
--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, 0.18);
|
||||
--vscode-statusBarItem-focusBorder: #ffffff;
|
||||
--vscode-statusBarItem-hoverBackground: rgba(255, 255, 255, 0.12);
|
||||
--vscode-statusBarItem-compactHoverBackground: rgba(255, 255, 255, 0.2);
|
||||
--vscode-statusBarItem-prominentForeground: #ffffff;
|
||||
--vscode-statusBarItem-prominentBackground: rgba(0, 0, 0, 0.5);
|
||||
--vscode-statusBarItem-prominentHoverBackground: rgba(0, 0, 0, 0.3);
|
||||
--vscode-statusBarItem-errorBackground: #c72e0f;
|
||||
--vscode-statusBarItem-errorForeground: #ffffff;
|
||||
--vscode-statusBarItem-warningBackground: #7a6400;
|
||||
--vscode-statusBarItem-warningForeground: #ffffff;
|
||||
--vscode-activityBar-background: #333333;
|
||||
--vscode-activityBar-foreground: #ffffff;
|
||||
--vscode-activityBar-inactiveForeground: rgba(255, 255, 255, 0.4);
|
||||
--vscode-activityBar-activeBorder: #ffffff;
|
||||
--vscode-activityBar-dropBorder: #ffffff;
|
||||
--vscode-activityBarBadge-background: #007acc;
|
||||
--vscode-activityBarBadge-foreground: #ffffff;
|
||||
--vscode-statusBarItem-remoteBackground: #16825d;
|
||||
--vscode-statusBarItem-remoteForeground: #ffffff;
|
||||
--vscode-extensionBadge-remoteBackground: #007acc;
|
||||
--vscode-extensionBadge-remoteForeground: #ffffff;
|
||||
--vscode-sideBar-background: #252526;
|
||||
--vscode-sideBarTitle-foreground: #bbbbbb;
|
||||
--vscode-sideBar-dropBackground: rgba(83, 89, 93, 0.5);
|
||||
--vscode-sideBarSectionHeader-background: rgba(0, 0, 0, 0);
|
||||
--vscode-sideBarSectionHeader-border: rgba(204, 204, 204, 0.2);
|
||||
--vscode-titleBar-activeForeground: #cccccc;
|
||||
--vscode-titleBar-inactiveForeground: rgba(204, 204, 204, 0.6);
|
||||
--vscode-titleBar-activeBackground: #3c3c3c;
|
||||
--vscode-titleBar-inactiveBackground: rgba(60, 60, 60, 0.6);
|
||||
--vscode-menubar-selectionForeground: #cccccc;
|
||||
--vscode-menubar-selectionBackground: rgba(90, 93, 94, 0.31);
|
||||
--vscode-notifications-foreground: #cccccc;
|
||||
--vscode-notifications-background: #252526;
|
||||
--vscode-notificationLink-foreground: #3794ff;
|
||||
--vscode-notificationCenterHeader-background: #303031;
|
||||
--vscode-notifications-border: #303031;
|
||||
--vscode-notificationsErrorIcon-foreground: #f14c4c;
|
||||
--vscode-notificationsWarningIcon-foreground: #cca700;
|
||||
--vscode-notificationsInfoIcon-foreground: #3794ff;
|
||||
--vscode-commandCenter-foreground: #cccccc;
|
||||
--vscode-commandCenter-activeForeground: #cccccc;
|
||||
--vscode-commandCenter-activeBackground: rgba(90, 93, 94, 0.31);
|
||||
--vscode-commandCenter-border: rgba(128, 128, 128, 0.35);
|
||||
--vscode-editorCommentsWidget-resolvedBorder: rgba(204, 204, 204, 0.5);
|
||||
--vscode-editorCommentsWidget-unresolvedBorder: #3794ff;
|
||||
--vscode-editorCommentsWidget-rangeBackground: rgba(55, 148, 255, 0.1);
|
||||
--vscode-editorCommentsWidget-rangeBorder: rgba(55, 148, 255, 0.4);
|
||||
--vscode-editorCommentsWidget-rangeActiveBackground: rgba(55, 148, 255, 0.1);
|
||||
--vscode-editorCommentsWidget-rangeActiveBorder: rgba(55, 148, 255, 0.4);
|
||||
--vscode-editorGutter-commentRangeForeground: #37373d;
|
||||
--vscode-debugToolBar-background: #333333;
|
||||
--vscode-debugIcon-startForeground: #89d185;
|
||||
--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 0, 0.2);
|
||||
--vscode-editor-focusedStackFrameHighlightBackground: rgba(
|
||||
122,
|
||||
189,
|
||||
122,
|
||||
0.3
|
||||
);
|
||||
--vscode-mergeEditor-change\.background: rgba(155, 185, 85, 0.2);
|
||||
--vscode-mergeEditor-change\.word\.background: rgba(156, 204, 44, 0.2);
|
||||
--vscode-mergeEditor-conflict\.unhandledUnfocused\.border: rgba(
|
||||
255,
|
||||
166,
|
||||
0,
|
||||
0.48
|
||||
);
|
||||
--vscode-mergeEditor-conflict\.unhandledFocused\.border: #ffa600;
|
||||
--vscode-mergeEditor-conflict\.handledUnfocused\.border: rgba(
|
||||
134,
|
||||
134,
|
||||
134,
|
||||
0.29
|
||||
);
|
||||
--vscode-mergeEditor-conflict\.handledFocused\.border: rgba(
|
||||
193,
|
||||
193,
|
||||
193,
|
||||
0.8
|
||||
);
|
||||
--vscode-mergeEditor-conflict\.handled\.minimapOverViewRuler: rgba(
|
||||
173,
|
||||
172,
|
||||
168,
|
||||
0.93
|
||||
);
|
||||
--vscode-mergeEditor-conflict\.unhandled\.minimapOverViewRuler: #fcba03;
|
||||
--vscode-mergeEditor-conflictingLines\.background: rgba(255, 234, 0, 0.28);
|
||||
--vscode-settings-headerForeground: #e7e7e7;
|
||||
--vscode-settings-modifiedItemIndicator: #0c7d9d;
|
||||
--vscode-settings-headerBorder: rgba(128, 128, 128, 0.35);
|
||||
--vscode-settings-sashBorder: rgba(128, 128, 128, 0.35);
|
||||
--vscode-settings-dropdownBackground: #3c3c3c;
|
||||
--vscode-settings-dropdownForeground: #f0f0f0;
|
||||
--vscode-settings-dropdownBorder: #3c3c3c;
|
||||
--vscode-settings-dropdownListBorder: #454545;
|
||||
--vscode-settings-checkboxBackground: #3c3c3c;
|
||||
--vscode-settings-checkboxForeground: #f0f0f0;
|
||||
--vscode-settings-checkboxBorder: #3c3c3c;
|
||||
--vscode-settings-textInputBackground: #3c3c3c;
|
||||
--vscode-settings-textInputForeground: #cccccc;
|
||||
--vscode-settings-numberInputBackground: #3c3c3c;
|
||||
--vscode-settings-numberInputForeground: #cccccc;
|
||||
--vscode-settings-focusedRowBackground: rgba(42, 45, 46, 0.6);
|
||||
--vscode-settings-rowHoverBackground: rgba(42, 45, 46, 0.3);
|
||||
--vscode-settings-focusedRowBorder: rgba(255, 255, 255, 0.12);
|
||||
--vscode-terminal-foreground: #cccccc;
|
||||
--vscode-terminal-selectionBackground: #264f78;
|
||||
--vscode-terminal-inactiveSelectionBackground: #3a3d41;
|
||||
--vscode-terminalCommandDecoration-defaultBackground: rgba(
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
0.25
|
||||
);
|
||||
--vscode-terminalCommandDecoration-successBackground: #1b81a8;
|
||||
--vscode-terminalCommandDecoration-errorBackground: #f14c4c;
|
||||
--vscode-terminalOverviewRuler-cursorForeground: rgba(160, 160, 160, 0.8);
|
||||
--vscode-terminal-border: rgba(128, 128, 128, 0.35);
|
||||
--vscode-terminal-findMatchBackground: #515c6a;
|
||||
--vscode-terminal-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);
|
||||
--vscode-terminalOverviewRuler-findMatchForeground: rgba(209, 134, 22, 0.49);
|
||||
--vscode-terminal-dropBackground: rgba(83, 89, 93, 0.5);
|
||||
--vscode-testing-iconFailed: #f14c4c;
|
||||
--vscode-testing-iconErrored: #f14c4c;
|
||||
--vscode-testing-iconPassed: #73c991;
|
||||
--vscode-testing-runAction: #73c991;
|
||||
--vscode-testing-iconQueued: #cca700;
|
||||
--vscode-testing-iconUnset: #848484;
|
||||
--vscode-testing-iconSkipped: #848484;
|
||||
--vscode-testing-peekBorder: #f14c4c;
|
||||
--vscode-testing-peekHeaderBackground: rgba(241, 76, 76, 0.1);
|
||||
--vscode-testing-message\.error\.decorationForeground: #f14c4c;
|
||||
--vscode-testing-message\.error\.lineBackground: rgba(255, 0, 0, 0.2);
|
||||
--vscode-testing-message\.info\.decorationForeground: rgba(
|
||||
212,
|
||||
212,
|
||||
212,
|
||||
0.5
|
||||
);
|
||||
--vscode-welcomePage-tileBackground: #252526;
|
||||
--vscode-welcomePage-tileHoverBackground: #2c2c2d;
|
||||
--vscode-welcomePage-tileShadow: rgba(0, 0, 0, 0.36);
|
||||
--vscode-welcomePage-progress\.background: #3c3c3c;
|
||||
--vscode-welcomePage-progress\.foreground: #3794ff;
|
||||
--vscode-debugExceptionWidget-border: #a31515;
|
||||
--vscode-debugExceptionWidget-background: #420b0d;
|
||||
--vscode-ports-iconRunningProcessForeground: #369432;
|
||||
--vscode-statusBar-debuggingBackground: #cc6633;
|
||||
--vscode-statusBar-debuggingForeground: #ffffff;
|
||||
--vscode-editor-inlineValuesForeground: rgba(255, 255, 255, 0.5);
|
||||
--vscode-editor-inlineValuesBackground: rgba(255, 200, 0, 0.2);
|
||||
--vscode-editorGutter-modifiedBackground: #1b81a8;
|
||||
--vscode-editorGutter-addedBackground: #487e02;
|
||||
--vscode-editorGutter-deletedBackground: #f14c4c;
|
||||
--vscode-minimapGutter-modifiedBackground: #1b81a8;
|
||||
--vscode-minimapGutter-addedBackground: #487e02;
|
||||
--vscode-minimapGutter-deletedBackground: #f14c4c;
|
||||
--vscode-editorOverviewRuler-modifiedForeground: rgba(27, 129, 168, 0.6);
|
||||
--vscode-editorOverviewRuler-addedForeground: rgba(72, 126, 2, 0.6);
|
||||
--vscode-editorOverviewRuler-deletedForeground: rgba(241, 76, 76, 0.6);
|
||||
--vscode-debugIcon-breakpointForeground: #e51400;
|
||||
--vscode-debugIcon-breakpointDisabledForeground: #848484;
|
||||
--vscode-debugIcon-breakpointUnverifiedForeground: #848484;
|
||||
--vscode-debugIcon-breakpointCurrentStackframeForeground: #ffcc00;
|
||||
--vscode-debugIcon-breakpointStackframeForeground: #89d185;
|
||||
--vscode-notebook-cellBorderColor: #37373d;
|
||||
--vscode-notebook-focusedEditorBorder: #007fd4;
|
||||
--vscode-notebookStatusSuccessIcon-foreground: #89d185;
|
||||
--vscode-notebookStatusErrorIcon-foreground: #f48771;
|
||||
--vscode-notebookStatusRunningIcon-foreground: #cccccc;
|
||||
--vscode-notebook-cellToolbarSeparator: rgba(128, 128, 128, 0.35);
|
||||
--vscode-notebook-selectedCellBackground: #37373d;
|
||||
--vscode-notebook-selectedCellBorder: #37373d;
|
||||
--vscode-notebook-focusedCellBorder: #007fd4;
|
||||
--vscode-notebook-inactiveFocusedCellBorder: #37373d;
|
||||
--vscode-notebook-cellStatusBarItemHoverBackground: rgba(255, 255, 255, 0.15);
|
||||
--vscode-notebook-cellInsertionIndicator: #007fd4;
|
||||
--vscode-notebookScrollbarSlider-background: rgba(121, 121, 121, 0.4);
|
||||
--vscode-notebookScrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7);
|
||||
--vscode-notebookScrollbarSlider-activeBackground: rgba(191, 191, 191, 0.4);
|
||||
--vscode-notebook-symbolHighlightBackground: rgba(255, 255, 255, 0.04);
|
||||
--vscode-notebook-cellEditorBackground: #252526;
|
||||
--vscode-notebook-editorBackground: #1e1e1e;
|
||||
--vscode-keybindingTable-headerBackground: rgba(204, 204, 204, 0.04);
|
||||
--vscode-keybindingTable-rowsBackground: rgba(204, 204, 204, 0.04);
|
||||
--vscode-scm-providerBorder: #454545;
|
||||
--vscode-debugTokenExpression-name: #c586c0;
|
||||
--vscode-debugTokenExpression-value: rgba(204, 204, 204, 0.6);
|
||||
--vscode-debugTokenExpression-string: #ce9178;
|
||||
--vscode-debugTokenExpression-boolean: #4e94ce;
|
||||
--vscode-debugTokenExpression-number: #b5cea8;
|
||||
--vscode-debugTokenExpression-error: #f48771;
|
||||
--vscode-debugView-exceptionLabelForeground: #cccccc;
|
||||
--vscode-debugView-exceptionLabelBackground: #6c2022;
|
||||
--vscode-debugView-stateLabelForeground: #cccccc;
|
||||
--vscode-debugView-stateLabelBackground: rgba(136, 136, 136, 0.27);
|
||||
--vscode-debugView-valueChangedHighlight: #569cd6;
|
||||
--vscode-debugConsole-infoForeground: #3794ff;
|
||||
--vscode-debugConsole-warningForeground: #cca700;
|
||||
--vscode-debugConsole-errorForeground: #f48771;
|
||||
--vscode-debugConsole-sourceForeground: #cccccc;
|
||||
--vscode-debugConsoleInputIcon-foreground: #cccccc;
|
||||
--vscode-debugIcon-pauseForeground: #75beff;
|
||||
--vscode-debugIcon-stopForeground: #f48771;
|
||||
--vscode-debugIcon-disconnectForeground: #f48771;
|
||||
--vscode-debugIcon-restartForeground: #89d185;
|
||||
--vscode-debugIcon-stepOverForeground: #75beff;
|
||||
--vscode-debugIcon-stepIntoForeground: #75beff;
|
||||
--vscode-debugIcon-stepOutForeground: #75beff;
|
||||
--vscode-debugIcon-continueForeground: #75beff;
|
||||
--vscode-debugIcon-stepBackForeground: #75beff;
|
||||
--vscode-extensionButton-prominentBackground: #0e639c;
|
||||
--vscode-extensionButton-prominentForeground: #ffffff;
|
||||
--vscode-extensionButton-prominentHoverBackground: #1177bb;
|
||||
--vscode-extensionIcon-starForeground: #ff8e00;
|
||||
--vscode-extensionIcon-verifiedForeground: #3794ff;
|
||||
--vscode-extensionIcon-preReleaseForeground: #1d9271;
|
||||
--vscode-extensionIcon-sponsorForeground: #d758b3;
|
||||
--vscode-terminal-ansiBlack: #000000;
|
||||
--vscode-terminal-ansiRed: #cd3131;
|
||||
--vscode-terminal-ansiGreen: #0dbc79;
|
||||
--vscode-terminal-ansiYellow: #e5e510;
|
||||
--vscode-terminal-ansiBlue: #2472c8;
|
||||
--vscode-terminal-ansiMagenta: #bc3fbc;
|
||||
--vscode-terminal-ansiCyan: #11a8cd;
|
||||
--vscode-terminal-ansiWhite: #e5e5e5;
|
||||
--vscode-terminal-ansiBrightBlack: #666666;
|
||||
--vscode-terminal-ansiBrightRed: #f14c4c;
|
||||
--vscode-terminal-ansiBrightGreen: #23d18b;
|
||||
--vscode-terminal-ansiBrightYellow: #f5f543;
|
||||
--vscode-terminal-ansiBrightBlue: #3b8eea;
|
||||
--vscode-terminal-ansiBrightMagenta: #d670d6;
|
||||
--vscode-terminal-ansiBrightCyan: #29b8db;
|
||||
--vscode-terminal-ansiBrightWhite: #e5e5e5;
|
||||
--vscode-interactive-activeCodeBorder: #3794ff;
|
||||
--vscode-interactive-inactiveCodeBorder: #37373d;
|
||||
--vscode-gitDecoration-addedResourceForeground: #81b88b;
|
||||
--vscode-gitDecoration-modifiedResourceForeground: #e2c08d;
|
||||
--vscode-gitDecoration-deletedResourceForeground: #c74e39;
|
||||
--vscode-gitDecoration-renamedResourceForeground: #73c991;
|
||||
--vscode-gitDecoration-untrackedResourceForeground: #73c991;
|
||||
--vscode-gitDecoration-ignoredResourceForeground: #8c8c8c;
|
||||
--vscode-gitDecoration-stageModifiedResourceForeground: #e2c08d;
|
||||
--vscode-gitDecoration-stageDeletedResourceForeground: #c74e39;
|
||||
--vscode-gitDecoration-conflictingResourceForeground: #e4676b;
|
||||
--vscode-gitDecoration-submoduleResourceForeground: #8db9e2;
|
||||
--vscode-testExplorer-errorDecorationBackground: #5a1d1d;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is copied in the same way, but from the <body> element
|
||||
*/
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: var(--vscode-editor-foreground);
|
||||
font-family: var(--vscode-font-family);
|
||||
font-weight: var(--vscode-font-weight);
|
||||
font-size: var(--vscode-font-size);
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import * as messages from './pure/messages';
|
||||
import * as qsClient from './queryserver-client';
|
||||
import * as tmp from 'tmp-promise';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
import { DatabaseItem } from './databases';
|
||||
|
||||
/**
|
||||
@@ -16,16 +15,6 @@ import { DatabaseItem } from './databases';
|
||||
*/
|
||||
const MAX_UPGRADE_MESSAGE_LINES = 10;
|
||||
|
||||
/**
|
||||
* Check that we support non-destructive upgrades.
|
||||
*
|
||||
* This requires 3 features. The ability to compile an upgrade sequence; The ability to
|
||||
* run a non-destructive upgrades as a query; the ability to specify a target when
|
||||
* resolving upgrades. We check for a version of codeql that has all three features.
|
||||
*/
|
||||
export async function hasNondestructiveUpgradeCapabilities(qs: qsClient.QueryServerClient): Promise<boolean> {
|
||||
return semver.gte(await qs.cliServer.getVersion(), '2.4.2');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -43,7 +32,7 @@ export async function compileDatabaseUpgradeSequence(
|
||||
if (dbItem.contents === undefined || dbItem.contents.dbSchemeUri === undefined) {
|
||||
throw new Error('Database is invalid, and cannot be upgraded.');
|
||||
}
|
||||
if (!await hasNondestructiveUpgradeCapabilities(qs)) {
|
||||
if (!await qs.cliServer.cliConstraints.supportsNonDestructiveUpgrades()) {
|
||||
throw new Error('The version of codeql is too old to run non-destructive upgrades.');
|
||||
}
|
||||
// If possible just compile the upgrade sequence
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import * as Rdom from 'react-dom';
|
||||
|
||||
import {
|
||||
ToCompareViewMessage,
|
||||
SetComparisonsMessage,
|
||||
} from '../../pure/interface-types';
|
||||
import CompareSelector from './CompareSelector';
|
||||
import { vscode } from '../../view/vscode-api';
|
||||
import { vscode } from '../vscode-api';
|
||||
import CompareTable from './CompareTable';
|
||||
|
||||
import '../results/resultsView.css';
|
||||
|
||||
const emptyComparison: SetComparisonsMessage = {
|
||||
t: 'setComparisons',
|
||||
stats: {},
|
||||
@@ -75,10 +76,3 @@ export function Compare(_: Record<string, never>): JSX.Element {
|
||||
return <div>Error!</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Rdom.render(
|
||||
<Compare />,
|
||||
document.getElementById('root'),
|
||||
// Post a message to the extension when fully loaded.
|
||||
() => vscode.postMessage({ t: 'compareViewLoaded' })
|
||||
);
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { SetComparisonsMessage } from '../../pure/interface-types';
|
||||
import RawTableHeader from '../../view/RawTableHeader';
|
||||
import { className } from '../../view/result-table-utils';
|
||||
import RawTableHeader from '../results/RawTableHeader';
|
||||
import { className } from '../results/result-table-utils';
|
||||
import { ResultRow } from '../../pure/bqrs-cli-types';
|
||||
import RawTableRow from '../../view/RawTableRow';
|
||||
import { vscode } from '../../view/vscode-api';
|
||||
import RawTableRow from '../results/RawTableRow';
|
||||
import { vscode } from '../vscode-api';
|
||||
|
||||
interface Props {
|
||||
comparison: SetComparisonsMessage;
|
||||
10
extensions/ql-vscode/src/view/compare/index.tsx
Normal file
10
extensions/ql-vscode/src/view/compare/index.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { WebviewDefinition } from '../webview-interface';
|
||||
import { Compare } from './Compare';
|
||||
|
||||
const definition: WebviewDefinition = {
|
||||
component: <Compare />,
|
||||
loadedMessage: 'compareViewLoaded'
|
||||
};
|
||||
|
||||
export default definition;
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { AnalysisAlert } from '../shared/analysis-result';
|
||||
import { AnalysisAlert } from '../../remote-queries/shared/analysis-result';
|
||||
import CodePaths from './CodePaths';
|
||||
import FileCodeSnippet from './FileCodeSnippet';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { VSCodeDropdown, VSCodeLink, VSCodeOption, VSCodeTag } from '@vscode/web
|
||||
import * as React from 'react';
|
||||
import { ChangeEvent, useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { CodeFlow, AnalysisMessage, ResultSeverity } from '../shared/analysis-result';
|
||||
import { CodeFlow, AnalysisMessage, ResultSeverity } from '../../remote-queries/shared/analysis-result';
|
||||
import FileCodeSnippet from './FileCodeSnippet';
|
||||
import SectionTitle from './SectionTitle';
|
||||
import VerticalSpace from './VerticalSpace';
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { CodeSnippet, FileLink, HighlightedRegion, AnalysisMessage, ResultSeverity } from '../shared/analysis-result';
|
||||
import { CodeSnippet, FileLink, HighlightedRegion, AnalysisMessage, ResultSeverity } from '../../remote-queries/shared/analysis-result';
|
||||
import VerticalSpace from './VerticalSpace';
|
||||
import { createRemoteFileRef } from '../../pure/location-link-utils';
|
||||
import { parseHighlightedLine, shouldHighlightLine } from '../../pure/sarif-utils';
|
||||
@@ -1,18 +1,17 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import * as Rdom from 'react-dom';
|
||||
import { Flash, ThemeProvider } from '@primer/react';
|
||||
import { ToRemoteQueriesMessage } from '../../pure/interface-types';
|
||||
import { AnalysisSummary, RemoteQueryResult } from '../shared/remote-query-result';
|
||||
import { MAX_RAW_RESULTS } from '../shared/result-limits';
|
||||
import { vscode } from '../../view/vscode-api';
|
||||
import { AnalysisSummary, RemoteQueryResult } from '../../remote-queries/shared/remote-query-result';
|
||||
import { MAX_RAW_RESULTS } from '../../remote-queries/shared/result-limits';
|
||||
import { vscode } from '../vscode-api';
|
||||
import { VSCodeBadge, VSCodeButton } from '@vscode/webview-ui-toolkit/react';
|
||||
import SectionTitle from './SectionTitle';
|
||||
import VerticalSpace from './VerticalSpace';
|
||||
import HorizontalSpace from './HorizontalSpace';
|
||||
import ViewTitle from './ViewTitle';
|
||||
import DownloadButton from './DownloadButton';
|
||||
import { AnalysisResults, getAnalysisResultCount } from '../shared/analysis-result';
|
||||
import { AnalysisResults, getAnalysisResultCount } from '../../remote-queries/shared/analysis-result';
|
||||
import DownloadSpinner from './DownloadSpinner';
|
||||
import CollapsibleItem from './CollapsibleItem';
|
||||
import { AlertIcon, CodeSquareIcon, FileCodeIcon, RepoIcon, TerminalIcon } from '@primer/octicons-react';
|
||||
@@ -24,6 +23,9 @@ import SortRepoFilter, { Sort, sorter } from './SortRepoFilter';
|
||||
import LastUpdated from './LastUpdated';
|
||||
import RepoListCopyButton from './RepoListCopyButton';
|
||||
|
||||
import './baseStyles.css';
|
||||
import './remoteQueries.css';
|
||||
|
||||
const numOfReposInContractedMode = 10;
|
||||
|
||||
const emptyQueryResult: RemoteQueryResult = {
|
||||
@@ -440,10 +442,3 @@ export function RemoteQueries(): JSX.Element {
|
||||
return <div>There was an error displaying the view.</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Rdom.render(
|
||||
<RemoteQueries />,
|
||||
document.getElementById('root'),
|
||||
// Post a message to the extension when fully loaded.
|
||||
() => vscode.postMessage({ t: 'remoteQueryLoaded' })
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { vscode } from '../../view/vscode-api';
|
||||
import { RemoteQueryResult } from '../shared/remote-query-result';
|
||||
import { vscode } from '../vscode-api';
|
||||
import { RemoteQueryResult } from '../../remote-queries/shared/remote-query-result';
|
||||
import { CopyIcon } from '@primer/octicons-react';
|
||||
import { IconButton } from '@primer/react';
|
||||
|
||||
10
extensions/ql-vscode/src/view/remote-queries/index.tsx
Normal file
10
extensions/ql-vscode/src/view/remote-queries/index.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { WebviewDefinition } from '../webview-interface';
|
||||
import { RemoteQueries } from './RemoteQueries';
|
||||
|
||||
const definition: WebviewDefinition = {
|
||||
component: <RemoteQueries />,
|
||||
loadedMessage: 'remoteQueryLoaded'
|
||||
};
|
||||
|
||||
export default definition;
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { vscode } from './vscode-api';
|
||||
import { RawResultsSortState, SortDirection } from '../pure/interface-types';
|
||||
import { vscode } from '../vscode-api';
|
||||
import { RawResultsSortState, SortDirection } from '../../pure/interface-types';
|
||||
import { nextSortDirection } from './result-table-utils';
|
||||
import { Column } from '../pure/bqrs-cli-types';
|
||||
import { Column } from '../../pure/bqrs-cli-types';
|
||||
|
||||
interface Props {
|
||||
readonly columns: readonly Column[];
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { ResultRow } from '../pure/bqrs-cli-types';
|
||||
import { ResultRow } from '../../pure/bqrs-cli-types';
|
||||
import { zebraStripe } from './result-table-utils';
|
||||
import RawTableValue from './RawTableValue';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { renderLocation } from './result-table-utils';
|
||||
import { CellValue } from '../pure/bqrs-cli-types';
|
||||
import { CellValue } from '../../pure/bqrs-cli-types';
|
||||
|
||||
interface Props {
|
||||
value: CellValue;
|
||||
@@ -1,19 +1,19 @@
|
||||
import * as path from 'path';
|
||||
import * as React from 'react';
|
||||
import * as Sarif from 'sarif';
|
||||
import * as Keys from '../pure/result-keys';
|
||||
import * as Keys from '../../pure/result-keys';
|
||||
import * as octicons from './octicons';
|
||||
import { className, renderLocation, ResultTableProps, zebraStripe, selectableZebraStripe, jumpToLocation, nextSortDirection, emptyQueryResultsMessage } from './result-table-utils';
|
||||
import { onNavigation, NavigationEvent } from './results';
|
||||
import { InterpretedResultSet, SarifInterpretationData } from '../pure/interface-types';
|
||||
import { InterpretedResultSet, SarifInterpretationData } from '../../pure/interface-types';
|
||||
import {
|
||||
parseSarifPlainTextMessage,
|
||||
parseSarifLocation,
|
||||
isNoLocation
|
||||
} from '../pure/sarif-utils';
|
||||
import { InterpretedResultsSortColumn, SortDirection, InterpretedResultsSortState } from '../pure/interface-types';
|
||||
import { vscode } from './vscode-api';
|
||||
import { isWholeFileLoc, isLineColumnLoc } from '../pure/bqrs-utils';
|
||||
} from '../../pure/sarif-utils';
|
||||
import { InterpretedResultsSortColumn, SortDirection, InterpretedResultsSortState } from '../../pure/interface-types';
|
||||
import { vscode } from '../vscode-api';
|
||||
import { isWholeFileLoc, isLineColumnLoc } from '../../pure/bqrs-utils';
|
||||
|
||||
export type PathTableProps = ResultTableProps & { resultSet: InterpretedResultSet<SarifInterpretationData> };
|
||||
export interface PathTableState {
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import * as d3 from 'd3';
|
||||
import { ResultTableProps } from './result-table-utils';
|
||||
import { InterpretedResultSet, GraphInterpretationData } from '../pure/interface-types';
|
||||
import { InterpretedResultSet, GraphInterpretationData } from '../../pure/interface-types';
|
||||
import { graphviz } from 'd3-graphviz';
|
||||
import { jumpToLocation } from './result-table-utils';
|
||||
import { tryGetLocationFromString } from '../pure/bqrs-utils';
|
||||
import { tryGetLocationFromString } from '../../pure/bqrs-utils';
|
||||
export type GraphProps = ResultTableProps & { resultSet: InterpretedResultSet<GraphInterpretationData> };
|
||||
|
||||
const graphClassName = 'vscode-codeql__result-tables-graph';
|
||||
10
extensions/ql-vscode/src/view/results/index.tsx
Normal file
10
extensions/ql-vscode/src/view/results/index.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { WebviewDefinition } from '../webview-interface';
|
||||
import { ResultsApp } from './results';
|
||||
|
||||
const definition: WebviewDefinition = {
|
||||
component: <ResultsApp />,
|
||||
loadedMessage: 'resultViewLoaded'
|
||||
};
|
||||
|
||||
export default definition;
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { ResultTableProps, className, emptyQueryResultsMessage } from './result-table-utils';
|
||||
import { RAW_RESULTS_LIMIT, RawResultsSortState } from '../pure/interface-types';
|
||||
import { RawTableResultSet } from '../pure/interface-types';
|
||||
import { RAW_RESULTS_LIMIT, RawResultsSortState } from '../../pure/interface-types';
|
||||
import { RawTableResultSet } from '../../pure/interface-types';
|
||||
import RawTableHeader from './RawTableHeader';
|
||||
import RawTableRow from './RawTableRow';
|
||||
import { ResultRow } from '../pure/bqrs-cli-types';
|
||||
import { ResultRow } from '../../pure/bqrs-cli-types';
|
||||
|
||||
export type RawTableProps = ResultTableProps & {
|
||||
resultSet: RawTableResultSet;
|
||||
@@ -1,11 +1,11 @@
|
||||
import * as React from 'react';
|
||||
import { UrlValue, ResolvableLocationValue } from '../pure/bqrs-cli-types';
|
||||
import { isStringLoc, tryGetResolvableLocation } from '../pure/bqrs-utils';
|
||||
import { RawResultsSortState, QueryMetadata, SortDirection } from '../pure/interface-types';
|
||||
import { assertNever } from '../pure/helpers-pure';
|
||||
import { ResultSet } from '../pure/interface-types';
|
||||
import { vscode } from './vscode-api';
|
||||
import { convertNonPrintableChars } from '../text-utils';
|
||||
import { UrlValue, ResolvableLocationValue } from '../../pure/bqrs-cli-types';
|
||||
import { isStringLoc, tryGetResolvableLocation } from '../../pure/bqrs-utils';
|
||||
import { RawResultsSortState, QueryMetadata, SortDirection } from '../../pure/interface-types';
|
||||
import { assertNever } from '../../pure/helpers-pure';
|
||||
import { ResultSet } from '../../pure/interface-types';
|
||||
import { vscode } from '../vscode-api';
|
||||
import { convertNonPrintableChars } from '../../text-utils';
|
||||
|
||||
export interface ResultTableProps {
|
||||
resultSet: ResultSet;
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
getDefaultResultSetName,
|
||||
ParsedResultSets,
|
||||
IntoResultsViewMsg,
|
||||
} from '../pure/interface-types';
|
||||
} from '../../pure/interface-types';
|
||||
import { PathTable } from './alert-table';
|
||||
import { Graph } from './graph';
|
||||
import { RawTable } from './raw-results-table';
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
alertExtrasClassName,
|
||||
openFile
|
||||
} from './result-table-utils';
|
||||
import { vscode } from './vscode-api';
|
||||
import { vscode } from '../vscode-api';
|
||||
|
||||
|
||||
const FILE_PATH_REGEX = /^(?:.+[\\/])*(.+)$/;
|
||||
@@ -1,6 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import * as Rdom from 'react-dom';
|
||||
import { assertNever } from '../pure/helpers-pure';
|
||||
import { assertNever } from '../../pure/helpers-pure';
|
||||
import {
|
||||
DatabaseInfo,
|
||||
Interpretation,
|
||||
@@ -13,11 +12,12 @@ import {
|
||||
ALERTS_TABLE_NAME,
|
||||
GRAPH_TABLE_NAME,
|
||||
ParsedResultSets,
|
||||
} from '../pure/interface-types';
|
||||
} from '../../pure/interface-types';
|
||||
import { EventHandlers as EventHandlerList } from './event-handler-list';
|
||||
import { ResultTables } from './result-tables';
|
||||
import { ResultSet } from '../pure/interface-types';
|
||||
import { vscode } from './vscode-api';
|
||||
import { ResultSet } from '../../pure/interface-types';
|
||||
|
||||
import './resultsView.css';
|
||||
|
||||
/**
|
||||
* results.tsx
|
||||
@@ -72,7 +72,7 @@ export const onNavigation = new EventHandlerList<NavigationEvent>();
|
||||
/**
|
||||
* A minimal state container for displaying results.
|
||||
*/
|
||||
class App extends React.Component<Record<string, never>, ResultsViewState> {
|
||||
export class ResultsApp extends React.Component<Record<string, never>, ResultsViewState> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@@ -302,7 +302,6 @@ class App extends React.Component<Record<string, never>, ResultsViewState> {
|
||||
componentDidMount(): void {
|
||||
this.vscodeMessageHandler = this.vscodeMessageHandler.bind(this);
|
||||
window.addEventListener('message', this.vscodeMessageHandler);
|
||||
vscode.postMessage({ t: 'resultViewLoaded' });
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
@@ -319,5 +318,3 @@ class App extends React.Component<Record<string, never>, ResultsViewState> {
|
||||
: console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
}
|
||||
|
||||
Rdom.render(<App />, document.getElementById('root'));
|
||||
4
extensions/ql-vscode/src/view/webview-interface.ts
Normal file
4
extensions/ql-vscode/src/view/webview-interface.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export type WebviewDefinition = {
|
||||
component: JSX.Element,
|
||||
loadedMessage: 'compareViewLoaded' | 'remoteQueryLoaded' | 'resultViewLoaded';
|
||||
}
|
||||
36
extensions/ql-vscode/src/view/webview.tsx
Normal file
36
extensions/ql-vscode/src/view/webview.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { vscode } from './vscode-api';
|
||||
|
||||
import { WebviewDefinition } from './webview-interface';
|
||||
|
||||
// Allow all views to use Codicons
|
||||
import '@vscode/codicons/dist/codicon.css';
|
||||
|
||||
const render = () => {
|
||||
const element = document.getElementById('root');
|
||||
|
||||
if (!element) {
|
||||
console.error('Could not find element with id "root"');
|
||||
return;
|
||||
}
|
||||
|
||||
const viewName = element.dataset.view;
|
||||
if (!viewName) {
|
||||
console.error('Could not find view name in data-view attribute');
|
||||
return;
|
||||
}
|
||||
|
||||
// It's a lot harder to use dynamic imports since those don't import the CSS
|
||||
// and require a less strict CSP policy
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const view: WebviewDefinition = require(`./${viewName}/index.tsx`).default;
|
||||
|
||||
ReactDOM.render(
|
||||
view.component,
|
||||
document.getElementById('root'),
|
||||
// Post a message to the extension when fully loaded.
|
||||
() => vscode.postMessage({ t: view.loadedMessage })
|
||||
);
|
||||
};
|
||||
|
||||
render();
|
||||
@@ -44,7 +44,7 @@ const _10MB = _1MB * 10;
|
||||
|
||||
// CLI version to test. Hard code the latest as default. And be sure
|
||||
// to update the env if it is not otherwise set.
|
||||
const CLI_VERSION = process.env.CLI_VERSION || 'v2.10.3';
|
||||
const CLI_VERSION = process.env.CLI_VERSION || 'v2.10.4';
|
||||
process.env.CLI_VERSION = CLI_VERSION;
|
||||
|
||||
// Base dir where CLIs will be downloaded into
|
||||
|
||||
@@ -6,15 +6,14 @@ import { expect } from 'chai';
|
||||
import { window } from 'vscode';
|
||||
|
||||
import {
|
||||
convertGithubNwoToDatabaseUrl,
|
||||
convertLgtmUrlToDatabaseUrl,
|
||||
looksLikeLgtmUrl,
|
||||
findDirWithFile,
|
||||
looksLikeGithubRepo,
|
||||
} from '../../databaseFetcher';
|
||||
import { ProgressCallback } from '../../commandRunner';
|
||||
import * as pq from 'proxyquire';
|
||||
|
||||
const proxyquire = pq.noPreserveCache();
|
||||
import * as Octokit from '@octokit/rest';
|
||||
|
||||
describe('databaseFetcher', function() {
|
||||
// These tests make API calls and may need extra time to complete.
|
||||
@@ -25,20 +24,16 @@ describe('databaseFetcher', function() {
|
||||
let quickPickSpy: sinon.SinonStub;
|
||||
let progressSpy: ProgressCallback;
|
||||
let mockRequest: sinon.SinonStub;
|
||||
let mod: any;
|
||||
|
||||
const credentials = getMockCredentials(0);
|
||||
let octokit: Octokit.Octokit;
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox();
|
||||
quickPickSpy = sandbox.stub(window, 'showQuickPick');
|
||||
progressSpy = sandbox.spy();
|
||||
mockRequest = sandbox.stub();
|
||||
mod = proxyquire('../../databaseFetcher', {
|
||||
'./authentication': {
|
||||
Credentials: credentials,
|
||||
},
|
||||
});
|
||||
octokit = ({
|
||||
request: mockRequest,
|
||||
}) as unknown as Octokit.Octokit;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -90,11 +85,17 @@ describe('databaseFetcher', function() {
|
||||
mockRequest.resolves(mockApiResponse);
|
||||
quickPickSpy.resolves('javascript');
|
||||
const githubRepo = 'github/codeql';
|
||||
const { databaseUrl, name, owner } = await mod.convertGithubNwoToDatabaseUrl(
|
||||
const result = await convertGithubNwoToDatabaseUrl(
|
||||
githubRepo,
|
||||
credentials,
|
||||
octokit,
|
||||
progressSpy
|
||||
);
|
||||
expect(result).not.to.be.undefined;
|
||||
if (result === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { databaseUrl, name, owner } = result;
|
||||
|
||||
expect(databaseUrl).to.equal(
|
||||
'https://api.github.com/repos/github/codeql/code-scanning/codeql/databases/javascript'
|
||||
@@ -119,7 +120,7 @@ describe('databaseFetcher', function() {
|
||||
mockRequest.resolves(mockApiResponse);
|
||||
const githubRepo = 'foo/bar-not-real';
|
||||
await expect(
|
||||
mod.convertGithubNwoToDatabaseUrl(githubRepo, credentials, progressSpy)
|
||||
convertGithubNwoToDatabaseUrl(githubRepo, octokit, progressSpy)
|
||||
).to.be.rejectedWith(/Unable to get database/);
|
||||
expect(progressSpy).to.have.callCount(0);
|
||||
});
|
||||
@@ -133,19 +134,10 @@ describe('databaseFetcher', function() {
|
||||
mockRequest.resolves(mockApiResponse);
|
||||
const githubRepo = 'foo/bar-with-no-dbs';
|
||||
await expect(
|
||||
mod.convertGithubNwoToDatabaseUrl(githubRepo, credentials, progressSpy)
|
||||
convertGithubNwoToDatabaseUrl(githubRepo, octokit, progressSpy)
|
||||
).to.be.rejectedWith(/Unable to get database/);
|
||||
expect(progressSpy).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
function getMockCredentials(response: any) {
|
||||
mockRequest = sinon.stub().resolves(response);
|
||||
return {
|
||||
getOctokit: () => ({
|
||||
request: mockRequest,
|
||||
}),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
describe('convertLgtmUrlToDatabaseUrl', () => {
|
||||
|
||||
@@ -564,6 +564,11 @@ repository:
|
||||
keyword: 'query'
|
||||
name: storage.modifier.query.ql
|
||||
|
||||
signature:
|
||||
match:
|
||||
keyword: 'signature'
|
||||
name: storage.modifier.signature.ql
|
||||
|
||||
transient:
|
||||
match:
|
||||
keyword: 'transient'
|
||||
@@ -583,8 +588,14 @@ repository:
|
||||
- include: '#pragma'
|
||||
- include: '#private'
|
||||
- include: '#query'
|
||||
- include: '#signature'
|
||||
- include: '#transient'
|
||||
|
||||
implements:
|
||||
match:
|
||||
keyword: 'implements'
|
||||
name: keyword.other.implements.ql
|
||||
|
||||
# A QL comment, regardless of form.
|
||||
comment:
|
||||
patterns:
|
||||
@@ -668,6 +679,19 @@ repository:
|
||||
- match: '(?#simple-id)'
|
||||
name: entity.name.type.namespace.ql
|
||||
|
||||
# The `implements` clause of a module definition.
|
||||
implements-clause:
|
||||
beginPattern: '#implements'
|
||||
# Ends at the first `{`.
|
||||
# REVIEW: This could be any token not allowed in a type.
|
||||
end: '(?= \{ )'
|
||||
name: meta.block.implements-clause.ql
|
||||
patterns:
|
||||
- include: '#non-context-sensitive'
|
||||
- match: '(?#simple-id)|(?#at-lower-id)'
|
||||
name: entity.name.type.ql
|
||||
|
||||
|
||||
# A `module` declaration, whether a module definition or an alias declaration.
|
||||
module-declaration:
|
||||
# Starts with the `module` keyword.
|
||||
@@ -677,6 +701,7 @@ repository:
|
||||
name: meta.block.module-declaration.ql
|
||||
patterns:
|
||||
- include: '#module-body'
|
||||
- include: '#implements-clause'
|
||||
- include: '#non-context-sensitive'
|
||||
# Any simple-id within a module head is part of a module name.
|
||||
- match: '(?#simple-id)'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user