diff --git a/packages/core/lib/commands/debug/meta.js b/packages/core/lib/commands/debug/meta.js index e269f827924..6698a4f72e5 100644 --- a/packages/core/lib/commands/debug/meta.js +++ b/packages/core/lib/commands/debug/meta.js @@ -31,6 +31,12 @@ module.exports = { describe: "Force debugger to skip compilation (dangerous!)", type: "boolean", default: false + }, + "vscode": { + describe: + "Starts the debug session in VS Code using the Truffle for VS Code extension", + type: "boolean", + default: false } }, help: { @@ -75,6 +81,11 @@ module.exports = { option: "--compile-none", description: "Forces the debugger to use artifacts even if it detects a problem. Dangerous; may cause errors." + }, + { + option: "--vscode", + description: + "Starts the debug session in VS Code using the Truffle for VS Code extension." } ], allowedGlobalOptions: ["config"] diff --git a/packages/core/lib/commands/debug/run.js b/packages/core/lib/commands/debug/run.js index a7d6d903900..02346308bbe 100644 --- a/packages/core/lib/commands/debug/run.js +++ b/packages/core/lib/commands/debug/run.js @@ -6,7 +6,7 @@ module.exports = async function (options) { const FromHardhat = require("@truffle/from-hardhat"); const Codec = require("@truffle/codec"); const TruffleError = require("@truffle/error"); - const { CLIDebugger } = require("../../debug"); + const { CLIDebugger, VSCodeDebugger } = require("../../debug"); if (options.url && options.network) { const message = @@ -60,6 +60,15 @@ module.exports = async function (options) { if (config.compileAll && config.compileNone) { throw new Error("Incompatible options passed regarding what to compile"); } + + // Checks if the user wants to open the debugger in vscode + if (config.vscode) { + // await new VSCodeDebugger(config, txHash).run(); + const vsDebugger = new VSCodeDebugger(config, txHash); + await vsDebugger.run(); + return; + } + const interpreter = await new CLIDebugger(config, { txHash, compilations diff --git a/packages/core/lib/debug/index.js b/packages/core/lib/debug/index.js index cd0d801a970..1dda86a07dd 100644 --- a/packages/core/lib/debug/index.js +++ b/packages/core/lib/debug/index.js @@ -1,5 +1,7 @@ const { CLIDebugger } = require("./cli"); +const { VSCodeDebugger } = require("./vscode"); module.exports = { - CLIDebugger + CLIDebugger, + VSCodeDebugger }; diff --git a/packages/core/lib/debug/vscode.js b/packages/core/lib/debug/vscode.js new file mode 100644 index 00000000000..922bdc2eb11 --- /dev/null +++ b/packages/core/lib/debug/vscode.js @@ -0,0 +1,73 @@ +const childProcess = require("child_process"); + +class VSCodeDebugger { + constructor(config, txHash) { + this.config = config; + this.txHash = txHash; + } + + /** + * This function is responsible for opening the debugger in vscode. + */ + async run() { + // Sets the URL + const url = new URL("/debug", "vscode://trufflesuite-csi.truffle-vscode"); + + const disableFetchExternal = this.config.fetchExternal ? false : true; + + // Sets the query parameters + url.searchParams.set("txHash", this.txHash); + url.searchParams.set("workingDirectory", this.config.working_directory); + url.searchParams.set("providerUrl", this.getProviderUrl()); + url.searchParams.set("network", this.config.network); + url.searchParams.set("disableFetchExternal", disableFetchExternal); + + // Opens VSCode based on OS + const openCommand = process.platform === "win32" ? `start ""` : `open`; + const commandLine = `${openCommand} "${url}"`; + + // Defines the options for the child process. An abort signal is used to cancel the process, if necessary. + const controller = new AbortController(); + const { signal } = controller; + + // Executes the command + childProcess.exec(commandLine, { signal }, (stderr, error) => { + if (stderr) { + throw new Error(`Error opening the debug session in VSCode: ${stderr}`); + } + if (error) { + controller.abort(); + throw new Error(`Error opening the debug session in VSCode: ${error}`); + } + }); + + // Sends a message to the user + this.config.logger.log("Opening truffle debugger in VSCode..."); + } + + /** + * This function is for getting the provider URL. + */ + getProviderUrl() { + // Checks if the user is using a custom provider + if (this.config.url) { + return this.config.url; + } + + // Checks if there is a provider in the config + if (this.config.provider) { + return this.config.provider.host; + } + + // Creates the provider URL from host and port + if (this.config.network_config) { + return new URL( + `http://${this.config.network_config.host}:${this.config.network_config.port}` + ).toString(); + } + } +} + +module.exports = { + VSCodeDebugger +};