Merge pull request #1566 from github/shati-elena/query-history-analysis-added
Emit `variantAnalysisAdded` event
This commit is contained in:
@@ -467,16 +467,16 @@ async function activateWithInstalledDistribution(
|
|||||||
const localQueryResultsView = new ResultsView(ctx, dbm, cliServer, queryServerLogger, labelProvider);
|
const localQueryResultsView = new ResultsView(ctx, dbm, cliServer, queryServerLogger, labelProvider);
|
||||||
ctx.subscriptions.push(localQueryResultsView);
|
ctx.subscriptions.push(localQueryResultsView);
|
||||||
|
|
||||||
void logger.log('Initializing remote queries manager.');
|
|
||||||
const rqm = new RemoteQueriesManager(ctx, cliServer, queryStorageDir, logger);
|
|
||||||
ctx.subscriptions.push(rqm);
|
|
||||||
|
|
||||||
void logger.log('Initializing variant analysis manager.');
|
void logger.log('Initializing variant analysis manager.');
|
||||||
const variantAnalysisStorageDir = path.join(ctx.globalStorageUri.fsPath, 'variant-analyses');
|
const variantAnalysisStorageDir = path.join(ctx.globalStorageUri.fsPath, 'variant-analyses');
|
||||||
await fs.ensureDir(variantAnalysisStorageDir);
|
await fs.ensureDir(variantAnalysisStorageDir);
|
||||||
const variantAnalysisManager = new VariantAnalysisManager(ctx, cliServer, variantAnalysisStorageDir, logger);
|
const variantAnalysisManager = new VariantAnalysisManager(ctx, cliServer, variantAnalysisStorageDir, logger);
|
||||||
ctx.subscriptions.push(variantAnalysisManager);
|
ctx.subscriptions.push(variantAnalysisManager);
|
||||||
|
|
||||||
|
void logger.log('Initializing remote queries manager.');
|
||||||
|
const rqm = new RemoteQueriesManager(ctx, cliServer, queryStorageDir, logger, variantAnalysisManager);
|
||||||
|
ctx.subscriptions.push(rqm);
|
||||||
|
|
||||||
void logger.log('Initializing query history.');
|
void logger.log('Initializing query history.');
|
||||||
const qhm = new QueryHistoryManager(
|
const qhm = new QueryHistoryManager(
|
||||||
qs,
|
qs,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { assertNever } from '../pure/helpers-pure';
|
|||||||
import { QueryStatus } from '../query-status';
|
import { QueryStatus } from '../query-status';
|
||||||
import { DisposableObject } from '../pure/disposable-object';
|
import { DisposableObject } from '../pure/disposable-object';
|
||||||
import { AnalysisResults } from './shared/analysis-result';
|
import { AnalysisResults } from './shared/analysis-result';
|
||||||
|
import { VariantAnalysisManager } from './variant-analysis-manager';
|
||||||
|
|
||||||
const autoDownloadMaxSize = 300 * 1024;
|
const autoDownloadMaxSize = 300 * 1024;
|
||||||
const autoDownloadMaxCount = 100;
|
const autoDownloadMaxCount = 100;
|
||||||
@@ -56,6 +57,7 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||||||
|
|
||||||
private readonly remoteQueriesMonitor: RemoteQueriesMonitor;
|
private readonly remoteQueriesMonitor: RemoteQueriesMonitor;
|
||||||
private readonly analysesResultsManager: AnalysesResultsManager;
|
private readonly analysesResultsManager: AnalysesResultsManager;
|
||||||
|
private readonly variantAnalysisManager: VariantAnalysisManager;
|
||||||
private readonly view: RemoteQueriesView;
|
private readonly view: RemoteQueriesView;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -63,11 +65,13 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||||||
private readonly cliServer: CodeQLCliServer,
|
private readonly cliServer: CodeQLCliServer,
|
||||||
private readonly storagePath: string,
|
private readonly storagePath: string,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
|
variantAnalysisManager: VariantAnalysisManager,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.analysesResultsManager = new AnalysesResultsManager(ctx, cliServer, storagePath, logger);
|
this.analysesResultsManager = new AnalysesResultsManager(ctx, cliServer, storagePath, logger);
|
||||||
this.view = new RemoteQueriesView(ctx, logger, this.analysesResultsManager);
|
this.view = new RemoteQueriesView(ctx, logger, this.analysesResultsManager);
|
||||||
this.remoteQueriesMonitor = new RemoteQueriesMonitor(ctx, logger);
|
this.remoteQueriesMonitor = new RemoteQueriesMonitor(ctx, logger);
|
||||||
|
this.variantAnalysisManager = variantAnalysisManager;
|
||||||
|
|
||||||
this.remoteQueryAddedEventEmitter = this.push(new EventEmitter<NewQueryEvent>());
|
this.remoteQueryAddedEventEmitter = this.push(new EventEmitter<NewQueryEvent>());
|
||||||
this.remoteQueryRemovedEventEmitter = this.push(new EventEmitter<RemovedQueryEvent>());
|
this.remoteQueryRemovedEventEmitter = this.push(new EventEmitter<RemovedQueryEvent>());
|
||||||
@@ -123,7 +127,8 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||||||
credentials, uri || window.activeTextEditor?.document.uri,
|
credentials, uri || window.activeTextEditor?.document.uri,
|
||||||
false,
|
false,
|
||||||
progress,
|
progress,
|
||||||
token);
|
token,
|
||||||
|
this.variantAnalysisManager);
|
||||||
|
|
||||||
if (querySubmission?.query) {
|
if (querySubmission?.query) {
|
||||||
const query = querySubmission.query;
|
const query = querySubmission.query;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import { getRepositorySelection, isValidSelection, RepositorySelection } from '.
|
|||||||
import { parseVariantAnalysisQueryLanguage, VariantAnalysisSubmission } from './shared/variant-analysis';
|
import { parseVariantAnalysisQueryLanguage, VariantAnalysisSubmission } from './shared/variant-analysis';
|
||||||
import { Repository } from './shared/repository';
|
import { Repository } from './shared/repository';
|
||||||
import { processVariantAnalysis } from './variant-analysis-processor';
|
import { processVariantAnalysis } from './variant-analysis-processor';
|
||||||
|
import { VariantAnalysisManager } from './variant-analysis-manager';
|
||||||
|
|
||||||
export interface QlPack {
|
export interface QlPack {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -182,7 +183,8 @@ export async function runRemoteQuery(
|
|||||||
uri: Uri | undefined,
|
uri: Uri | undefined,
|
||||||
dryRun: boolean,
|
dryRun: boolean,
|
||||||
progress: ProgressCallback,
|
progress: ProgressCallback,
|
||||||
token: CancellationToken
|
token: CancellationToken,
|
||||||
|
variantAnalysisManager: VariantAnalysisManager
|
||||||
): Promise<void | RemoteQuerySubmissionResult> {
|
): Promise<void | RemoteQuerySubmissionResult> {
|
||||||
if (!(await cliServer.cliConstraints.supportsRemoteQueries())) {
|
if (!(await cliServer.cliConstraints.supportsRemoteQueries())) {
|
||||||
throw new Error(`Variant analysis is not supported by this version of CodeQL. Please upgrade to v${cli.CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES
|
throw new Error(`Variant analysis is not supported by this version of CodeQL. Please upgrade to v${cli.CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES
|
||||||
@@ -273,6 +275,8 @@ export async function runRemoteQuery(
|
|||||||
|
|
||||||
const processedVariantAnalysis = processVariantAnalysis(variantAnalysisSubmission, variantAnalysisResponse);
|
const processedVariantAnalysis = processVariantAnalysis(variantAnalysisSubmission, variantAnalysisResponse);
|
||||||
|
|
||||||
|
variantAnalysisManager.onVariantAnalysisSubmitted(processedVariantAnalysis);
|
||||||
|
|
||||||
void logger.log(`Variant analysis:\n${JSON.stringify(processedVariantAnalysis, null, 2)}`);
|
void logger.log(`Variant analysis:\n${JSON.stringify(processedVariantAnalysis, null, 2)}`);
|
||||||
|
|
||||||
void showAndLogInformationMessage(`Variant analysis ${processedVariantAnalysis.query.name} submitted for processing`);
|
void showAndLogInformationMessage(`Variant analysis ${processedVariantAnalysis.query.name} submitted for processing`);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as ghApiClient from './gh-api/gh-api-client';
|
import * as ghApiClient from './gh-api/gh-api-client';
|
||||||
import { CancellationToken, ExtensionContext } from 'vscode';
|
import { CancellationToken, EventEmitter, ExtensionContext } from 'vscode';
|
||||||
import { DisposableObject } from '../pure/disposable-object';
|
import { DisposableObject } from '../pure/disposable-object';
|
||||||
import { Logger } from '../logging';
|
import { Logger } from '../logging';
|
||||||
import { Credentials } from '../authentication';
|
import { Credentials } from '../authentication';
|
||||||
@@ -21,6 +21,9 @@ import { VariantAnalysisResultsManager } from './variant-analysis-results-manage
|
|||||||
import { CodeQLCliServer } from '../cli';
|
import { CodeQLCliServer } from '../cli';
|
||||||
|
|
||||||
export class VariantAnalysisManager extends DisposableObject implements VariantAnalysisViewManager<VariantAnalysisView> {
|
export class VariantAnalysisManager extends DisposableObject implements VariantAnalysisViewManager<VariantAnalysisView> {
|
||||||
|
private readonly _onVariantAnalysisAdded = this.push(new EventEmitter<VariantAnalysis | undefined>());
|
||||||
|
readonly onVariantAnalysisAdded = this._onVariantAnalysisAdded.event;
|
||||||
|
|
||||||
private readonly variantAnalysisMonitor: VariantAnalysisMonitor;
|
private readonly variantAnalysisMonitor: VariantAnalysisMonitor;
|
||||||
private readonly variantAnalysisResultsManager: VariantAnalysisResultsManager;
|
private readonly variantAnalysisResultsManager: VariantAnalysisResultsManager;
|
||||||
private readonly views = new Map<number, VariantAnalysisView>();
|
private readonly views = new Map<number, VariantAnalysisView>();
|
||||||
@@ -73,6 +76,10 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
|
|||||||
await this.getView(variantAnalysis.id)?.updateView(variantAnalysis);
|
await this.getView(variantAnalysis.id)?.updateView(variantAnalysis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onVariantAnalysisSubmitted(variantAnalysis: VariantAnalysis): void {
|
||||||
|
this._onVariantAnalysisAdded.fire(variantAnalysis);
|
||||||
|
}
|
||||||
|
|
||||||
private async onRepoStateUpdated(variantAnalysisId: number, repoState: VariantAnalysisScannedRepositoryState): Promise<void> {
|
private async onRepoStateUpdated(variantAnalysisId: number, repoState: VariantAnalysisScannedRepositoryState): Promise<void> {
|
||||||
await this.getView(variantAnalysisId)?.updateRepoState(repoState);
|
await this.getView(variantAnalysisId)?.updateRepoState(repoState);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { assert, expect } from 'chai';
|
import { assert, expect } from 'chai';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import { CancellationTokenSource, extensions, QuickPickItem, Uri, window } from 'vscode';
|
import { CancellationTokenSource, ExtensionContext, extensions, QuickPickItem, Uri, window } from 'vscode';
|
||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
@@ -21,6 +21,9 @@ import {
|
|||||||
import { Repository } from '../../../remote-queries/gh-api/repository';
|
import { Repository } from '../../../remote-queries/gh-api/repository';
|
||||||
import { VariantAnalysisStatus } from '../../../remote-queries/shared/variant-analysis';
|
import { VariantAnalysisStatus } from '../../../remote-queries/shared/variant-analysis';
|
||||||
import { createMockApiResponse } from '../../factories/remote-queries/gh-api/variant-analysis-api-response';
|
import { createMockApiResponse } from '../../factories/remote-queries/gh-api/variant-analysis-api-response';
|
||||||
|
import { createMockExtensionContext } from '../../no-workspace';
|
||||||
|
import { VariantAnalysisManager } from '../../../remote-queries/variant-analysis-manager';
|
||||||
|
import { OutputChannelLogger } from '../../../logging';
|
||||||
|
|
||||||
describe('Remote queries', function() {
|
describe('Remote queries', function() {
|
||||||
const baseDir = path.join(__dirname, '../../../../src/vscode-tests/cli-integration');
|
const baseDir = path.join(__dirname, '../../../../src/vscode-tests/cli-integration');
|
||||||
@@ -37,6 +40,9 @@ describe('Remote queries', function() {
|
|||||||
let showQuickPickSpy: sinon.SinonStub;
|
let showQuickPickSpy: sinon.SinonStub;
|
||||||
let getRepositoryFromNwoStub: sinon.SinonStub;
|
let getRepositoryFromNwoStub: sinon.SinonStub;
|
||||||
let liveResultsStub: sinon.SinonStub;
|
let liveResultsStub: sinon.SinonStub;
|
||||||
|
let ctx: ExtensionContext;
|
||||||
|
let logger: any;
|
||||||
|
let variantAnalysisManager: VariantAnalysisManager;
|
||||||
|
|
||||||
// use `function` so we have access to `this`
|
// use `function` so we have access to `this`
|
||||||
beforeEach(async function() {
|
beforeEach(async function() {
|
||||||
@@ -49,6 +55,10 @@ describe('Remote queries', function() {
|
|||||||
throw new Error('Extension not initialized. Make sure cli is downloaded and installed properly.');
|
throw new Error('Extension not initialized. Make sure cli is downloaded and installed properly.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx = createMockExtensionContext();
|
||||||
|
logger = new OutputChannelLogger('test-logger');
|
||||||
|
variantAnalysisManager = new VariantAnalysisManager(ctx, cli, 'fake-storage-dir', logger);
|
||||||
|
|
||||||
if (!(await cli.cliConstraints.supportsRemoteQueries())) {
|
if (!(await cli.cliConstraints.supportsRemoteQueries())) {
|
||||||
console.log(`Remote queries are not supported on CodeQL CLI v${CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES
|
console.log(`Remote queries are not supported on CodeQL CLI v${CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES
|
||||||
}. Skipping this test.`);
|
}. Skipping this test.`);
|
||||||
@@ -94,7 +104,7 @@ describe('Remote queries', function() {
|
|||||||
it('should run a remote query that is part of a qlpack', async () => {
|
it('should run a remote query that is part of a qlpack', async () => {
|
||||||
const fileUri = getFile('data-remote-qlpack/in-pack.ql');
|
const fileUri = getFile('data-remote-qlpack/in-pack.ql');
|
||||||
|
|
||||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
expect(querySubmissionResult).to.be.ok;
|
expect(querySubmissionResult).to.be.ok;
|
||||||
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
||||||
printDirectoryContents(queryPackRootDir);
|
printDirectoryContents(queryPackRootDir);
|
||||||
@@ -155,7 +165,7 @@ describe('Remote queries', function() {
|
|||||||
it('should run a remote query that is not part of a qlpack', async () => {
|
it('should run a remote query that is not part of a qlpack', async () => {
|
||||||
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
||||||
|
|
||||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
expect(querySubmissionResult).to.be.ok;
|
expect(querySubmissionResult).to.be.ok;
|
||||||
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
||||||
|
|
||||||
@@ -218,7 +228,7 @@ describe('Remote queries', function() {
|
|||||||
it('should run a remote query that is nested inside a qlpack', async () => {
|
it('should run a remote query that is nested inside a qlpack', async () => {
|
||||||
const fileUri = getFile('data-remote-qlpack-nested/subfolder/in-pack.ql');
|
const fileUri = getFile('data-remote-qlpack-nested/subfolder/in-pack.ql');
|
||||||
|
|
||||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
expect(querySubmissionResult).to.be.ok;
|
expect(querySubmissionResult).to.be.ok;
|
||||||
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
const queryPackRootDir = querySubmissionResult!.queryDirPath!;
|
||||||
|
|
||||||
@@ -280,7 +290,7 @@ describe('Remote queries', function() {
|
|||||||
it('should cancel a run before uploading', async () => {
|
it('should cancel a run before uploading', async () => {
|
||||||
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
||||||
|
|
||||||
const promise = runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const promise = runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
|
|
||||||
cancellationTokenSource.token.isCancellationRequested = true;
|
cancellationTokenSource.token.isCancellationRequested = true;
|
||||||
|
|
||||||
@@ -306,7 +316,7 @@ describe('Remote queries', function() {
|
|||||||
it('should run a variant analysis that is part of a qlpack', async () => {
|
it('should run a variant analysis that is part of a qlpack', async () => {
|
||||||
const fileUri = getFile('data-remote-qlpack/in-pack.ql');
|
const fileUri = getFile('data-remote-qlpack/in-pack.ql');
|
||||||
|
|
||||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
expect(querySubmissionResult).to.be.ok;
|
expect(querySubmissionResult).to.be.ok;
|
||||||
const variantAnalysis = querySubmissionResult!.variantAnalysis!;
|
const variantAnalysis = querySubmissionResult!.variantAnalysis!;
|
||||||
expect(variantAnalysis.id).to.be.equal(mockApiResponse.id);
|
expect(variantAnalysis.id).to.be.equal(mockApiResponse.id);
|
||||||
@@ -319,7 +329,7 @@ describe('Remote queries', function() {
|
|||||||
it('should run a remote query that is not part of a qlpack', async () => {
|
it('should run a remote query that is not part of a qlpack', async () => {
|
||||||
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
||||||
|
|
||||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
expect(querySubmissionResult).to.be.ok;
|
expect(querySubmissionResult).to.be.ok;
|
||||||
const variantAnalysis = querySubmissionResult!.variantAnalysis!;
|
const variantAnalysis = querySubmissionResult!.variantAnalysis!;
|
||||||
expect(variantAnalysis.id).to.be.equal(mockApiResponse.id);
|
expect(variantAnalysis.id).to.be.equal(mockApiResponse.id);
|
||||||
@@ -332,7 +342,7 @@ describe('Remote queries', function() {
|
|||||||
it('should run a remote query that is nested inside a qlpack', async () => {
|
it('should run a remote query that is nested inside a qlpack', async () => {
|
||||||
const fileUri = getFile('data-remote-qlpack-nested/subfolder/in-pack.ql');
|
const fileUri = getFile('data-remote-qlpack-nested/subfolder/in-pack.ql');
|
||||||
|
|
||||||
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const querySubmissionResult = await runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
expect(querySubmissionResult).to.be.ok;
|
expect(querySubmissionResult).to.be.ok;
|
||||||
const variantAnalysis = querySubmissionResult!.variantAnalysis!;
|
const variantAnalysis = querySubmissionResult!.variantAnalysis!;
|
||||||
expect(variantAnalysis.id).to.be.equal(mockApiResponse.id);
|
expect(variantAnalysis.id).to.be.equal(mockApiResponse.id);
|
||||||
@@ -345,7 +355,7 @@ describe('Remote queries', function() {
|
|||||||
it('should cancel a run before uploading', async () => {
|
it('should cancel a run before uploading', async () => {
|
||||||
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
const fileUri = getFile('data-remote-no-qlpack/in-pack.ql');
|
||||||
|
|
||||||
const promise = runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token);
|
const promise = runRemoteQuery(cli, credentials, fileUri, true, progress, cancellationTokenSource.token, variantAnalysisManager);
|
||||||
|
|
||||||
cancellationTokenSource.token.isCancellationRequested = true;
|
cancellationTokenSource.token.isCancellationRequested = true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user