Add a new "remote repository lists" setting
This commit is contained in:
@@ -233,6 +233,19 @@
|
|||||||
"default": false,
|
"default": false,
|
||||||
"scope": "application",
|
"scope": "application",
|
||||||
"description": "Specifies whether or not to write telemetry events to the extension log."
|
"description": "Specifies whether or not to write telemetry events to the extension log."
|
||||||
|
},
|
||||||
|
"codeQL.remoteRepositoryLists": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
".*": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": null,
|
||||||
|
"markdownDescription": "[For internal use only] Lists of GitHub repositories that you want to query remotely. This should be a JSON object where each key is a user-specified name for this repository list, and the value is an array of GitHub repositories (of the form `<owner>/<repo>`)."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -291,3 +291,17 @@ export function isCanary() {
|
|||||||
* Avoids caching in the AST viewer if the user is also a canary user.
|
* Avoids caching in the AST viewer if the user is also a canary user.
|
||||||
*/
|
*/
|
||||||
export const NO_CACHE_AST_VIEWER = new Setting('disableCache', AST_VIEWER_SETTING);
|
export const NO_CACHE_AST_VIEWER = new Setting('disableCache', AST_VIEWER_SETTING);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lists of GitHub repositories that you want to query remotely via the "Run Remote query" command.
|
||||||
|
* Note: This command is only available for internal users.
|
||||||
|
*
|
||||||
|
* This setting should be a JSON object where each key is a user-specified name (string),
|
||||||
|
* and the value is an array of GitHub repositories (of the form `<owner>/<repo>`).
|
||||||
|
*/
|
||||||
|
|
||||||
|
const REMOTE_REPO_LISTS = new Setting('remoteRepositoryLists', ROOT_SETTING);
|
||||||
|
|
||||||
|
export function getRemoteRepositoryLists(): Record<string, string[]> | undefined {
|
||||||
|
return REMOTE_REPO_LISTS.getValue<Record<string, string[]>>() || undefined;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Uri, window } from 'vscode';
|
import { QuickPickItem, Uri, window } from 'vscode';
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import { getOnDiskWorkspaceFolders, showAndLogErrorMessage, showAndLogInformationMessage } from './helpers';
|
import { getOnDiskWorkspaceFolders, showAndLogErrorMessage, showAndLogInformationMessage } from './helpers';
|
||||||
import { Credentials } from './authentication';
|
import { Credentials } from './authentication';
|
||||||
import * as cli from './cli';
|
import * as cli from './cli';
|
||||||
import { logger } from './logging';
|
import { logger } from './logging';
|
||||||
|
import { getRemoteRepositoryLists } from './config';
|
||||||
interface Config {
|
interface Config {
|
||||||
repositories: string[];
|
repositories: string[];
|
||||||
ref?: string;
|
ref?: string;
|
||||||
@@ -47,6 +47,41 @@ export async function findLanguage(
|
|||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface RepoListQuickPickItem extends QuickPickItem {
|
||||||
|
repoList: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the repositories to run the query against.
|
||||||
|
*/
|
||||||
|
async function getRepositories(): Promise<string[] | undefined> {
|
||||||
|
const repoLists = getRemoteRepositoryLists();
|
||||||
|
if (repoLists && Object.keys(repoLists).length) {
|
||||||
|
const quickPickItems = Object.entries(repoLists).map<RepoListQuickPickItem>(([key, value]) => (
|
||||||
|
{
|
||||||
|
label: key, // the name of the repository list
|
||||||
|
repoList: value, // the actual array of repositories
|
||||||
|
}
|
||||||
|
));
|
||||||
|
const quickpick = await window.showQuickPick<RepoListQuickPickItem>(
|
||||||
|
quickPickItems,
|
||||||
|
{
|
||||||
|
placeHolder: 'Select a repository list. You can define repository lists in the `codeQL.remoteRepositoryLists` setting.',
|
||||||
|
ignoreFocusOut: true,
|
||||||
|
});
|
||||||
|
if (quickpick && quickpick.repoList.length > 0) {
|
||||||
|
void logger.log(`Selected repositories: ${quickpick.repoList}`);
|
||||||
|
return quickpick.repoList;
|
||||||
|
} else {
|
||||||
|
void showAndLogErrorMessage('No repositories selected.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
void showAndLogErrorMessage('No repository lists defined. You can define repository lists in the `codeQL.remoteRepositoryLists` setting.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials: Credentials, uri?: Uri) {
|
export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials: Credentials, uri?: Uri) {
|
||||||
if (!uri?.fsPath.endsWith('.ql')) {
|
if (!uri?.fsPath.endsWith('.ql')) {
|
||||||
return;
|
return;
|
||||||
@@ -59,19 +94,31 @@ export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials
|
|||||||
const query = await fs.readFile(queryFile, 'utf8');
|
const query = await fs.readFile(queryFile, 'utf8');
|
||||||
|
|
||||||
const repositoriesFile = queryFile.substring(0, queryFile.length - '.ql'.length) + '.repositories';
|
const repositoriesFile = queryFile.substring(0, queryFile.length - '.ql'.length) + '.repositories';
|
||||||
if (!(await fs.pathExists(repositoriesFile))) {
|
let ref: string | undefined;
|
||||||
void showAndLogErrorMessage(`Missing file: '${repositoriesFile}' to specify the repositories to run against. This file must be a sibling of ${queryFile}.`);
|
let language: string | undefined;
|
||||||
return;
|
let repositories: string[] | undefined;
|
||||||
|
|
||||||
|
// If the user has an explicit `.repositories` file, use that.
|
||||||
|
// Otherwise, prompt user to select repositories from the `codeQL.remoteRepositoryLists` setting.
|
||||||
|
if (await fs.pathExists(repositoriesFile)) {
|
||||||
|
void logger.log(`Found '${repositoriesFile}'. Using information from that file to run ${queryFile}.`);
|
||||||
|
|
||||||
|
const config = yaml.safeLoad(await fs.readFile(repositoriesFile, 'utf8')) as Config;
|
||||||
|
|
||||||
|
ref = config.ref || 'main';
|
||||||
|
language = config.language || await findLanguage(cliServer, uri);
|
||||||
|
repositories = config.repositories;
|
||||||
|
} else {
|
||||||
|
ref = 'main';
|
||||||
|
[language, repositories] = await Promise.all([findLanguage(cliServer, uri), getRepositories()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = yaml.safeLoad(await fs.readFile(repositoriesFile, 'utf8')) as Config;
|
|
||||||
|
|
||||||
const ref = config.ref || 'main';
|
|
||||||
const language = config.language || await findLanguage(cliServer, uri);
|
|
||||||
const repositories = config.repositories;
|
|
||||||
|
|
||||||
if (!language) {
|
if (!language) {
|
||||||
return; // No error message needed, since `findlanguage` already displays one.
|
return; // No error message needed, since `findLanguage` already displays one.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!repositories || repositories.length === 0) {
|
||||||
|
return; // No error message needed, since `getRepositories` already displays one.
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user