Skip to content

Commit 77eb83e

Browse files
committed
Use better heuristics when chekcking db folders
1 parent 78a90ff commit 77eb83e

File tree

3 files changed

+69
-11
lines changed

3 files changed

+69
-11
lines changed

extensions/ql-vscode/src/databases-ui.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ export class DatabaseUI extends DisposableObject {
750750
* Perform some heuristics to ensure a proper database location is chosen.
751751
*
752752
* 1. If the selected URI to add is a file, choose the containing directory
753-
* 2. If the selected URI is a directory matching db-*, choose the containing directory
753+
* 2. If the selected URI appears to be a db language folder, choose the containing directory
754754
* 3. choose the current directory
755755
*
756756
* @param uri a URI that is a database folder or inside it
@@ -763,7 +763,7 @@ export class DatabaseUI extends DisposableObject {
763763
dbPath = path.dirname(dbPath);
764764
}
765765

766-
if (isLikelyDbLanguageFolder(dbPath)) {
766+
if (await isLikelyDbLanguageFolder(dbPath)) {
767767
dbPath = path.dirname(dbPath);
768768
}
769769
return Uri.file(dbPath);

extensions/ql-vscode/src/helpers.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,9 @@ export function getInitialQueryContents(language: string, dbscheme: string) {
470470

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

487-
return !!((a || b) && c);
487+
return ((a || b) && c.length > 0);
488488
}
489489

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

494497
/**

extensions/ql-vscode/src/vscode-tests/no-workspace/helpers.test.ts

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { DirResult } from 'tmp';
2121
import {
2222
getInitialQueryContents,
2323
InvocationRateLimiter,
24+
isLikelyDatabaseRoot,
2425
isLikelyDbLanguageFolder,
2526
showBinaryChoiceDialog,
2627
showBinaryChoiceWithUrlDialog,
@@ -150,11 +151,65 @@ describe('helpers', () => {
150151
it('should get initial query contents when nothing is known', () => {
151152
expect(getInitialQueryContents('', 'hucairz')).to.eq('select ""');
152153
});
154+
153155
});
154156

155-
it('should find likely db language folders', () => {
156-
expect(isLikelyDbLanguageFolder('db-javascript')).to.be.true;
157-
expect(isLikelyDbLanguageFolder('dbnot-a-db')).to.be.false;
157+
describe('likely tests', () => {
158+
let dir: tmp.DirResult;
159+
beforeEach(() => {
160+
dir = tmp.dirSync();
161+
});
162+
163+
afterEach(() => {
164+
dir.removeCallback();
165+
});
166+
167+
it('should likely be a database root: codeql-database.yml', async () => {
168+
const dbFolder = path.join(dir.name, 'db');
169+
fs.mkdirSync(dbFolder);
170+
fs.mkdirSync(path.join(dbFolder, 'db-python'));
171+
fs.writeFileSync(path.join(dbFolder, 'codeql-database.yml'), '', 'utf8');
172+
173+
expect(await isLikelyDatabaseRoot(dbFolder)).to.be.true;
174+
});
175+
176+
it('should likely be a database root: .dbinfo', async () => {
177+
const dbFolder = path.join(dir.name, 'db');
178+
fs.mkdirSync(dbFolder);
179+
fs.mkdirSync(path.join(dbFolder, 'db-python'));
180+
fs.writeFileSync(path.join(dbFolder, '.dbinfo'), '', 'utf8');
181+
182+
expect(await isLikelyDatabaseRoot(dbFolder)).to.be.true;
183+
});
184+
185+
it('should likely NOT be a database root: empty dir', async () => {
186+
const dbFolder = path.join(dir.name, 'db');
187+
fs.mkdirSync(dbFolder);
188+
fs.mkdirSync(path.join(dbFolder, 'db-python'));
189+
190+
expect(await isLikelyDatabaseRoot(dbFolder)).to.be.false;
191+
});
192+
193+
it('should likely NOT be a database root: no db language folder', async () => {
194+
const dbFolder = path.join(dir.name, 'db');
195+
fs.mkdirSync(dbFolder);
196+
fs.writeFileSync(path.join(dbFolder, '.dbinfo'), '', 'utf8');
197+
198+
expect(await isLikelyDatabaseRoot(dbFolder)).to.be.false;
199+
});
200+
201+
it('should find likely db language folder', async () => {
202+
const dbFolder = path.join(dir.name, 'db-python');
203+
fs.mkdirSync(dbFolder);
204+
fs.mkdirSync(path.join(dbFolder, 'db-python'));
205+
fs.writeFileSync(path.join(dbFolder, 'codeql-database.yml'), '', 'utf8');
206+
207+
// not a db folder since there is a db-python folder inside this one
208+
expect(await isLikelyDbLanguageFolder(dbFolder)).to.be.false;
209+
210+
const nestedDbPythonFolder = path.join(dbFolder, 'db-python');
211+
expect(await isLikelyDbLanguageFolder(nestedDbPythonFolder)).to.be.true;
212+
});
158213
});
159214

160215
class MockExtensionContext implements ExtensionContext {

0 commit comments

Comments
 (0)