Skip to content
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
12 changes: 9 additions & 3 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ export function registerToolchainCommands(
];
}

export enum Commands {
RUN = "swift.run",
DEBUG = "swift.debug",
CLEAN_BUILD = "swift.cleanBuild",
}

/**
* Registers this extension's commands in the given {@link vscode.ExtensionContext context}.
*/
Expand All @@ -74,9 +80,9 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
resolveDependencies(ctx)
),
vscode.commands.registerCommand("swift.updateDependencies", () => updateDependencies(ctx)),
vscode.commands.registerCommand("swift.run", () => runBuild(ctx)),
vscode.commands.registerCommand("swift.debug", () => debugBuild(ctx)),
vscode.commands.registerCommand("swift.cleanBuild", () => cleanBuild(ctx)),
vscode.commands.registerCommand(Commands.RUN, () => runBuild(ctx)),
vscode.commands.registerCommand(Commands.DEBUG, () => debugBuild(ctx)),
vscode.commands.registerCommand(Commands.CLEAN_BUILD, () => cleanBuild(ctx)),
vscode.commands.registerCommand("swift.runTestsMultipleTimes", item => {
if (ctx.currentFolder) {
return runTestMultipleTimes(ctx.currentFolder, item, false);
Expand Down
8 changes: 4 additions & 4 deletions src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ import { FolderContext } from "../FolderContext";
* Executes a {@link vscode.Task task} to run swift target.
*/
export async function runBuild(ctx: WorkspaceContext) {
await debugBuildWithOptions(ctx, { noDebug: true });
return await debugBuildWithOptions(ctx, { noDebug: true });
}

/**
* Executes a {@link vscode.Task task} to debug swift target.
*/
export async function debugBuild(ctx: WorkspaceContext) {
await debugBuildWithOptions(ctx, {});
return await debugBuildWithOptions(ctx, {});
}

/**
Expand All @@ -41,7 +41,7 @@ export async function cleanBuild(ctx: WorkspaceContext) {
if (!current) {
return;
}
await folderCleanBuild(current);
return await folderCleanBuild(current);
}

/**
Expand All @@ -62,7 +62,7 @@ export async function folderCleanBuild(folderContext: FolderContext) {
folderContext.workspaceContext.toolchain
);

await executeTaskWithUI(task, "Clean Build", folderContext);
return await executeTaskWithUI(task, "Clean Build", folderContext);
}

/**
Expand Down
17 changes: 13 additions & 4 deletions src/debugger/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ import { CI_DISABLE_ASLR } from "./lldb";
* @param ctx folder context to create launch configurations for
* @param yes automatically answer yes to dialogs
*/
export async function makeDebugConfigurations(ctx: FolderContext, message?: string, yes = false) {
export async function makeDebugConfigurations(
ctx: FolderContext,
message?: string,
yes = false
): Promise<boolean> {
if (!configuration.folder(ctx.workspaceFolder).autoGenerateLaunchConfigurations) {
return;
return false;
}
const wsLaunchSection = vscode.workspace.getConfiguration("launch", ctx.folder);
const launchConfigs = wsLaunchSection.get<vscode.DebugConfiguration[]>("configurations") || [];
Expand All @@ -41,6 +45,8 @@ export async function makeDebugConfigurations(ctx: FolderContext, message?: stri
"cwd",
"preLaunchTask",
"type",
"disableASLR",
"initCommands",
`env.${swiftLibraryPathKey()}`,
];
const configUpdates: { index: number; config: vscode.DebugConfiguration }[] = [];
Expand Down Expand Up @@ -96,6 +102,7 @@ export async function makeDebugConfigurations(ctx: FolderContext, message?: stri
vscode.ConfigurationTarget.WorkspaceFolder
);
}
return true;
}

// Return debug launch configuration for an executable in the given folder
Expand Down Expand Up @@ -178,15 +185,17 @@ export async function debugLaunchConfig(
config: vscode.DebugConfiguration,
options: vscode.DebugSessionOptions = {}
) {
return new Promise<void>((resolve, reject) => {
return new Promise<boolean>((resolve, reject) => {
vscode.debug.startDebugging(workspaceFolder, config, options).then(
started => {
if (started) {
const terminateSession = vscode.debug.onDidTerminateDebugSession(async () => {
// dispose terminate debug handler
terminateSession.dispose();
resolve();
resolve(true);
});
} else {
resolve(false);
}
},
reason => {
Expand Down
3 changes: 2 additions & 1 deletion src/ui/ReloadExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//

import * as vscode from "vscode";
import { Workbench } from "../utilities/commands";

/**
* Prompts the user to reload the extension in cases where we are unable to do
Expand All @@ -29,7 +30,7 @@ export async function showReloadExtensionNotification<T extends string>(
const buttons: ("Reload Extensions" | T)[] = ["Reload Extensions", ...items];
const selected = await vscode.window.showWarningMessage(message, ...buttons);
if (selected === "Reload Extensions") {
await vscode.commands.executeCommand("workbench.action.reloadWindow");
await vscode.commands.executeCommand(Workbench.ACTION_RELOADWINDOW);
}
return selected;
}
19 changes: 19 additions & 0 deletions src/utilities/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the VS Code Swift open source project
//
// Copyright (c) 2024 the VS Code Swift project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of VS Code Swift project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

export enum Workbench {
ACTION_DEBUG_CONTINUE = "workbench.action.debug.continue",
ACTION_CLOSEALLEDITORS = "workbench.action.closeAllEditors",
ACTION_RELOADWINDOW = "workbench.action.reloadWindow",
}
3 changes: 2 additions & 1 deletion test/integration-tests/BackgroundCompilation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { WorkspaceContext } from "../../src/WorkspaceContext";
import { globalWorkspaceContextPromise } from "./extension.test";
import { testAssetUri } from "../fixtures";
import { waitForNoRunningTasks } from "../utilities";
import { Workbench } from "../../src/utilities/commands";

suite("BackgroundCompilation Test Suite", () => {
let workspaceContext: WorkspaceContext;
Expand All @@ -31,7 +32,7 @@ suite("BackgroundCompilation Test Suite", () => {

suiteTeardown(async () => {
await vscode.workspace.getConfiguration("swift").update("backgroundCompilation", undefined);
await vscode.commands.executeCommand("workbench.action.closeActiveEditor");
await vscode.commands.executeCommand(Workbench.ACTION_CLOSEALLEDITORS);
});

test("build all on save @slow", async () => {
Expand Down
3 changes: 2 additions & 1 deletion test/integration-tests/DiagnosticsManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { DiagnosticsManager } from "../../src/DiagnosticsManager";
import { FolderContext } from "../../src/FolderContext";
import { Version } from "../../src/utilities/version";
import { folderContextPromise, globalWorkspaceContextPromise } from "./extension.test";
import { Workbench } from "../../src/utilities/commands";

const waitForDiagnostics = (uris: vscode.Uri[], allowEmpty: boolean = true) =>
new Promise<void>(res =>
Expand Down Expand Up @@ -907,7 +908,7 @@ suite("DiagnosticsManager Test Suite", async function () {
});

teardown(async () => {
await vscode.commands.executeCommand("workbench.action.closeAllEditors");
await vscode.commands.executeCommand(Workbench.ACTION_CLOSEALLEDITORS);
});

test("Provides swift diagnostics", async () => {
Expand Down
97 changes: 97 additions & 0 deletions test/integration-tests/commands/build.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the VS Code Swift open source project
//
// Copyright (c) 2024 the VS Code Swift project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of VS Code Swift project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import * as vscode from "vscode";
import * as fs from "fs";
import * as path from "path";
import { expect } from "chai";
import { folderContextPromise, globalWorkspaceContextPromise } from "../extension.test";
import { waitForNoRunningTasks } from "../../utilities";
import { testAssetUri } from "../../fixtures";
import { FolderContext } from "../../../src/FolderContext";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import { Commands } from "../../../src/commands";
import { makeDebugConfigurations } from "../../../src/debugger/launch";
import { Workbench } from "../../../src/utilities/commands";
import { continueSession, waitForDebugAdapterCommand } from "../../utilities/debug";
import { SettingsMap, updateSettings } from "../testexplorer/utilities";

suite("Build Commands", function () {
let folderContext: FolderContext;
let workspaceContext: WorkspaceContext;
let settingsTeardown: () => Promise<SettingsMap>;
const uri = testAssetUri("defaultPackage/Sources/PackageExe/main.swift");
const breakpoints = [
new vscode.SourceBreakpoint(new vscode.Location(uri, new vscode.Position(2, 0))),
];

suiteSetup(async function () {
workspaceContext = await globalWorkspaceContextPromise;
await waitForNoRunningTasks();
folderContext = await folderContextPromise("defaultPackage");
await workspaceContext.focusFolder(folderContext);
await vscode.window.showTextDocument(uri);
settingsTeardown = await updateSettings({
"swift.autoGenerateLaunchConfigurations": true,
});
await makeDebugConfigurations(folderContext, undefined, true);
});

suiteTeardown(async () => {
await settingsTeardown();
await vscode.commands.executeCommand(Workbench.ACTION_CLOSEALLEDITORS);
});

test("Swift: Run Build", async () => {
// A breakpoint will have not effect on the Run command.
vscode.debug.addBreakpoints(breakpoints);

const result = await vscode.commands.executeCommand(Commands.RUN);
expect(result).to.be.true;

vscode.debug.removeBreakpoints(breakpoints);
});

test("Swift: Clean Build", async () => {
const buildPath = path.join(folderContext.folder.fsPath, ".build");
const beforeItemCount = fs.readdirSync(buildPath).length;

const result = await vscode.commands.executeCommand(Commands.CLEAN_BUILD);
expect(result).to.be.true;

const afterItemCount = fs.readdirSync(buildPath).length;
// This test will run in order after the Swift: Run Build test,
// where .build folder is going to be filled with built artifacts.
// After executing the clean command the build directory is guranteed to have less entry.
expect(afterItemCount).to.be.lessThan(beforeItemCount);
});

test("Swift: Debug Build @slow", async () => {
vscode.debug.addBreakpoints(breakpoints);
// Promise used to indicate we hit the break point.
// NB: "stopped" is the exact command when debuggee has stopped due to break point,
// but "stackTrace" is the deterministic sync point we will use to make sure we can execute continue
const bpPromise = waitForDebugAdapterCommand(
"Debug PackageExe (defaultPackage)",
"stackTrace",
workspaceContext
);

const result = vscode.commands.executeCommand(Commands.DEBUG);
expect(result).to.eventually.be.true;

await bpPromise.then(() => continueSession());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we're hitting breakpoints, crossing into smoke level, let's create a smoke suite and put that there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that's what @slow do right now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still should split into separate suite. Is it actually slow or just trying to keep out of CI build?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are we trying to achieve to split this into a separate suite? Is it for dependency management?

Given the test run fast and this is a command that should probably always work, I am not sure if we want keep this out of CI.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will leave this for until long term approach is decided

vscode.debug.removeBreakpoints(breakpoints);
});
});
3 changes: 2 additions & 1 deletion test/integration-tests/editor/CommentCompletion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as assert from "assert";
import * as vscode from "vscode";
import { CommentCompletionProviders } from "../../../src/editor/CommentCompletion";
import { Workbench } from "../../../src/utilities/commands";

suite("CommentCompletion Test Suite", () => {
let document: vscode.TextDocument | undefined;
Expand All @@ -31,7 +32,7 @@ suite("CommentCompletion Test Suite", () => {

if (editor && document) {
await vscode.window.showTextDocument(document, editor.viewColumn);
await vscode.commands.executeCommand("workbench.action.closeActiveEditor");
await vscode.commands.executeCommand(Workbench.ACTION_CLOSEALLEDITORS);
}

provider.dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
eventPromise,
gatherTests,
runTest,
SettingsMap,
setupTestExplorerTest,
waitForTestExplorerReady,
} from "./utilities";
Expand Down Expand Up @@ -51,7 +52,7 @@ suite("Test Explorer Suite", function () {
let testExplorer: TestExplorer;

suite("Debugging", function () {
let settingsTeardown: () => void;
let settingsTeardown: () => Promise<SettingsMap>;

async function runXCTest() {
const suiteId = "PackageTests.PassingXCTestSuite";
Expand Down
6 changes: 2 additions & 4 deletions test/integration-tests/testexplorer/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export type SettingsMap = { [key: string]: unknown };
* "section.name" format, and the value is the new setting value.
* @returns A function that, when called, resets the settings back to their original values.
*/
export async function updateSettings(settings: SettingsMap): Promise<() => Promise<void>> {
export async function updateSettings(settings: SettingsMap): Promise<() => Promise<SettingsMap>> {
const applySettings = async (settings: SettingsMap) => {
const savedOriginalSettings: SettingsMap = {};
Object.keys(settings).forEach(async setting => {
Expand Down Expand Up @@ -224,9 +224,7 @@ export async function updateSettings(settings: SettingsMap): Promise<() => Promi
const savedOriginalSettings = await applySettings(settings);

// Clients call the callback to reset updated settings to their original value
return async () => {
await applySettings(savedOriginalSettings);
};
return async () => await applySettings(savedOriginalSettings);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion test/unit-tests/ui/ReloadExtension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { expect } from "chai";
import { mockGlobalObject } from "../../MockUtils";
import * as vscode from "vscode";
import { showReloadExtensionNotification } from "../../../src/ui/ReloadExtension";
import { Workbench } from "../../../src/utilities/commands";

suite("showReloadExtensionNotification()", async function () {
const mockedVSCodeWindow = mockGlobalObject(vscode, "window");
Expand All @@ -38,7 +39,7 @@ suite("showReloadExtensionNotification()", async function () {
await showReloadExtensionNotification("Want to reload?");

expect(mockedVSCodeCommands.executeCommand).to.have.been.calledOnceWithExactly(
"workbench.action.reloadWindow"
Workbench.ACTION_RELOADWINDOW
);
});

Expand Down
Loading