Skip to content

Commit 131d252

Browse files
authored
Merge pull request #1567 from github/koesie10/set-repo-results-message
Implement message for setting download status
2 parents 9002313 + 303a7d1 commit 131d252

File tree

9 files changed

+166
-45
lines changed

9 files changed

+166
-45
lines changed

extensions/ql-vscode/src/pure/interface-types.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import * as sarif from 'sarif';
22
import { AnalysisResults } from '../remote-queries/shared/analysis-result';
33
import { AnalysisSummary, RemoteQueryResult } from '../remote-queries/shared/remote-query-result';
44
import { RawResultSet, ResultRow, ResultSetSchema, Column, ResolvableLocationValue } from './bqrs-cli-types';
5-
import { VariantAnalysis } from '../remote-queries/shared/variant-analysis';
5+
import {
6+
VariantAnalysis,
7+
VariantAnalysisScannedRepositoryResult,
8+
VariantAnalysisScannedRepositoryState,
9+
} from '../remote-queries/shared/variant-analysis';
610

711
/**
812
* This module contains types and code that are shared between
@@ -436,8 +440,20 @@ export interface SetVariantAnalysisMessage {
436440
variantAnalysis: VariantAnalysis;
437441
}
438442

443+
export interface SetRepoResultsMessage {
444+
t: 'setRepoResults';
445+
repoResults: VariantAnalysisScannedRepositoryResult[];
446+
}
447+
448+
export interface SetRepoStatesMessage {
449+
t: 'setRepoStates';
450+
repoStates: VariantAnalysisScannedRepositoryState[];
451+
}
452+
439453
export type ToVariantAnalysisMessage =
440-
| SetVariantAnalysisMessage;
454+
| SetVariantAnalysisMessage
455+
| SetRepoResultsMessage
456+
| SetRepoStatesMessage;
441457

442458
export type FromVariantAnalysisMessage =
443459
| ViewLoadedMsg;

extensions/ql-vscode/src/remote-queries/shared/variant-analysis.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ export interface VariantAnalysisSkippedRepository {
8282
private?: boolean,
8383
}
8484

85+
export enum VariantAnalysisScannedRepositoryDownloadStatus {
86+
Pending = 'pending',
87+
InProgress = 'inProgress',
88+
Succeeded = 'succeeded',
89+
Failed = 'failed',
90+
}
91+
92+
export interface VariantAnalysisScannedRepositoryState {
93+
repositoryId: number;
94+
downloadStatus: VariantAnalysisScannedRepositoryDownloadStatus;
95+
}
96+
8597
export interface VariantAnalysisScannedRepositoryResult {
8698
repositoryId: number;
8799
interpretedResults?: AnalysisAlert[];

extensions/ql-vscode/src/remote-queries/variant-analysis-manager.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import {
1111
VariantAnalysisRepoTask,
1212
VariantAnalysisScannedRepository as ApiVariantAnalysisScannedRepository
1313
} from './gh-api/variant-analysis';
14-
import { VariantAnalysis } from './shared/variant-analysis';
14+
import {
15+
VariantAnalysis,
16+
VariantAnalysisScannedRepositoryDownloadStatus,
17+
VariantAnalysisScannedRepositoryState
18+
} from './shared/variant-analysis';
1519
import { getErrorMessage } from '../pure/helpers-pure';
1620
import { VariantAnalysisView } from './variant-analysis-view';
1721
import { VariantAnalysisViewManager } from './variant-analysis-view-manager';
@@ -52,17 +56,20 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
5256
this.views.delete(view.variantAnalysisId);
5357
}
5458

59+
public getView(variantAnalysisId: number): VariantAnalysisView | undefined {
60+
return this.views.get(variantAnalysisId);
61+
}
62+
5563
private async onVariantAnalysisUpdated(variantAnalysis: VariantAnalysis | undefined): Promise<void> {
5664
if (!variantAnalysis) {
5765
return;
5866
}
5967

60-
const view = this.views.get(variantAnalysis.id);
61-
if (!view) {
62-
return;
63-
}
68+
await this.getView(variantAnalysis.id)?.updateView(variantAnalysis);
69+
}
6470

65-
await view.updateView(variantAnalysis);
71+
private async onRepoStateUpdated(variantAnalysisId: number, repoState: VariantAnalysisScannedRepositoryState): Promise<void> {
72+
await this.getView(variantAnalysisId)?.updateRepoState(repoState);
6673
}
6774

6875
public async monitorVariantAnalysis(
@@ -77,11 +84,19 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
7784
variantAnalysisSummary: VariantAnalysisApiResponse,
7885
cancellationToken: CancellationToken
7986
): Promise<void> {
87+
const repoState = {
88+
repositoryId: scannedRepo.repository.id,
89+
downloadStatus: VariantAnalysisScannedRepositoryDownloadStatus.Pending,
90+
};
91+
92+
await this.onRepoStateUpdated(variantAnalysisSummary.id, repoState);
8093

8194
const credentials = await Credentials.initialize(this.ctx);
8295
if (!credentials) { throw Error('Error authenticating with GitHub'); }
8396

8497
if (cancellationToken && cancellationToken.isCancellationRequested) {
98+
repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.Failed;
99+
await this.onRepoStateUpdated(variantAnalysisSummary.id, repoState);
85100
return;
86101
}
87102

@@ -93,10 +108,16 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
93108
variantAnalysisSummary.id,
94109
scannedRepo.repository.id
95110
);
111+
} catch (e) {
112+
repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.Failed;
113+
await this.onRepoStateUpdated(variantAnalysisSummary.id, repoState);
114+
throw new Error(`Could not download the results for variant analysis with id: ${variantAnalysisSummary.id}. Error: ${getErrorMessage(e)}`);
96115
}
97-
catch (e) { throw new Error(`Could not download the results for variant analysis with id: ${variantAnalysisSummary.id}. Error: ${getErrorMessage(e)}`); }
98116

99117
if (repoTask.artifact_url) {
118+
repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.InProgress;
119+
await this.onRepoStateUpdated(variantAnalysisSummary.id, repoState);
120+
100121
const resultDirectory = path.join(
101122
this.ctx.globalStorageUri.fsPath,
102123
'variant-analyses',
@@ -117,5 +138,8 @@ export class VariantAnalysisManager extends DisposableObject implements VariantA
117138
fs.mkdirSync(resultDirectory, { recursive: true });
118139
await fs.writeFile(storagePath, JSON.stringify(result, null, 2), 'utf8');
119140
}
141+
142+
repoState.downloadStatus = VariantAnalysisScannedRepositoryDownloadStatus.Succeeded;
143+
await this.onRepoStateUpdated(variantAnalysisSummary.id, repoState);
120144
}
121145
}

extensions/ql-vscode/src/remote-queries/variant-analysis-view.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { AbstractWebview, WebviewPanelConfig } from '../abstract-webview';
33
import { WebviewMessage } from '../interface-utils';
44
import { logger } from '../logging';
55
import { VariantAnalysisViewInterface, VariantAnalysisViewManager } from './variant-analysis-view-manager';
6-
import { VariantAnalysis } from './shared/variant-analysis';
6+
import { VariantAnalysis, VariantAnalysisScannedRepositoryState } from './shared/variant-analysis';
77
import { FromVariantAnalysisMessage, ToVariantAnalysisMessage } from '../pure/interface-types';
88

99
export class VariantAnalysisView extends AbstractWebview<ToVariantAnalysisMessage, FromVariantAnalysisMessage> implements VariantAnalysisViewInterface {
@@ -32,6 +32,17 @@ export class VariantAnalysisView extends AbstractWebview<ToVariantAnalysisMessag
3232
});
3333
}
3434

35+
public async updateRepoState(repoState: VariantAnalysisScannedRepositoryState): Promise<void> {
36+
if (!this.isShowingPanel) {
37+
return;
38+
}
39+
40+
await this.postMessage({
41+
t: 'setRepoStates',
42+
repoStates: [repoState],
43+
});
44+
}
45+
3546
protected getPanelConfig(): WebviewPanelConfig {
3647
return {
3748
viewId: 'variantAnalysisView',

extensions/ql-vscode/src/stories/variant-analysis/RepoRow.stories.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import React from 'react';
33
import { ComponentMeta, ComponentStory } from '@storybook/react';
44

55
import { VariantAnalysisContainer } from '../../view/variant-analysis/VariantAnalysisContainer';
6-
import { VariantAnalysisRepoStatus } from '../../remote-queries/shared/variant-analysis';
6+
import {
7+
VariantAnalysisRepoStatus,
8+
VariantAnalysisScannedRepositoryDownloadStatus,
9+
} from '../../remote-queries/shared/variant-analysis';
710
import { AnalysisAlert, AnalysisRawResults } from '../../remote-queries/shared/analysis-result';
811

912
import analysesResults from '../remote-queries/data/analysesResultsMessage.json';
@@ -62,6 +65,14 @@ Canceled.args = {
6265
status: VariantAnalysisRepoStatus.Canceled,
6366
};
6467

68+
export const SucceededDownloading = Template.bind({});
69+
SucceededDownloading.args = {
70+
...Pending.args,
71+
status: VariantAnalysisRepoStatus.Succeeded,
72+
resultCount: 198,
73+
downloadStatus: VariantAnalysisScannedRepositoryDownloadStatus.InProgress,
74+
};
75+
6576
export const InterpretedResults = Template.bind({});
6677
InterpretedResults.args = {
6778
...Pending.args,

extensions/ql-vscode/src/view/variant-analysis/RepoRow.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import * as React from 'react';
22
import { useCallback, useState } from 'react';
33
import styled from 'styled-components';
44
import { VSCodeBadge, VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
5-
import { isCompletedAnalysisRepoStatus, VariantAnalysisRepoStatus } from '../../remote-queries/shared/variant-analysis';
5+
import {
6+
isCompletedAnalysisRepoStatus,
7+
VariantAnalysisRepoStatus,
8+
VariantAnalysisScannedRepositoryDownloadStatus
9+
} from '../../remote-queries/shared/variant-analysis';
610
import { formatDecimal } from '../../pure/number';
711
import { Codicon, ErrorIcon, LoadingIcon, SuccessIcon, WarningIcon } from '../common';
812
import { Repository } from '../../remote-queries/shared/repository';
@@ -62,6 +66,7 @@ export type RepoRowProps = {
6266
// Only fullName is required
6367
repository: Partial<Repository> & Pick<Repository, 'fullName'>;
6468
status?: VariantAnalysisRepoStatus;
69+
downloadStatus?: VariantAnalysisScannedRepositoryDownloadStatus;
6570
resultCount?: number;
6671

6772
interpretedResults?: AnalysisAlert[];
@@ -71,6 +76,7 @@ export type RepoRowProps = {
7176
export const RepoRow = ({
7277
repository,
7378
status,
79+
downloadStatus,
7480
resultCount,
7581
interpretedResults,
7682
rawResults,
@@ -99,6 +105,7 @@ export const RepoRow = ({
99105
{status === VariantAnalysisRepoStatus.InProgress && <LoadingIcon label="In progress" />}
100106
{!status && <WarningIcon />}
101107
</span>
108+
{downloadStatus === VariantAnalysisScannedRepositoryDownloadStatus.InProgress && <LoadingIcon label="Downloading" />}
102109
</TitleContainer>
103110
{isExpanded && status &&
104111
<AnalyzedRepoItemContent status={status} interpretedResults={interpretedResults} rawResults={rawResults} />}

extensions/ql-vscode/src/view/variant-analysis/VariantAnalysis.tsx

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import { ToVariantAnalysisMessage } from '../../pure/interface-types';
55
import {
66
VariantAnalysis as VariantAnalysisDomainModel,
77
VariantAnalysisQueryLanguage,
8-
VariantAnalysisRepoStatus, VariantAnalysisScannedRepositoryResult,
8+
VariantAnalysisRepoStatus, VariantAnalysisScannedRepositoryResult, VariantAnalysisScannedRepositoryState,
99
VariantAnalysisStatus
1010
} from '../../remote-queries/shared/variant-analysis';
11-
import { VariantAnalysisContainer } from './VariantAnalysisContainer';
1211
import { VariantAnalysisHeader } from './VariantAnalysisHeader';
1312
import { VariantAnalysisOutcomePanels } from './VariantAnalysisOutcomePanels';
1413
import { VariantAnalysisLoading } from './VariantAnalysisLoading';
@@ -200,45 +199,37 @@ const repositoryResults: VariantAnalysisScannedRepositoryResult[] = [
200199
}
201200
];
202201

203-
function getContainerContents(variantAnalysis: VariantAnalysisDomainModel) {
204-
if (variantAnalysis.actionsWorkflowRunId === undefined) {
205-
return <VariantAnalysisLoading />;
206-
}
207-
208-
return (
209-
<>
210-
<VariantAnalysisHeader
211-
variantAnalysis={variantAnalysis}
212-
onOpenQueryFileClick={() => console.log('Open query')}
213-
onViewQueryTextClick={() => console.log('View query')}
214-
onStopQueryClick={() => console.log('Stop query')}
215-
onCopyRepositoryListClick={() => console.log('Copy repository list')}
216-
onExportResultsClick={() => console.log('Export results')}
217-
onViewLogsClick={() => console.log('View logs')}
218-
/>
219-
<VariantAnalysisOutcomePanels
220-
variantAnalysis={variantAnalysis}
221-
repositoryResults={repositoryResults}
222-
/>
223-
</>
224-
);
225-
}
226-
227202
type Props = {
228203
variantAnalysis?: VariantAnalysisDomainModel;
204+
repoStates?: VariantAnalysisScannedRepositoryState[];
205+
repoResults?: VariantAnalysisScannedRepositoryResult[];
229206
}
230207

231208
export function VariantAnalysis({
232209
variantAnalysis: initialVariantAnalysis = variantAnalysis,
210+
repoStates: initialRepoStates = [],
211+
repoResults: initialRepoResults = repositoryResults,
233212
}: Props): JSX.Element {
234213
const [variantAnalysis, setVariantAnalysis] = useState<VariantAnalysisDomainModel>(initialVariantAnalysis);
214+
const [repoStates, setRepoStates] = useState<VariantAnalysisScannedRepositoryState[]>(initialRepoStates);
215+
const [repoResults, setRepoResults] = useState<VariantAnalysisScannedRepositoryResult[]>(initialRepoResults);
235216

236217
useEffect(() => {
237218
window.addEventListener('message', (evt: MessageEvent) => {
238219
if (evt.origin === window.origin) {
239220
const msg: ToVariantAnalysisMessage = evt.data;
240221
if (msg.t === 'setVariantAnalysis') {
241222
setVariantAnalysis(msg.variantAnalysis);
223+
} else if (msg.t === 'setRepoResults') {
224+
setRepoResults(oldRepoResults => {
225+
const newRepoIds = msg.repoResults.map(r => r.repositoryId);
226+
return [...oldRepoResults.filter(v => !newRepoIds.includes(v.repositoryId)), ...msg.repoResults];
227+
});
228+
} else if (msg.t === 'setRepoStates') {
229+
setRepoStates(oldRepoStates => {
230+
const newRepoIds = msg.repoStates.map(r => r.repositoryId);
231+
return [...oldRepoStates.filter(v => !newRepoIds.includes(v.repositoryId)), ...msg.repoStates];
232+
});
242233
}
243234
} else {
244235
// sanitize origin
@@ -248,9 +239,26 @@ export function VariantAnalysis({
248239
});
249240
});
250241

242+
if (variantAnalysis.actionsWorkflowRunId === undefined) {
243+
return <VariantAnalysisLoading />;
244+
}
245+
251246
return (
252-
<VariantAnalysisContainer>
253-
{getContainerContents(variantAnalysis)}
254-
</VariantAnalysisContainer>
247+
<>
248+
<VariantAnalysisHeader
249+
variantAnalysis={variantAnalysis}
250+
onOpenQueryFileClick={() => console.log('Open query')}
251+
onViewQueryTextClick={() => console.log('View query')}
252+
onStopQueryClick={() => console.log('Stop query')}
253+
onCopyRepositoryListClick={() => console.log('Copy repository list')}
254+
onExportResultsClick={() => console.log('Export results')}
255+
onViewLogsClick={() => console.log('View logs')}
256+
/>
257+
<VariantAnalysisOutcomePanels
258+
variantAnalysis={variantAnalysis}
259+
repositoryStates={repoStates}
260+
repositoryResults={repoResults}
261+
/>
262+
</>
255263
);
256264
}

extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisAnalyzedRepos.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import * as React from 'react';
22
import styled from 'styled-components';
3-
import { VariantAnalysis, VariantAnalysisScannedRepositoryResult } from '../../remote-queries/shared/variant-analysis';
43
import { RepoRow } from './RepoRow';
4+
import {
5+
VariantAnalysis,
6+
VariantAnalysisScannedRepositoryResult,
7+
VariantAnalysisScannedRepositoryState
8+
} from '../../remote-queries/shared/variant-analysis';
59
import { useMemo } from 'react';
610

711
const Container = styled.div`
@@ -12,13 +16,23 @@ const Container = styled.div`
1216

1317
export type VariantAnalysisAnalyzedReposProps = {
1418
variantAnalysis: VariantAnalysis;
19+
repositoryStates?: VariantAnalysisScannedRepositoryState[];
1520
repositoryResults?: VariantAnalysisScannedRepositoryResult[];
1621
}
1722

1823
export const VariantAnalysisAnalyzedRepos = ({
1924
variantAnalysis,
25+
repositoryStates,
2026
repositoryResults,
2127
}: VariantAnalysisAnalyzedReposProps) => {
28+
const repositoryStateById = useMemo(() => {
29+
const map = new Map<number, VariantAnalysisScannedRepositoryState>();
30+
repositoryStates?.forEach((repository) => {
31+
map.set(repository.repositoryId, repository);
32+
});
33+
return map;
34+
}, [repositoryStates]);
35+
2236
const repositoryResultsById = useMemo(() => {
2337
const map = new Map<number, VariantAnalysisScannedRepositoryResult>();
2438
repositoryResults?.forEach((repository) => {
@@ -30,13 +44,15 @@ export const VariantAnalysisAnalyzedRepos = ({
3044
return (
3145
<Container>
3246
{variantAnalysis.scannedRepos?.map(repository => {
47+
const state = repositoryStateById.get(repository.repository.id);
3348
const results = repositoryResultsById.get(repository.repository.id);
3449

3550
return (
3651
<RepoRow
3752
key={repository.repository.id}
3853
repository={repository.repository}
3954
status={repository.analysisStatus}
55+
downloadStatus={state?.downloadStatus}
4056
resultCount={repository.resultCount}
4157
interpretedResults={results?.interpretedResults}
4258
rawResults={results?.rawResults}

0 commit comments

Comments
 (0)