Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use better heuristics when checking db folders #1565

Merged
merged 2 commits into from
Oct 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions extensions/ql-vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [UNRELEASED]

- Fix a bug where it was not possible to add a database folder if the folder name starts with `db-`. [#1565](https://github.com/github/vscode-codeql/pull/1565)

## 1.7.0 - 20 September 2022

- Remove ability to download databases from LGTM. [#1467](https://github.com/github/vscode-codeql/pull/1467)
Expand Down
4 changes: 2 additions & 2 deletions extensions/ql-vscode/src/databases-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ export class DatabaseUI extends DisposableObject {
* Perform some heuristics to ensure a proper database location is chosen.
*
* 1. If the selected URI to add is a file, choose the containing directory
* 2. If the selected URI is a directory matching db-*, choose the containing directory
* 2. If the selected URI appears to be a db language folder, choose the containing directory
* 3. choose the current directory
*
* @param uri a URI that is a database folder or inside it
Expand All @@ -763,7 +763,7 @@ export class DatabaseUI extends DisposableObject {
dbPath = path.dirname(dbPath);
}

if (isLikelyDbLanguageFolder(dbPath)) {
if (await isLikelyDbLanguageFolder(dbPath)) {
dbPath = path.dirname(dbPath);
}
return Uri.file(dbPath);
Expand Down
15 changes: 9 additions & 6 deletions extensions/ql-vscode/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ export function getInitialQueryContents(language: string, dbscheme: string) {

/**
* Heuristically determines if the directory passed in corresponds
* to a database root.
*
* @param maybeRoot
* to a database root. A database root is a directory that contains
* a codeql-database.yml or (historically) a .dbinfo file. It also
* contains a folder starting with `db-`.
*/
export async function isLikelyDatabaseRoot(maybeRoot: string) {
const [a, b, c] = (await Promise.all([
Expand All @@ -484,11 +484,14 @@ export async function isLikelyDatabaseRoot(maybeRoot: string) {
glob('db-*/', { cwd: maybeRoot })
]));

return !!((a || b) && c);
return ((a || b) && c.length > 0);
}

export function isLikelyDbLanguageFolder(dbPath: string) {
return !!path.basename(dbPath).startsWith('db-');
/**
* A language folder is any folder starting with `db-` that is itself not a database root.
*/
export async function isLikelyDbLanguageFolder(dbPath: string) {
return path.basename(dbPath).startsWith('db-') && !(await isLikelyDatabaseRoot(dbPath));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { DirResult } from 'tmp';
import {
getInitialQueryContents,
InvocationRateLimiter,
isLikelyDatabaseRoot,
isLikelyDbLanguageFolder,
showBinaryChoiceDialog,
showBinaryChoiceWithUrlDialog,
Expand Down Expand Up @@ -150,11 +151,65 @@ describe('helpers', () => {
it('should get initial query contents when nothing is known', () => {
expect(getInitialQueryContents('', 'hucairz')).to.eq('select ""');
});

});

it('should find likely db language folders', () => {
expect(isLikelyDbLanguageFolder('db-javascript')).to.be.true;
expect(isLikelyDbLanguageFolder('dbnot-a-db')).to.be.false;
describe('likely database tests', () => {
let dir: tmp.DirResult;
beforeEach(() => {
dir = tmp.dirSync();
});

afterEach(() => {
dir.removeCallback();
});

it('should likely be a database root: codeql-database.yml', async () => {
const dbFolder = path.join(dir.name, 'db');
fs.mkdirSync(dbFolder);
fs.mkdirSync(path.join(dbFolder, 'db-python'));
fs.writeFileSync(path.join(dbFolder, 'codeql-database.yml'), '', 'utf8');

expect(await isLikelyDatabaseRoot(dbFolder)).to.be.true;
});

it('should likely be a database root: .dbinfo', async () => {
const dbFolder = path.join(dir.name, 'db');
fs.mkdirSync(dbFolder);
fs.mkdirSync(path.join(dbFolder, 'db-python'));
fs.writeFileSync(path.join(dbFolder, '.dbinfo'), '', 'utf8');

expect(await isLikelyDatabaseRoot(dbFolder)).to.be.true;
});

it('should likely NOT be a database root: empty dir', async () => {
const dbFolder = path.join(dir.name, 'db');
fs.mkdirSync(dbFolder);
fs.mkdirSync(path.join(dbFolder, 'db-python'));

expect(await isLikelyDatabaseRoot(dbFolder)).to.be.false;
});

it('should likely NOT be a database root: no db language folder', async () => {
const dbFolder = path.join(dir.name, 'db');
fs.mkdirSync(dbFolder);
fs.writeFileSync(path.join(dbFolder, '.dbinfo'), '', 'utf8');

expect(await isLikelyDatabaseRoot(dbFolder)).to.be.false;
});

it('should find likely db language folder', async () => {
const dbFolder = path.join(dir.name, 'db-python');
fs.mkdirSync(dbFolder);
fs.mkdirSync(path.join(dbFolder, 'db-python'));
fs.writeFileSync(path.join(dbFolder, 'codeql-database.yml'), '', 'utf8');

// not a db folder since there is a db-python folder inside this one
expect(await isLikelyDbLanguageFolder(dbFolder)).to.be.false;

const nestedDbPythonFolder = path.join(dbFolder, 'db-python');
expect(await isLikelyDbLanguageFolder(nestedDbPythonFolder)).to.be.true;
});
});

class MockExtensionContext implements ExtensionContext {
Expand Down