diff --git a/package.json b/package.json index c9311db..2cf5ede 100644 --- a/package.json +++ b/package.json @@ -201,6 +201,12 @@ "title": "Flash Pico Project (SWD)", "category": "Raspberry Pi Pico", "enablement": "raspberry-pi-pico.isPicoProject" + }, + { + "command": "raspberry-pi-pico.cleanCmake", + "title": "Clean CMake", + "category": "Raspberry Pi Pico", + "enablement": "raspberry-pi-pico.isPicoProject && !raspberry-pi-pico.isRustProject" } ], "configuration": { diff --git a/src/commands/configureCmake.mts b/src/commands/configureCmake.mts index e6ea4f5..c02bd0f 100644 --- a/src/commands/configureCmake.mts +++ b/src/commands/configureCmake.mts @@ -3,6 +3,9 @@ import Logger from "../logger.mjs"; import { window, workspace } from "vscode"; import { configureCmakeNinja } from "../utils/cmakeUtil.mjs"; import Settings, { SettingsKey } from "../settings.mjs"; +import { join } from "path"; +import { rimraf } from "rimraf"; +import { unknownErrorToString } from "../utils/errorHelper.mjs"; export default class ConfigureCmakeCommand extends Command { private _logger: Logger = new Logger("ConfigureCmakeCommand"); @@ -34,7 +37,7 @@ export default class ConfigureCmakeCommand extends Command { "You must use the CMake Tools extension to configure your build. " + "To use this extension instead, change the useCmakeTools setting." ); - + return; } @@ -45,3 +48,62 @@ export default class ConfigureCmakeCommand extends Command { } } } + +export class CleanCMakeCommand extends Command { + private _logger: Logger = new Logger("CleanCMakeCommand"); + + public static readonly id = "cleanCmake"; + + constructor() { + super(CleanCMakeCommand.id); + } + + async execute(): Promise { + const workspaceFolder = workspace.workspaceFolders?.[0]; + + if (workspaceFolder === undefined) { + this._logger.warn("No workspace folder found."); + void window.showWarningMessage("No workspace folder found."); + + return; + } + + const settings = Settings.getInstance(); + + if ( + settings !== undefined && + settings.getBoolean(SettingsKey.useCmakeTools) + ) { + void window.showErrorMessage( + "You must use the CMake Tools extension to clean your build. " + + "To use this extension instead, change the useCmakeTools setting." + ); + + return; + } + + try { + // delete build dir if present + const buildDir = join(workspaceFolder.uri.fsPath, "build"); + await rimraf(buildDir, { maxRetries: 2 }); + } catch (error) { + this._logger.error( + "Error cleaning build directory.", + unknownErrorToString(error) + ); + void window.showErrorMessage("Error cleaning build directory."); + + return; + } + + if (await configureCmakeNinja(workspaceFolder.uri)) { + void window.showInformationMessage( + "CMake has been cleaned and reconfigured." + ); + } else { + void window.showWarningMessage( + "CMake could not be reconfigured. See log for details." + ); + } + } +} diff --git a/src/extension.mts b/src/extension.mts index f37757d..cb3309f 100644 --- a/src/extension.mts +++ b/src/extension.mts @@ -65,7 +65,9 @@ import { PicoProjectActivityBar } from "./webview/activityBar.mjs"; import ConditionalDebuggingCommand from "./commands/conditionalDebugging.mjs"; import DebugLayoutCommand from "./commands/debugLayout.mjs"; import OpenSdkDocumentationCommand from "./commands/openSdkDocumentation.mjs"; -import ConfigureCmakeCommand from "./commands/configureCmake.mjs"; +import ConfigureCmakeCommand, { + CleanCMakeCommand, +} from "./commands/configureCmake.mjs"; import ImportProjectCommand from "./commands/importProject.mjs"; import { homedir } from "os"; import NewExampleProjectCommand from "./commands/newExampleProject.mjs"; @@ -121,6 +123,7 @@ export async function activate(context: ExtensionContext): Promise { new ImportProjectCommand(context.extensionUri), new NewExampleProjectCommand(context.extensionUri), new UninstallPicoSDKCommand(), + new CleanCMakeCommand(), ]; // register all command handlers diff --git a/src/webview/activityBar.mts b/src/webview/activityBar.mts index bf60764..3b3f4e7 100644 --- a/src/webview/activityBar.mts +++ b/src/webview/activityBar.mts @@ -19,7 +19,9 @@ import OpenSdkDocumentationCommand, { DOCUMENTATION_LABEL_BY_ID, DocumentationId, } from "../commands/openSdkDocumentation.mjs"; -import ConfigureCmakeCommand from "../commands/configureCmake.mjs"; +import ConfigureCmakeCommand, { + CleanCMakeCommand, +} from "../commands/configureCmake.mjs"; import ImportProjectCommand from "../commands/importProject.mjs"; import NewExampleProjectCommand from "../commands/newExampleProject.mjs"; import SwitchBoardCommand from "../commands/switchBoard.mjs"; @@ -49,6 +51,7 @@ const COMPILE_PROJECT_LABEL = "Compile Project"; const RUN_PROJECT_LABEL = "Run Project (USB)"; const FLASH_PROJECT_LABEL = "Flash Project (SWD)"; const CONFIGURE_CMAKE_PROJECT_LABEL = "Configure CMake"; +const CLEAN_CMAKE_PROJECT_LABEL = "Clean CMake"; const DEBUG_PROJECT_LABEL = "Debug Project"; const DEBUG_LAYOUT_PROJECT_LABEL = "Debug Layout"; @@ -112,6 +115,10 @@ export class PicoProjectActivityBar // alt. "gather" element.iconPath = new ThemeIcon("beaker"); break; + case CLEAN_CMAKE_PROJECT_LABEL: + // or "trash" or "sync" + element.iconPath = new ThemeIcon("squirrel"); + break; case SWITCH_SDK_LABEL: // repo-forked or extensions; alt. "replace-all" element.iconPath = new ThemeIcon("find-replace-all"); @@ -239,6 +246,14 @@ export class PicoProjectActivityBar title: CONFIGURE_CMAKE_PROJECT_LABEL, } ), + new QuickAccessCommand( + CLEAN_CMAKE_PROJECT_LABEL, + TreeItemCollapsibleState.None, + { + command: `${extensionName}.${CleanCMakeCommand.id}`, + title: CLEAN_CMAKE_PROJECT_LABEL, + } + ), new QuickAccessCommand( SWITCH_SDK_LABEL, TreeItemCollapsibleState.None,