User should be able to generate a database from the current workspace
There is no easy way for a user to create a database locally if the only version of the cli installed is the default extension's version. The reason is that there is no easy way for a user to determine the file system path to the executable.
Instead, the extension should offer a mechanism to generate a database from the current workspace.
My idea is this:
- User executes the
CodeQL: Create database from workspacecommand - vscode opens an input box to request the language of the database
- the cli invokes the
database createcommand with the given language and placed in a well-known location (perhaps specified in configuration) - After creating the database, it is automatically imported into the workspace
Open questions:
- How do we handle database updating? Perhaps there is another command that the user needs to run and it is done manually? Perhaps it can be performed in the background on a schedule?
- How do we add the appropriate ql packs so that the user can run queries? Can we download them and import into the project?
See https://github.com/orgs/github/teams/codeql-core/discussions/1 for a longer discussion on this.
For compiled languages, presumably you would just run the autobuilder, or perhaps let the user specify the build command to run. If the user already has a VSCode "Task" set up to build their project, I wonder if we could have the user tell us which task they use to build, and figure out how to run that task under the tracer. If the task uses ShellExecution or ProcessExecution for its implementation, this might be pretty easy. If it uses a custom execution model via a JS callback, we probably can't do it.
Having to duplicate the build command, and keep the duplicate build command in sync with the real build command, has been a recurring problem for setting up CodeQL analysis in CI systems. If we can avoid having to do that, at least in the common case, for VS Code, that should make it easier for users to get started.
Good point about piggy-backing off of a vscode task. I wonder if defining our own kind of taskDefinition may be better here. See https://code.visualstudio.com/api/references/contribution-points#contributes.taskDefinitions
With https://github.com/github/codeql-cli-binaries/releases/tag/v2.6.0 now supporting .github/workflows/codeql-analysis.yml, shouldn't it be pretty use to use that just like .devcontainer/devcontainer.json? =)
https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#example-configuration-files
I don't know if this is the right approach, but I've been using this for a few days now for quickly building C/C++ databases from individual source files:
interface MakeTaskDefinition extends vscode.TaskDefinition {
}
async function getTask(): Promise<vscode.Task> {
const folders = vscode.workspace.workspaceFolders?.map(folder => folder.uri.path)
let pwd = null;
if (folders) {
pwd = await vscode.window.showQuickPick(folders)
}
if (pwd == null) {
pwd = '.'
}
channel.appendLine(pwd)
console.log(pwd)
const command = await vscode.window.showInputBox({
title: 'Build command',
placeHolder: 'Build command',
value: 'gcc -o test -c test.cpp',
});
console.log(command);
const dbPath = `${pwd}/test-db`
vscode.window.showInformationMessage(`Creating database at ${dbPath}`)
let task = new vscode.Task(
<MakeTaskDefinition>{type: "codeql"},
vscode.TaskScope.Workspace,
"codeql",
'codeql',
new vscode.ShellExecution(`codeql database create ${dbPath} --language=cpp --overwrite --command="${command}" --source-root="${pwd}"`)
);
task.group = vscode.TaskGroup.Build;
return task;
}
context.subscriptions.push(vscode.commands.registerCommand('gsgx.buildCodeQLDatabase', async () => {
if (vscode.window.activeTextEditor) {
if (vscode.languages.match(["c", "cpp"], vscode.window.activeTextEditor.document)) {
let fileName = vscode.window.activeTextEditor.document.fileName
console.log(fileName);
let task = await getTask();
await vscode.tasks.executeTask(task);
}
}
}));
Obviously needs some work to make it more generic, but maybe it'll be a good starting point for this issue?