Skip to content

Commit e8cc1a1

Browse files
authored
Merge branch 'main' into restart_lsp_for_config_changes
2 parents fe4df34 + bf7c770 commit e8cc1a1

File tree

9 files changed

+466
-186
lines changed

9 files changed

+466
-186
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
- New `swift.outputChannelLogLevel` setting to control the verbosity of the `Swift` output channel ([#1746](https://github.com/swiftlang/vscode-swift/pull/1746))
99
- New `swift.debugTestsMultipleTimes` and `swift.debugTestsUntilFailure` commands for debugging tests over multiple runs ([#1763](https://github.com/swiftlang/vscode-swift/pull/1763))
1010
- Optionally include LLDB DAP logs in the Swift diagnostics bundle ([#1768](https://github.com/swiftlang/vscode-swift/pull/1758))
11-
- Show prompt to restart `SourceKit-LSP` after changing `.sourcekit-lsp/config.json` files ([#1744](https://github.com/swiftlang/vscode-swift/issues/1744))
11+
- Prompt to restart `SourceKit-LSP` after changing `.sourcekit-lsp/config.json` files ([#1744](https://github.com/swiftlang/vscode-swift/issues/1744))
12+
- Prompt to cancel and replace the active test run if one is in flight ([#1774](https://github.com/swiftlang/vscode-swift/pull/1774))
1213

1314
### Changed
1415
- Added log levels and improved Swift extension logging so a logfile is produced in addition to logging messages to the existing `Swift` output channel. Deprecated the `swift.diagnostics` setting in favour of the new `swift.outputChannelLogLevel` setting ([#1746](https://github.com/swiftlang/vscode-swift/pull/1746))

package-lock.json

Lines changed: 145 additions & 147 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,14 +1977,14 @@
19771977
"@types/micromatch": "^4.0.9",
19781978
"@types/mocha": "^10.0.10",
19791979
"@types/mock-fs": "^4.13.4",
1980-
"@types/node": "^20.19.9",
1980+
"@types/node": "^20.19.10",
19811981
"@types/plist": "^3.0.5",
19821982
"@types/semver": "^7.7.0",
19831983
"@types/sinon": "^17.0.4",
19841984
"@types/sinon-chai": "^3.2.12",
19851985
"@types/vscode": "^1.88.0",
19861986
"@types/xml2js": "^0.4.14",
1987-
"@typescript-eslint/eslint-plugin": "^8.39.0",
1987+
"@typescript-eslint/eslint-plugin": "^8.39.1",
19881988
"@typescript-eslint/parser": "^8.32.1",
19891989
"@vscode/debugprotocol": "^1.68.0",
19901990
"@vscode/test-cli": "^0.0.11",
@@ -2000,7 +2000,7 @@
20002000
"eslint-config-prettier": "^10.1.8",
20012001
"fantasticon": "^3.0.0",
20022002
"husky": "^9.1.7",
2003-
"lint-staged": "^16.1.4",
2003+
"lint-staged": "^16.1.5",
20042004
"lodash.debounce": "^4.0.8",
20052005
"lodash.throttle": "^4.1.1",
20062006
"micromatch": "^4.0.8",
@@ -2030,6 +2030,6 @@
20302030
"plist": "^3.1.0",
20312031
"vscode-languageclient": "^9.0.1",
20322032
"xml2js": "^0.6.2",
2033-
"zod": "^4.0.14"
2033+
"zod": "^4.0.17"
20342034
}
20352035
}

src/FolderContext.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,22 @@ import { LinuxMain } from "./LinuxMain";
1818
import { PackageWatcher } from "./PackageWatcher";
1919
import { SwiftPackage, Target, TargetType } from "./SwiftPackage";
2020
import { TestExplorer } from "./TestExplorer/TestExplorer";
21+
import { TestRunManager } from "./TestExplorer/TestRunManager";
2122
import { WorkspaceContext, FolderOperation } from "./WorkspaceContext";
2223
import { BackgroundCompilation } from "./BackgroundCompilation";
2324
import { TaskQueue } from "./tasks/TaskQueue";
2425
import { isPathInsidePath } from "./utilities/filesystem";
2526
import { SwiftToolchain } from "./toolchain/toolchain";
2627
import { SwiftLogger } from "./logging/SwiftLogger";
28+
import { TestRunProxy } from "./TestExplorer/TestRunner";
2729

2830
export class FolderContext implements vscode.Disposable {
29-
private packageWatcher: PackageWatcher;
3031
public backgroundCompilation: BackgroundCompilation;
3132
public hasResolveErrors = false;
3233
public testExplorer?: TestExplorer;
3334
public taskQueue: TaskQueue;
35+
private packageWatcher: PackageWatcher;
36+
private testRunManager: TestRunManager;
3437

3538
/**
3639
* FolderContext constructor
@@ -49,6 +52,7 @@ export class FolderContext implements vscode.Disposable {
4952
this.packageWatcher = new PackageWatcher(this, workspaceContext);
5053
this.backgroundCompilation = new BackgroundCompilation(this);
5154
this.taskQueue = new TaskQueue(this);
55+
this.testRunManager = new TestRunManager();
5256
}
5357

5458
/** dispose of any thing FolderContext holds */
@@ -212,6 +216,34 @@ export class FolderContext implements vscode.Disposable {
212216
return target;
213217
}
214218

219+
/**
220+
* Register a new test run
221+
* @param testRun The test run to register
222+
* @param folder The folder context
223+
* @param testKind The kind of test run
224+
* @param tokenSource The cancellation token source
225+
*/
226+
public registerTestRun(testRun: TestRunProxy, tokenSource: vscode.CancellationTokenSource) {
227+
this.testRunManager.registerTestRun(testRun, this, tokenSource);
228+
}
229+
230+
/**
231+
* Returns true if there is an active test run for the given test kind
232+
* @param testKind The kind of test
233+
* @returns True if there is an active test run, false otherwise
234+
*/
235+
hasActiveTestRun() {
236+
return this.testRunManager.getActiveTestRun(this) !== undefined;
237+
}
238+
239+
/**
240+
* Cancels the active test run for the given test kind
241+
* @param testKind The kind of test run
242+
*/
243+
cancelTestRun() {
244+
this.testRunManager.cancelTestRun(this);
245+
}
246+
215247
/**
216248
* Called whenever we have new document symbols
217249
*/

src/TestExplorer/TestRunManager.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the VS Code Swift open source project
4+
//
5+
// Copyright (c) 2021-2025 the VS Code Swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of VS Code Swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import * as vscode from "vscode";
16+
import { TestRunProxy } from "./TestRunner";
17+
import { FolderContext } from "../FolderContext";
18+
19+
/**
20+
* Manages active test runs and provides functionality to check if a test run is in progress
21+
* and to cancel test runs.
22+
*/
23+
export class TestRunManager {
24+
private activeTestRuns = new Map<
25+
string,
26+
{ testRun: TestRunProxy; tokenSource: vscode.CancellationTokenSource }
27+
>();
28+
29+
/**
30+
* Register a new test run
31+
* @param testRun The test run to register
32+
* @param folder The folder context
33+
* @param tokenSource The cancellation token source
34+
*/
35+
public registerTestRun(
36+
testRun: TestRunProxy,
37+
folder: FolderContext,
38+
tokenSource: vscode.CancellationTokenSource
39+
) {
40+
const key = this.getTestRunKey(folder);
41+
this.activeTestRuns.set(key, { testRun, tokenSource });
42+
43+
// When the test run completes, remove it from active test runs
44+
testRun.onTestRunComplete(() => {
45+
this.activeTestRuns.delete(key);
46+
});
47+
}
48+
49+
/**
50+
* Cancel an active test run
51+
* @param folder The folder context
52+
*/
53+
public cancelTestRun(folder: FolderContext) {
54+
const key = this.getTestRunKey(folder);
55+
const activeRun = this.activeTestRuns.get(key);
56+
if (activeRun) {
57+
activeRun.tokenSource.cancel();
58+
}
59+
}
60+
61+
/**
62+
* Check if a test run is already in progress for the given folder and test kind
63+
* @param folder The folder context
64+
* @returns The active test run if one exists, undefined otherwise
65+
*/
66+
public getActiveTestRun(folder: FolderContext) {
67+
const key = this.getTestRunKey(folder);
68+
const activeRun = this.activeTestRuns.get(key);
69+
return activeRun?.testRun;
70+
}
71+
72+
/**
73+
* Generate a unique key for a test run based on folder and test kind
74+
* @param folder The folder context
75+
* @returns A unique key
76+
*/
77+
private getTestRunKey(folder: FolderContext) {
78+
return folder.folder.fsPath;
79+
}
80+
}

0 commit comments

Comments
 (0)