Merge pull request #2186 from github/robertbrignull/export_results_telemetry

Add telemetry for exporting variant analysis results
This commit is contained in:
Robert 2023-03-20 16:47:49 +00:00 коммит произвёл GitHub
Родитель 9044d11d2b fb70382929
Коммит 3c229d244e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 137 добавлений и 135 удалений

Просмотреть файл

@ -109,10 +109,7 @@ import {
handleInstallPackDependencies,
} from "./packaging";
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
import {
exportSelectedVariantAnalysisResults,
exportVariantAnalysisResults,
} from "./variant-analysis/export-results";
import { exportSelectedVariantAnalysisResults } from "./variant-analysis/export-results";
import { EvalLogViewer } from "./eval-log-viewer";
import { SummaryLanguageSupport } from "./log-insights/summary-language-support";
import { JoinOrderScannerProvider } from "./log-insights/join-order";
@ -1149,35 +1146,10 @@ async function activateWithInstalledDistribution(
ctx.subscriptions.push(
commandRunner("codeQL.exportSelectedVariantAnalysisResults", async () => {
await exportSelectedVariantAnalysisResults(qhm);
await exportSelectedVariantAnalysisResults(variantAnalysisManager, qhm);
}),
);
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.exportVariantAnalysisResults",
async (
progress: ProgressCallback,
token: CancellationToken,
variantAnalysisId: number,
filterSort?: RepositoriesFilterSortStateWithIds,
) => {
await exportVariantAnalysisResults(
variantAnalysisManager,
variantAnalysisId,
filterSort,
app.credentials,
progress,
token,
);
},
{
title: "Exporting variant analysis results",
cancellable: true,
},
),
);
ctx.subscriptions.push(
commandRunner(
"codeQL.loadVariantAnalysisRepoResults",

Просмотреть файл

@ -1122,8 +1122,7 @@ export class QueryHistoryManager extends DisposableObject {
return;
}
await commands.executeCommand(
"codeQL.exportVariantAnalysisResults",
await this.variantAnalysisManager.exportResults(
finalSingleItem.variantAnalysis.id,
);
}

Просмотреть файл

@ -9,7 +9,11 @@ import {
window,
workspace,
} from "vscode";
import { ProgressCallback, UserCancellationException } from "../commandRunner";
import {
ProgressCallback,
UserCancellationException,
withProgress,
} from "../commandRunner";
import { showInformationMessageWithAction } from "../helpers";
import { extLogger } from "../common";
import { QueryHistoryManager } from "../query-history/query-history-manager";
@ -37,6 +41,7 @@ import { Credentials } from "../common/authentication";
* Exports the results of the currently-selected variant analysis.
*/
export async function exportSelectedVariantAnalysisResults(
variantAnalysisManager: VariantAnalysisManager,
queryHistoryManager: QueryHistoryManager,
): Promise<void> {
const queryHistoryItem = queryHistoryManager.getCurrentQueryHistoryItem();
@ -46,8 +51,7 @@ export async function exportSelectedVariantAnalysisResults(
);
}
return commands.executeCommand(
"codeQL.exportVariantAnalysisResults",
await variantAnalysisManager.exportResults(
queryHistoryItem.variantAnalysis.id,
);
}
@ -63,108 +67,117 @@ export async function exportVariantAnalysisResults(
variantAnalysisId: number,
filterSort: RepositoriesFilterSortStateWithIds | undefined,
credentials: Credentials,
progress: ProgressCallback,
token: CancellationToken,
): Promise<void> {
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(
variantAnalysisId,
);
if (!variantAnalysis) {
void extLogger.log(
`Could not find variant analysis with id ${variantAnalysisId}`,
);
throw new Error(
"There was an error when trying to retrieve variant analysis information",
);
}
await withProgress(
async (progress: ProgressCallback, token: CancellationToken) => {
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(
variantAnalysisId,
);
if (!variantAnalysis) {
void extLogger.log(
`Could not find variant analysis with id ${variantAnalysisId}`,
);
throw new Error(
"There was an error when trying to retrieve variant analysis information",
);
}
if (token.isCancellationRequested) {
throw new UserCancellationException("Cancelled");
}
if (token.isCancellationRequested) {
throw new UserCancellationException("Cancelled");
}
const repoStates = await variantAnalysisManager.getRepoStates(
variantAnalysisId,
);
void extLogger.log(
`Exporting variant analysis results for variant analysis with id ${variantAnalysis.id}`,
);
progress({
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
step: 0,
message: "Determining export format",
});
const exportFormat = await determineExportFormat();
if (!exportFormat) {
return;
}
if (token.isCancellationRequested) {
throw new UserCancellationException("Cancelled");
}
const repositories = filterAndSortRepositoriesWithResults(
variantAnalysis.scannedRepos,
filterSort,
)?.filter(
(repo) =>
repo.resultCount &&
repoStates.find((r) => r.repositoryId === repo.repository.id)
?.downloadStatus ===
VariantAnalysisScannedRepositoryDownloadStatus.Succeeded,
);
async function* getAnalysesResults(): AsyncGenerator<
[VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult]
> {
if (!variantAnalysis) {
return;
}
if (!repositories) {
return;
}
for (const repo of repositories) {
const result = await variantAnalysisManager.loadResults(
variantAnalysis.id,
repo.repository.fullName,
{
skipCacheStore: true,
},
const repoStates = await variantAnalysisManager.getRepoStates(
variantAnalysisId,
);
yield [repo, result];
}
}
void extLogger.log(
`Exporting variant analysis results for variant analysis with id ${variantAnalysis.id}`,
);
const exportDirectory =
variantAnalysisManager.getVariantAnalysisStorageLocation(
variantAnalysis.id,
);
progress({
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
step: 0,
message: "Determining export format",
});
// 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 = join(
exportDirectory,
"exported-results",
`results_${formattedDate}`,
);
const exportFormat = await determineExportFormat();
if (!exportFormat) {
return;
}
await exportVariantAnalysisAnalysisResults(
exportedResultsDirectory,
variantAnalysis,
getAnalysesResults(),
repositories?.length ?? 0,
exportFormat,
credentials,
progress,
token,
if (token.isCancellationRequested) {
throw new UserCancellationException("Cancelled");
}
const repositories = filterAndSortRepositoriesWithResults(
variantAnalysis.scannedRepos,
filterSort,
)?.filter(
(repo) =>
repo.resultCount &&
repoStates.find((r) => r.repositoryId === repo.repository.id)
?.downloadStatus ===
VariantAnalysisScannedRepositoryDownloadStatus.Succeeded,
);
async function* getAnalysesResults(): AsyncGenerator<
[
VariantAnalysisScannedRepository,
VariantAnalysisScannedRepositoryResult,
]
> {
if (!variantAnalysis) {
return;
}
if (!repositories) {
return;
}
for (const repo of repositories) {
const result = await variantAnalysisManager.loadResults(
variantAnalysis.id,
repo.repository.fullName,
{
skipCacheStore: true,
},
);
yield [repo, result];
}
}
const exportDirectory =
variantAnalysisManager.getVariantAnalysisStorageLocation(
variantAnalysis.id,
);
// 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 = join(
exportDirectory,
"exported-results",
`results_${formattedDate}`,
);
await exportVariantAnalysisAnalysisResults(
exportedResultsDirectory,
variantAnalysis,
getAnalysesResults(),
repositories?.length ?? 0,
exportFormat,
credentials,
progress,
token,
);
},
{
title: "Exporting variant analysis results",
cancellable: true,
},
);
}

Просмотреть файл

@ -67,6 +67,7 @@ import { DbManager } from "../databases/db-manager";
import { App } from "../common/app";
import { redactableError } from "../pure/errors";
import { AppCommandManager, VariantAnalysisCommands } from "../common/commands";
import { exportVariantAnalysisResults } from "./export-results";
export class VariantAnalysisManager
extends DisposableObject
@ -690,6 +691,18 @@ export class VariantAnalysisManager
await env.clipboard.writeText(text.join(EOL));
}
public async exportResults(
variantAnalysisId: number,
filterSort?: RepositoriesFilterSortStateWithIds,
) {
await exportVariantAnalysisResults(
this,
variantAnalysisId,
filterSort,
this.app.credentials,
);
}
private getRepoStatesStoragePath(variantAnalysisId: number): string {
return join(
this.getVariantAnalysisStorageLocation(variantAnalysisId),

Просмотреть файл

@ -3,6 +3,7 @@ import {
VariantAnalysisScannedRepositoryState,
} from "./shared/variant-analysis";
import { AppCommandManager } from "../common/commands";
import { RepositoriesFilterSortStateWithIds } from "../pure/variant-analysis-filter-sort";
export interface VariantAnalysisViewInterface {
variantAnalysisId: number;
@ -27,4 +28,8 @@ export interface VariantAnalysisViewManager<
openQueryFile(variantAnalysisId: number): Promise<void>;
openQueryText(variantAnalysisId: number): Promise<void>;
cancelVariantAnalysis(variantAnalysisId: number): Promise<void>;
exportResults(
variantAnalysisId: number,
filterSort?: RepositoriesFilterSortStateWithIds,
): Promise<void>;
}

Просмотреть файл

@ -138,8 +138,7 @@ export class VariantAnalysisView
);
break;
case "exportResults":
void commands.executeCommand(
"codeQL.exportVariantAnalysisResults",
await this.manager.exportResults(
this.variantAnalysisId,
msg.filterSort,
);

Просмотреть файл

@ -139,6 +139,7 @@ export function VariantAnalysis({
repositoryIds: selectedRepositoryIds,
},
});
sendTelemetry("variant-analysis-export-results");
}, [filterSortState, selectedRepositoryIds]);
if (

Просмотреть файл

@ -86,6 +86,7 @@ describe("QueryHistoryManager", () => {
onVariantAnalysisRemoved: jest.fn(),
removeVariantAnalysis: jest.fn(),
cancelVariantAnalysis: jest.fn(),
exportResults: jest.fn(),
showView: jest.fn(),
} as any as VariantAnalysisManager;
@ -862,7 +863,7 @@ describe("QueryHistoryManager", () => {
const item = localQueryHistory[4];
await queryHistoryManager.handleExportResults(item, [item]);
expect(executeCommandSpy).not.toBeCalled();
expect(variantAnalysisManagerStub.exportResults).not.toBeCalled();
});
it("should export results for a single variant analysis", async () => {
@ -870,8 +871,7 @@ describe("QueryHistoryManager", () => {
const item = variantAnalysisHistory[1];
await queryHistoryManager.handleExportResults(item, [item]);
expect(executeCommandSpy).toBeCalledWith(
"codeQL.exportVariantAnalysisResults",
expect(variantAnalysisManagerStub.exportResults).toBeCalledWith(
item.variantAnalysis.id,
);
});
@ -882,7 +882,7 @@ describe("QueryHistoryManager", () => {
const item1 = variantAnalysisHistory[1];
const item2 = variantAnalysisHistory[3];
await queryHistoryManager.handleExportResults(item1, [item1, item2]);
expect(executeCommandSpy).not.toBeCalled();
expect(variantAnalysisManagerStub.exportResults).not.toBeCalled();
});
});