Skip to content

Commit 3c229d2

Browse files
Merge pull request #2186 from github/robertbrignull/export_results_telemetry
Add telemetry for exporting variant analysis results
2 parents 9044d11 + fb70382 commit 3c229d2

File tree

8 files changed

+133
-131
lines changed

8 files changed

+133
-131
lines changed

extensions/ql-vscode/src/extension.ts

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,7 @@ import {
109109
handleInstallPackDependencies,
110110
} from "./packaging";
111111
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
112-
import {
113-
exportSelectedVariantAnalysisResults,
114-
exportVariantAnalysisResults,
115-
} from "./variant-analysis/export-results";
112+
import { exportSelectedVariantAnalysisResults } from "./variant-analysis/export-results";
116113
import { EvalLogViewer } from "./eval-log-viewer";
117114
import { SummaryLanguageSupport } from "./log-insights/summary-language-support";
118115
import { JoinOrderScannerProvider } from "./log-insights/join-order";
@@ -1149,35 +1146,10 @@ async function activateWithInstalledDistribution(
11491146

11501147
ctx.subscriptions.push(
11511148
commandRunner("codeQL.exportSelectedVariantAnalysisResults", async () => {
1152-
await exportSelectedVariantAnalysisResults(qhm);
1149+
await exportSelectedVariantAnalysisResults(variantAnalysisManager, qhm);
11531150
}),
11541151
);
11551152

1156-
ctx.subscriptions.push(
1157-
commandRunnerWithProgress(
1158-
"codeQL.exportVariantAnalysisResults",
1159-
async (
1160-
progress: ProgressCallback,
1161-
token: CancellationToken,
1162-
variantAnalysisId: number,
1163-
filterSort?: RepositoriesFilterSortStateWithIds,
1164-
) => {
1165-
await exportVariantAnalysisResults(
1166-
variantAnalysisManager,
1167-
variantAnalysisId,
1168-
filterSort,
1169-
app.credentials,
1170-
progress,
1171-
token,
1172-
);
1173-
},
1174-
{
1175-
title: "Exporting variant analysis results",
1176-
cancellable: true,
1177-
},
1178-
),
1179-
);
1180-
11811153
ctx.subscriptions.push(
11821154
commandRunner(
11831155
"codeQL.loadVariantAnalysisRepoResults",

extensions/ql-vscode/src/query-history/query-history-manager.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,8 +1122,7 @@ export class QueryHistoryManager extends DisposableObject {
11221122
return;
11231123
}
11241124

1125-
await commands.executeCommand(
1126-
"codeQL.exportVariantAnalysisResults",
1125+
await this.variantAnalysisManager.exportResults(
11271126
finalSingleItem.variantAnalysis.id,
11281127
);
11291128
}

extensions/ql-vscode/src/variant-analysis/export-results.ts

Lines changed: 106 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import {
99
window,
1010
workspace,
1111
} from "vscode";
12-
import { ProgressCallback, UserCancellationException } from "../commandRunner";
12+
import {
13+
ProgressCallback,
14+
UserCancellationException,
15+
withProgress,
16+
} from "../commandRunner";
1317
import { showInformationMessageWithAction } from "../helpers";
1418
import { extLogger } from "../common";
1519
import { QueryHistoryManager } from "../query-history/query-history-manager";
@@ -37,6 +41,7 @@ import { Credentials } from "../common/authentication";
3741
* Exports the results of the currently-selected variant analysis.
3842
*/
3943
export async function exportSelectedVariantAnalysisResults(
44+
variantAnalysisManager: VariantAnalysisManager,
4045
queryHistoryManager: QueryHistoryManager,
4146
): Promise<void> {
4247
const queryHistoryItem = queryHistoryManager.getCurrentQueryHistoryItem();
@@ -46,8 +51,7 @@ export async function exportSelectedVariantAnalysisResults(
4651
);
4752
}
4853

49-
return commands.executeCommand(
50-
"codeQL.exportVariantAnalysisResults",
54+
await variantAnalysisManager.exportResults(
5155
queryHistoryItem.variantAnalysis.id,
5256
);
5357
}
@@ -63,108 +67,117 @@ export async function exportVariantAnalysisResults(
6367
variantAnalysisId: number,
6468
filterSort: RepositoriesFilterSortStateWithIds | undefined,
6569
credentials: Credentials,
66-
progress: ProgressCallback,
67-
token: CancellationToken,
6870
): Promise<void> {
69-
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(
70-
variantAnalysisId,
71-
);
72-
if (!variantAnalysis) {
73-
void extLogger.log(
74-
`Could not find variant analysis with id ${variantAnalysisId}`,
75-
);
76-
throw new Error(
77-
"There was an error when trying to retrieve variant analysis information",
78-
);
79-
}
80-
81-
if (token.isCancellationRequested) {
82-
throw new UserCancellationException("Cancelled");
83-
}
84-
85-
const repoStates = await variantAnalysisManager.getRepoStates(
86-
variantAnalysisId,
87-
);
88-
89-
void extLogger.log(
90-
`Exporting variant analysis results for variant analysis with id ${variantAnalysis.id}`,
91-
);
71+
await withProgress(
72+
async (progress: ProgressCallback, token: CancellationToken) => {
73+
const variantAnalysis = await variantAnalysisManager.getVariantAnalysis(
74+
variantAnalysisId,
75+
);
76+
if (!variantAnalysis) {
77+
void extLogger.log(
78+
`Could not find variant analysis with id ${variantAnalysisId}`,
79+
);
80+
throw new Error(
81+
"There was an error when trying to retrieve variant analysis information",
82+
);
83+
}
9284

93-
progress({
94-
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
95-
step: 0,
96-
message: "Determining export format",
97-
});
85+
if (token.isCancellationRequested) {
86+
throw new UserCancellationException("Cancelled");
87+
}
9888

99-
const exportFormat = await determineExportFormat();
100-
if (!exportFormat) {
101-
return;
102-
}
89+
const repoStates = await variantAnalysisManager.getRepoStates(
90+
variantAnalysisId,
91+
);
10392

104-
if (token.isCancellationRequested) {
105-
throw new UserCancellationException("Cancelled");
106-
}
93+
void extLogger.log(
94+
`Exporting variant analysis results for variant analysis with id ${variantAnalysis.id}`,
95+
);
10796

108-
const repositories = filterAndSortRepositoriesWithResults(
109-
variantAnalysis.scannedRepos,
110-
filterSort,
111-
)?.filter(
112-
(repo) =>
113-
repo.resultCount &&
114-
repoStates.find((r) => r.repositoryId === repo.repository.id)
115-
?.downloadStatus ===
116-
VariantAnalysisScannedRepositoryDownloadStatus.Succeeded,
117-
);
97+
progress({
98+
maxStep: MAX_VARIANT_ANALYSIS_EXPORT_PROGRESS_STEPS,
99+
step: 0,
100+
message: "Determining export format",
101+
});
118102

119-
async function* getAnalysesResults(): AsyncGenerator<
120-
[VariantAnalysisScannedRepository, VariantAnalysisScannedRepositoryResult]
121-
> {
122-
if (!variantAnalysis) {
123-
return;
124-
}
103+
const exportFormat = await determineExportFormat();
104+
if (!exportFormat) {
105+
return;
106+
}
125107

126-
if (!repositories) {
127-
return;
128-
}
108+
if (token.isCancellationRequested) {
109+
throw new UserCancellationException("Cancelled");
110+
}
129111

130-
for (const repo of repositories) {
131-
const result = await variantAnalysisManager.loadResults(
132-
variantAnalysis.id,
133-
repo.repository.fullName,
134-
{
135-
skipCacheStore: true,
136-
},
112+
const repositories = filterAndSortRepositoriesWithResults(
113+
variantAnalysis.scannedRepos,
114+
filterSort,
115+
)?.filter(
116+
(repo) =>
117+
repo.resultCount &&
118+
repoStates.find((r) => r.repositoryId === repo.repository.id)
119+
?.downloadStatus ===
120+
VariantAnalysisScannedRepositoryDownloadStatus.Succeeded,
137121
);
138122

139-
yield [repo, result];
140-
}
141-
}
142-
143-
const exportDirectory =
144-
variantAnalysisManager.getVariantAnalysisStorageLocation(
145-
variantAnalysis.id,
146-
);
123+
async function* getAnalysesResults(): AsyncGenerator<
124+
[
125+
VariantAnalysisScannedRepository,
126+
VariantAnalysisScannedRepositoryResult,
127+
]
128+
> {
129+
if (!variantAnalysis) {
130+
return;
131+
}
132+
133+
if (!repositories) {
134+
return;
135+
}
136+
137+
for (const repo of repositories) {
138+
const result = await variantAnalysisManager.loadResults(
139+
variantAnalysis.id,
140+
repo.repository.fullName,
141+
{
142+
skipCacheStore: true,
143+
},
144+
);
145+
146+
yield [repo, result];
147+
}
148+
}
147149

148-
// The date will be formatted like the following: 20221115T123456Z. The time is in UTC.
149-
const formattedDate = new Date()
150-
.toISOString()
151-
.replace(/[-:]/g, "")
152-
.replace(/\.\d+Z$/, "Z");
153-
const exportedResultsDirectory = join(
154-
exportDirectory,
155-
"exported-results",
156-
`results_${formattedDate}`,
157-
);
150+
const exportDirectory =
151+
variantAnalysisManager.getVariantAnalysisStorageLocation(
152+
variantAnalysis.id,
153+
);
154+
155+
// The date will be formatted like the following: 20221115T123456Z. The time is in UTC.
156+
const formattedDate = new Date()
157+
.toISOString()
158+
.replace(/[-:]/g, "")
159+
.replace(/\.\d+Z$/, "Z");
160+
const exportedResultsDirectory = join(
161+
exportDirectory,
162+
"exported-results",
163+
`results_${formattedDate}`,
164+
);
158165

159-
await exportVariantAnalysisAnalysisResults(
160-
exportedResultsDirectory,
161-
variantAnalysis,
162-
getAnalysesResults(),
163-
repositories?.length ?? 0,
164-
exportFormat,
165-
credentials,
166-
progress,
167-
token,
166+
await exportVariantAnalysisAnalysisResults(
167+
exportedResultsDirectory,
168+
variantAnalysis,
169+
getAnalysesResults(),
170+
repositories?.length ?? 0,
171+
exportFormat,
172+
credentials,
173+
progress,
174+
token,
175+
);
176+
},
177+
{
178+
title: "Exporting variant analysis results",
179+
cancellable: true,
180+
},
168181
);
169182
}
170183

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import { DbManager } from "../databases/db-manager";
6767
import { App } from "../common/app";
6868
import { redactableError } from "../pure/errors";
6969
import { AppCommandManager, VariantAnalysisCommands } from "../common/commands";
70+
import { exportVariantAnalysisResults } from "./export-results";
7071

7172
export class VariantAnalysisManager
7273
extends DisposableObject
@@ -690,6 +691,18 @@ export class VariantAnalysisManager
690691
await env.clipboard.writeText(text.join(EOL));
691692
}
692693

694+
public async exportResults(
695+
variantAnalysisId: number,
696+
filterSort?: RepositoriesFilterSortStateWithIds,
697+
) {
698+
await exportVariantAnalysisResults(
699+
this,
700+
variantAnalysisId,
701+
filterSort,
702+
this.app.credentials,
703+
);
704+
}
705+
693706
private getRepoStatesStoragePath(variantAnalysisId: number): string {
694707
return join(
695708
this.getVariantAnalysisStorageLocation(variantAnalysisId),

extensions/ql-vscode/src/variant-analysis/variant-analysis-view-manager.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
VariantAnalysisScannedRepositoryState,
44
} from "./shared/variant-analysis";
55
import { AppCommandManager } from "../common/commands";
6+
import { RepositoriesFilterSortStateWithIds } from "../pure/variant-analysis-filter-sort";
67

78
export interface VariantAnalysisViewInterface {
89
variantAnalysisId: number;
@@ -27,4 +28,8 @@ export interface VariantAnalysisViewManager<
2728
openQueryFile(variantAnalysisId: number): Promise<void>;
2829
openQueryText(variantAnalysisId: number): Promise<void>;
2930
cancelVariantAnalysis(variantAnalysisId: number): Promise<void>;
31+
exportResults(
32+
variantAnalysisId: number,
33+
filterSort?: RepositoriesFilterSortStateWithIds,
34+
): Promise<void>;
3035
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ export class VariantAnalysisView
138138
);
139139
break;
140140
case "exportResults":
141-
void commands.executeCommand(
142-
"codeQL.exportVariantAnalysisResults",
141+
await this.manager.exportResults(
143142
this.variantAnalysisId,
144143
msg.filterSort,
145144
);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export function VariantAnalysis({
139139
repositoryIds: selectedRepositoryIds,
140140
},
141141
});
142+
sendTelemetry("variant-analysis-export-results");
142143
}, [filterSortState, selectedRepositoryIds]);
143144

144145
if (

extensions/ql-vscode/test/vscode-tests/no-workspace/query-history/query-history-manager.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ describe("QueryHistoryManager", () => {
8686
onVariantAnalysisRemoved: jest.fn(),
8787
removeVariantAnalysis: jest.fn(),
8888
cancelVariantAnalysis: jest.fn(),
89+
exportResults: jest.fn(),
8990
showView: jest.fn(),
9091
} as any as VariantAnalysisManager;
9192

@@ -862,16 +863,15 @@ describe("QueryHistoryManager", () => {
862863
const item = localQueryHistory[4];
863864
await queryHistoryManager.handleExportResults(item, [item]);
864865

865-
expect(executeCommandSpy).not.toBeCalled();
866+
expect(variantAnalysisManagerStub.exportResults).not.toBeCalled();
866867
});
867868

868869
it("should export results for a single variant analysis", async () => {
869870
queryHistoryManager = await createMockQueryHistory(allHistory);
870871

871872
const item = variantAnalysisHistory[1];
872873
await queryHistoryManager.handleExportResults(item, [item]);
873-
expect(executeCommandSpy).toBeCalledWith(
874-
"codeQL.exportVariantAnalysisResults",
874+
expect(variantAnalysisManagerStub.exportResults).toBeCalledWith(
875875
item.variantAnalysis.id,
876876
);
877877
});
@@ -882,7 +882,7 @@ describe("QueryHistoryManager", () => {
882882
const item1 = variantAnalysisHistory[1];
883883
const item2 = variantAnalysisHistory[3];
884884
await queryHistoryManager.handleExportResults(item1, [item1, item2]);
885-
expect(executeCommandSpy).not.toBeCalled();
885+
expect(variantAnalysisManagerStub.exportResults).not.toBeCalled();
886886
});
887887
});
888888

0 commit comments

Comments
 (0)