Add ability to create repo list from MRVA results (#1403)
This commit is contained in:
@@ -573,6 +573,10 @@
|
||||
"command": "codeQLQueryHistory.openOnGithub",
|
||||
"title": "Open Variant Analysis on GitHub"
|
||||
},
|
||||
{
|
||||
"command": "codeQLQueryHistory.copyRepoList",
|
||||
"title": "Copy Repository List"
|
||||
},
|
||||
{
|
||||
"command": "codeQLQueryResults.nextPathStep",
|
||||
"title": "CodeQL: Show Next Step on Path"
|
||||
@@ -790,6 +794,11 @@
|
||||
"group": "9_qlCommands",
|
||||
"when": "viewItem == remoteResultsItem || viewItem == inProgressRemoteResultsItem || viewItem == cancelledResultsItem"
|
||||
},
|
||||
{
|
||||
"command": "codeQLQueryHistory.copyRepoList",
|
||||
"group": "9_qlCommands",
|
||||
"when": "viewItem == remoteResultsItem"
|
||||
},
|
||||
{
|
||||
"command": "codeQLTests.showOutputDifferences",
|
||||
"group": "qltest@1",
|
||||
@@ -978,6 +987,10 @@
|
||||
"command": "codeQLQueryHistory.openOnGithub",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "codeQLQueryHistory.copyRepoList",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "codeQLQueryHistory.showQueryText",
|
||||
"when": "false"
|
||||
|
||||
@@ -886,6 +886,12 @@ async function activateWithInstalledDistribution(
|
||||
await rqm.monitorRemoteQuery(queryId, query, token);
|
||||
}));
|
||||
|
||||
ctx.subscriptions.push(
|
||||
commandRunner('codeQL.copyRepoList', async (queryId: string) => {
|
||||
await rqm.copyRemoteQueryRepoListToClipboard(queryId);
|
||||
})
|
||||
);
|
||||
|
||||
ctx.subscriptions.push(
|
||||
commandRunner('codeQL.autoDownloadRemoteQueryResults', async (
|
||||
queryResult: RemoteQueryResult,
|
||||
|
||||
@@ -395,7 +395,8 @@ export type FromRemoteQueriesMessage =
|
||||
| OpenVirtualFileMsg
|
||||
| RemoteQueryDownloadAnalysisResultsMessage
|
||||
| RemoteQueryDownloadAllAnalysesResultsMessage
|
||||
| RemoteQueryExportResultsMessage;
|
||||
| RemoteQueryExportResultsMessage
|
||||
| CopyRepoListMessage;
|
||||
|
||||
export type ToRemoteQueriesMessage =
|
||||
| SetRemoteQueryResultMessage
|
||||
@@ -433,3 +434,8 @@ export interface RemoteQueryDownloadAllAnalysesResultsMessage {
|
||||
export interface RemoteQueryExportResultsMessage {
|
||||
t: 'remoteQueryExportResults';
|
||||
}
|
||||
|
||||
export interface CopyRepoListMessage {
|
||||
t: 'copyRepoList';
|
||||
queryId: string;
|
||||
}
|
||||
|
||||
@@ -491,6 +491,12 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
}
|
||||
)
|
||||
);
|
||||
this.push(
|
||||
commandRunner(
|
||||
'codeQLQueryHistory.copyRepoList',
|
||||
this.handleCopyRepoList.bind(this)
|
||||
)
|
||||
);
|
||||
|
||||
// There are two configuration items that affect the query history:
|
||||
// 1. The ttl for query history items.
|
||||
@@ -1050,6 +1056,20 @@ export class QueryHistoryManager extends DisposableObject {
|
||||
);
|
||||
}
|
||||
|
||||
async handleCopyRepoList(
|
||||
singleItem: QueryHistoryInfo,
|
||||
multiSelect: QueryHistoryInfo[],
|
||||
) {
|
||||
const { finalSingleItem, finalMultiSelect } = this.determineSelection(singleItem, multiSelect);
|
||||
|
||||
// Remote queries only
|
||||
if (!this.assertSingleQuery(finalMultiSelect) || !finalSingleItem || finalSingleItem.t !== 'remote') {
|
||||
return;
|
||||
}
|
||||
|
||||
await commands.executeCommand('codeQL.copyRepoList', finalSingleItem.queryId);
|
||||
}
|
||||
|
||||
async getQueryText(item: QueryHistoryInfo): Promise<string> {
|
||||
return item.t === 'local'
|
||||
? item.initialInfo.queryText
|
||||
|
||||
@@ -80,6 +80,7 @@ export class RemoteQueriesInterfaceManager {
|
||||
const affectedRepositories = queryResult.analysisSummaries.filter(r => r.resultCount > 0);
|
||||
|
||||
return {
|
||||
queryId: queryResult.queryId,
|
||||
queryTitle: query.queryName,
|
||||
queryFileName: queryFileName,
|
||||
queryFilePath: query.queryFilePath,
|
||||
@@ -206,6 +207,9 @@ export class RemoteQueriesInterfaceManager {
|
||||
case 'openVirtualFile':
|
||||
await this.openVirtualFile(msg.queryText);
|
||||
break;
|
||||
case 'copyRepoList':
|
||||
await commands.executeCommand('codeQL.copyRepoList', msg.queryId);
|
||||
break;
|
||||
case 'remoteQueryDownloadAnalysisResults':
|
||||
await this.downloadAnalysisResults(msg);
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { CancellationToken, commands, EventEmitter, ExtensionContext, Uri, window } from 'vscode';
|
||||
import { CancellationToken, commands, EventEmitter, ExtensionContext, Uri, env, window } from 'vscode';
|
||||
import { nanoid } from 'nanoid';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as os from 'os';
|
||||
|
||||
import { Credentials } from '../authentication';
|
||||
import { CodeQLCliServer } from '../cli';
|
||||
@@ -190,6 +191,22 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
results => this.interfaceManager.setAnalysisResults(results, queryResult.queryId));
|
||||
}
|
||||
|
||||
public async copyRemoteQueryRepoListToClipboard(queryId: string) {
|
||||
const queryResult = await this.getRemoteQueryResult(queryId);
|
||||
const repos = queryResult.analysisSummaries.map(a => a.nwo);
|
||||
|
||||
if (repos.length > 0) {
|
||||
const text = [
|
||||
'"new-repo-list": [',
|
||||
...repos.slice(0, -1).map(repo => ` "${repo}",`),
|
||||
` "${repos[repos.length - 1]}"`,
|
||||
']'
|
||||
];
|
||||
|
||||
await env.clipboard.writeText(text.join(os.EOL));
|
||||
}
|
||||
}
|
||||
|
||||
private mapQueryResult(
|
||||
executionEndTime: number,
|
||||
resultIndex: RemoteQueryResultIndex,
|
||||
@@ -259,6 +276,10 @@ export class RemoteQueriesManager extends DisposableObject {
|
||||
await createTimestampFile(path.join(this.storagePath, queryId));
|
||||
}
|
||||
|
||||
private async getRemoteQueryResult(queryId: string): Promise<RemoteQueryResult> {
|
||||
return await this.retrieveJsonFile<RemoteQueryResult>(queryId, 'query-result.json');
|
||||
}
|
||||
|
||||
private async storeJsonFile<T>(queryId: string, fileName: string, obj: T): Promise<void> {
|
||||
const filePath = path.join(this.storagePath, queryId, fileName);
|
||||
await fs.writeFile(filePath, JSON.stringify(obj, null, 2), 'utf8');
|
||||
|
||||
@@ -2,6 +2,7 @@ import { DownloadLink } from '../download-link';
|
||||
import { AnalysisFailure } from './analysis-failure';
|
||||
|
||||
export interface RemoteQueryResult {
|
||||
queryId: string,
|
||||
queryTitle: string,
|
||||
queryFileName: string,
|
||||
queryFilePath: string,
|
||||
|
||||
@@ -22,10 +22,12 @@ import RepositoriesSearch from './RepositoriesSearch';
|
||||
import StarCount from './StarCount';
|
||||
import SortRepoFilter, { Sort, sorter } from './SortRepoFilter';
|
||||
import LastUpdated from './LastUpdated';
|
||||
import RepoListCopyButton from './RepoListCopyButton';
|
||||
|
||||
const numOfReposInContractedMode = 10;
|
||||
|
||||
const emptyQueryResult: RemoteQueryResult = {
|
||||
queryId: '',
|
||||
queryTitle: '',
|
||||
queryFileName: '',
|
||||
queryFilePath: '',
|
||||
@@ -149,10 +151,14 @@ const SummaryTitleWithResults = ({
|
||||
text="Download all"
|
||||
onClick={() => downloadAllAnalysesResults(queryResult)} />
|
||||
}
|
||||
<SortRepoFilter
|
||||
sort={sort}
|
||||
setSort={setSort}
|
||||
/>
|
||||
<div style={{ flexGrow: 2, textAlign: 'right' }}>
|
||||
<RepoListCopyButton queryResult={queryResult} />
|
||||
<HorizontalSpace size={1} />
|
||||
<SortRepoFilter
|
||||
sort={sort}
|
||||
setSort={setSort}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as React from 'react';
|
||||
import { vscode } from '../../view/vscode-api';
|
||||
import { RemoteQueryResult } from '../shared/remote-query-result';
|
||||
import { CopyIcon } from '@primer/octicons-react';
|
||||
import { IconButton } from '@primer/react';
|
||||
|
||||
const copyRepositoryList = (queryResult: RemoteQueryResult) => {
|
||||
vscode.postMessage({
|
||||
t: 'copyRepoList',
|
||||
queryId: queryResult.queryId
|
||||
});
|
||||
};
|
||||
|
||||
const RepoListCopyButton = ({ queryResult }: { queryResult: RemoteQueryResult }) => (
|
||||
<IconButton
|
||||
aria-label="Copy repository list"
|
||||
icon={CopyIcon}
|
||||
variant="invisible"
|
||||
size="small"
|
||||
sx={{ 'text-align': 'right' }}
|
||||
onClick={() => copyRepositoryList(queryResult)} />
|
||||
);
|
||||
|
||||
export default RepoListCopyButton;
|
||||
Reference in New Issue
Block a user