Merge pull request #1766 from github/koesie10/export-results-sorting-filtering

Add filtering and sorting to exported results
This commit is contained in:
Koen Vlaswinkel
2022-11-16 19:01:36 +01:00
committed by GitHub
5 changed files with 40 additions and 21 deletions

View File

@@ -1015,8 +1015,8 @@ async function activateWithInstalledDistribution(
);
ctx.subscriptions.push(
commandRunner('codeQL.exportVariantAnalysisResults', async (variantAnalysisId: number) => {
await exportVariantAnalysisResults(ctx, variantAnalysisManager, variantAnalysisId);
commandRunner('codeQL.exportVariantAnalysisResults', async (variantAnalysisId: number, filterSort?: RepositoriesFilterSortStateWithIds) => {
await exportVariantAnalysisResults(ctx, variantAnalysisManager, variantAnalysisId, filterSort);
})
);

View File

@@ -480,6 +480,7 @@ export interface CopyRepositoryListMessage {
export interface ExportResultsMessage {
t: 'exportResults';
filterSort?: RepositoriesFilterSortStateWithIds;
}
export interface OpenLogsMessage {

View File

@@ -24,6 +24,10 @@ import {
VariantAnalysisScannedRepository,
VariantAnalysisScannedRepositoryResult
} from './shared/variant-analysis';
import {
filterAndSortRepositoriesWithResults,
RepositoriesFilterSortStateWithIds,
} from '../pure/variant-analysis-filter-sort';
/**
* Exports the results of the currently-selected remote query or variant analysis.
@@ -73,13 +77,14 @@ export async function exportRemoteQueryResults(
}
const exportDirectory = await queryHistoryManager.getQueryHistoryItemDirectory(queryHistoryItem);
const exportedResultsDirectory = path.join(exportDirectory, 'exported-results');
await exportRemoteQueryAnalysisResults(ctx, exportDirectory, query, analysesResults, exportFormat);
await exportRemoteQueryAnalysisResults(ctx, exportedResultsDirectory, query, analysesResults, exportFormat);
}
export async function exportRemoteQueryAnalysisResults(
ctx: ExtensionContext,
exportDirectory: string,
exportedResultsPath: string,
query: RemoteQuery,
analysesResults: AnalysisResults[],
exportFormat: 'gist' | 'local',
@@ -87,7 +92,7 @@ export async function exportRemoteQueryAnalysisResults(
const description = buildGistDescription(query, analysesResults);
const markdownFiles = generateMarkdown(query, analysesResults, exportFormat);
await exportResults(ctx, exportDirectory, description, markdownFiles, exportFormat);
await exportResults(ctx, exportedResultsPath, description, markdownFiles, exportFormat);
}
/**
@@ -98,6 +103,7 @@ export async function exportVariantAnalysisResults(
ctx: ExtensionContext,
variantAnalysisManager: VariantAnalysisManager,
variantAnalysisId: number,
filterSort?: RepositoriesFilterSortStateWithIds,
): Promise<void> {
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(variantAnalysisId);
if (!variantAnalysis) {
@@ -113,11 +119,16 @@ export async function exportVariantAnalysisResults(
}
async function* getAnalysesResults(): AsyncGenerator<[VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult]> {
if (!variantAnalysis?.scannedRepos) {
if (!variantAnalysis) {
return;
}
for (const repo of variantAnalysis.scannedRepos) {
const repositories = filterAndSortRepositoriesWithResults(variantAnalysis.scannedRepos, filterSort);
if (!repositories) {
return;
}
for (const repo of repositories) {
if (repo.resultCount == 0) {
yield [repo, {
variantAnalysisId: variantAnalysis.id,
@@ -136,12 +147,16 @@ export async function exportVariantAnalysisResults(
const exportDirectory = variantAnalysisManager.getVariantAnalysisStorageLocation(variantAnalysis.id);
await exportVariantAnalysisAnalysisResults(ctx, exportDirectory, variantAnalysis, getAnalysesResults(), exportFormat);
// The date will be formatted like the following: 20221115T123456Z. The time is in UTC.
const formattedDate = (new Date()).toISOString().replace(/[-:]/g, '').replace(/\.\d+Z$/, 'Z');
const exportedResultsDirectory = path.join(exportDirectory, 'exported-results', `results_${formattedDate}`);
await exportVariantAnalysisAnalysisResults(ctx, exportedResultsDirectory, variantAnalysis, getAnalysesResults(), exportFormat);
}
export async function exportVariantAnalysisAnalysisResults(
ctx: ExtensionContext,
exportDirectory: string,
exportedResultsPath: string,
variantAnalysis: VariantAnalysis,
analysesResults: AsyncIterable<[VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult]>,
exportFormat: 'gist' | 'local',
@@ -149,7 +164,7 @@ export async function exportVariantAnalysisAnalysisResults(
const description = buildVariantAnalysisGistDescription(variantAnalysis);
const markdownFiles = await generateVariantAnalysisMarkdown(variantAnalysis, analysesResults, 'gist');
await exportResults(ctx, exportDirectory, description, markdownFiles, exportFormat);
await exportResults(ctx, exportedResultsPath, description, markdownFiles, exportFormat);
}
/**
@@ -190,7 +205,7 @@ async function determineExportFormat(): Promise<'gist' | 'local' | undefined> {
export async function exportResults(
ctx: ExtensionContext,
exportDirectory: string,
exportedResultsPath: string,
description: string,
markdownFiles: MarkdownFile[],
exportFormat: 'gist' | 'local',
@@ -198,7 +213,7 @@ export async function exportResults(
if (exportFormat === 'gist') {
await exportToGist(ctx, description, markdownFiles);
} else if (exportFormat === 'local') {
await exportToLocalMarkdown(exportDirectory, markdownFiles);
await exportToLocalMarkdown(exportedResultsPath, markdownFiles);
}
}
@@ -254,10 +269,9 @@ const buildVariantAnalysisGistDescription = (variantAnalysis: VariantAnalysis) =
* Saves the results of an exported query to local markdown files.
*/
async function exportToLocalMarkdown(
exportDirectory: string,
exportedResultsPath: string,
markdownFiles: MarkdownFile[],
) {
const exportedResultsPath = path.join(exportDirectory, 'exported-results');
await fs.ensureDir(exportedResultsPath);
for (const markdownFile of markdownFiles) {
const filePath = path.join(exportedResultsPath, `${markdownFile.fileName}.md`);

View File

@@ -107,7 +107,7 @@ export class VariantAnalysisView extends AbstractWebview<ToVariantAnalysisMessag
void commands.executeCommand('codeQL.copyVariantAnalysisRepoList', this.variantAnalysisId, msg.filterSort);
break;
case 'exportResults':
void commands.executeCommand('codeQL.exportVariantAnalysisResults', this.variantAnalysisId);
void commands.executeCommand('codeQL.exportVariantAnalysisResults', this.variantAnalysisId, msg.filterSort);
break;
case 'openLogs':
await this.openLogs();

View File

@@ -37,12 +37,6 @@ const stopQuery = () => {
});
};
const exportResults = () => {
vscode.postMessage({
t: 'exportResults',
});
};
const openLogs = () => {
vscode.postMessage({
t: 'openLogs',
@@ -104,6 +98,16 @@ export function VariantAnalysis({
});
}, [filterSortState, selectedRepositoryIds]);
const exportResults = useCallback(() => {
vscode.postMessage({
t: 'exportResults',
filterSort: {
...filterSortState,
repositoryIds: selectedRepositoryIds,
},
});
}, [filterSortState, selectedRepositoryIds]);
if (variantAnalysis?.actionsWorkflowRunId === undefined) {
return <VariantAnalysisLoading />;
}