Skip to content

Commit 5b2114e

Browse files
committed
Fix Quick Query without a workspace
1 parent d19ea24 commit 5b2114e

4 files changed

Lines changed: 61 additions & 13 deletions

File tree

extensions/ql-vscode/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## [UNRELEASED]
44

5+
- Fix Quick Query failing to start when no workspace is open.
6+
57
## 1.17.8 - 17 July 2026
68

79
- Fix a bug where installing or updating the CodeQL CLI could hang indefinitely while extracting the downloaded archive. Extraction now reports an error if a file cannot be written, and aborts with a clear message if no progress is made within the download timeout (for example due to slow or networked storage, or security software). [#4455](https://github.com/github/vscode-codeql/pull/4455)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { ensureDir } from "fs-extra";
2+
import { join } from "path";
3+
import type { App } from "../common/app";
4+
5+
const QUICK_QUERIES_DIR_NAME = "quick-queries";
6+
7+
export async function getQuickQueriesDir(app: App): Promise<string> {
8+
const storagePath = app.workspaceStoragePath ?? app.globalStoragePath;
9+
const queriesPath = join(storagePath, QUICK_QUERIES_DIR_NAME);
10+
await ensureDir(queriesPath, { mode: 0o700 });
11+
return queriesPath;
12+
}

extensions/ql-vscode/src/local-queries/quick-query.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ensureDir, writeFile, pathExists, readFile } from "fs-extra";
1+
import { writeFile, pathExists, readFile } from "fs-extra";
22
import { dump, load } from "js-yaml";
33
import { basename, join } from "path";
44
import { window as Window, workspace, Uri } from "vscode";
@@ -11,11 +11,10 @@ import type { ProgressCallback } from "../common/vscode/progress";
1111
import { UserCancellationException } from "../common/vscode/progress";
1212
import { getErrorMessage } from "../common/helpers-pure";
1313
import { FALLBACK_QLPACK_FILENAME, getQlPackFilePath } from "../common/ql";
14-
import type { App } from "../common/app";
1514
import type { ExtensionApp } from "../common/vscode/extension-app";
1615
import type { QlPackFile } from "../packaging/qlpack-file";
16+
import { getQuickQueriesDir } from "./quick-query-dir";
1717

18-
const QUICK_QUERIES_DIR_NAME = "quick-queries";
1918
const QUICK_QUERY_QUERY_NAME = "quick-query.ql";
2019
const QUICK_QUERY_WORKSPACE_FOLDER_NAME = "Quick Queries";
2120
const QLPACK_FILE_HEADER = "# This is an automatically generated file.\n\n";
@@ -24,16 +23,6 @@ export function isQuickQueryPath(queryPath: string): boolean {
2423
return basename(queryPath) === QUICK_QUERY_QUERY_NAME;
2524
}
2625

27-
async function getQuickQueriesDir(app: App): Promise<string> {
28-
const storagePath = app.workspaceStoragePath;
29-
if (storagePath === undefined) {
30-
throw new Error("Workspace storage path is undefined");
31-
}
32-
const queriesPath = join(storagePath, QUICK_QUERIES_DIR_NAME);
33-
await ensureDir(queriesPath, { mode: 0o700 });
34-
return queriesPath;
35-
}
36-
3726
function updateQuickQueryDir(queriesDir: string, index: number, len: number) {
3827
workspace.updateWorkspaceFolders(index, len, {
3928
uri: Uri.file(queriesDir),
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { DirResult } from "tmp";
2+
import { dirSync } from "tmp";
3+
import { pathExists } from "fs-extra";
4+
import { join } from "path";
5+
import { createMockApp } from "../../__mocks__/appMock";
6+
import { getQuickQueriesDir } from "../../../src/local-queries/quick-query-dir";
7+
8+
describe("getQuickQueriesDir", () => {
9+
let dir: DirResult;
10+
11+
beforeEach(() => {
12+
dir = dirSync({
13+
unsafeCleanup: true,
14+
});
15+
});
16+
17+
afterEach(() => {
18+
dir.removeCallback();
19+
});
20+
21+
it("uses global storage when no workspace is open", async () => {
22+
const app = {
23+
...createMockApp({ globalStoragePath: dir.name }),
24+
workspaceStoragePath: undefined,
25+
};
26+
27+
const quickQueriesDir = await getQuickQueriesDir(app);
28+
29+
expect(quickQueriesDir).toBe(join(dir.name, "quick-queries"));
30+
expect(await pathExists(quickQueriesDir)).toBe(true);
31+
});
32+
33+
it("prefers workspace storage when a workspace is open", async () => {
34+
const workspaceStoragePath = join(dir.name, "workspace-storage");
35+
const app = createMockApp({
36+
workspaceStoragePath,
37+
globalStoragePath: dir.name,
38+
});
39+
40+
const quickQueriesDir = await getQuickQueriesDir(app);
41+
42+
expect(quickQueriesDir).toBe(join(workspaceStoragePath, "quick-queries"));
43+
expect(await pathExists(quickQueriesDir)).toBe(true);
44+
});
45+
});

0 commit comments

Comments
 (0)