From 344bbbd804528c378730b06ed784377444230fc9 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Wed, 11 Nov 2020 11:27:58 -0800 Subject: [PATCH 01/13] fix dtr on serial open --- src/serialmonitor/serialportctrl.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/serialmonitor/serialportctrl.ts b/src/serialmonitor/serialportctrl.ts index c09e1e78..a7445c4a 100644 --- a/src/serialmonitor/serialportctrl.ts +++ b/src/serialmonitor/serialportctrl.ts @@ -71,7 +71,7 @@ export class SerialPortCtrl { this._outputChannel.appendLine("[Warning] Auto checking serial port open is disabled"); return resolve(); } - + this._currentSerialPort.write("TestingOpen" + "\r\n", (err) => { // TODO: Fix this on the serial port lib: https://github.com/EmergingTechnologyAdvisors/node-serialport/issues/795 if (err && !(err.message.indexOf("Writing to COM port (GetOverlappedResult): Unknown error code 121") >= 0)) { @@ -79,6 +79,11 @@ export class SerialPortCtrl { reject(err); } else { this._outputChannel.appendLine(`[Info] Opened the serial port - ${this._currentPort}`); + this._currentSerialPort.set(['dtr=true'], (err) => { + if (err) { + reject(err); + } + }); resolve(); } }); @@ -164,7 +169,13 @@ export class SerialPortCtrl { if (err) { reject(err); } else { - resolve(); + this._currentSerialPort.set(['dtr=true'], (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); } }); }); From 1785737ab26d1297766a506fee89e14a1fe6b93a Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Wed, 11 Nov 2020 11:27:58 -0800 Subject: [PATCH 02/13] fix dtr on serial open --- src/serialmonitor/serialportctrl.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/serialmonitor/serialportctrl.ts b/src/serialmonitor/serialportctrl.ts index c09e1e78..a7445c4a 100644 --- a/src/serialmonitor/serialportctrl.ts +++ b/src/serialmonitor/serialportctrl.ts @@ -71,7 +71,7 @@ export class SerialPortCtrl { this._outputChannel.appendLine("[Warning] Auto checking serial port open is disabled"); return resolve(); } - + this._currentSerialPort.write("TestingOpen" + "\r\n", (err) => { // TODO: Fix this on the serial port lib: https://github.com/EmergingTechnologyAdvisors/node-serialport/issues/795 if (err && !(err.message.indexOf("Writing to COM port (GetOverlappedResult): Unknown error code 121") >= 0)) { @@ -79,6 +79,11 @@ export class SerialPortCtrl { reject(err); } else { this._outputChannel.appendLine(`[Info] Opened the serial port - ${this._currentPort}`); + this._currentSerialPort.set(['dtr=true'], (err) => { + if (err) { + reject(err); + } + }); resolve(); } }); @@ -164,7 +169,13 @@ export class SerialPortCtrl { if (err) { reject(err); } else { - resolve(); + this._currentSerialPort.set(['dtr=true'], (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); } }); }); From abcfcc1a5d0bb191635fbfe179b2252ab48be8b4 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Wed, 11 Nov 2020 17:38:46 -0800 Subject: [PATCH 03/13] fix linting --- src/serialmonitor/serialportctrl.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/serialmonitor/serialportctrl.ts b/src/serialmonitor/serialportctrl.ts index a7445c4a..ec02d6b9 100644 --- a/src/serialmonitor/serialportctrl.ts +++ b/src/serialmonitor/serialportctrl.ts @@ -71,7 +71,7 @@ export class SerialPortCtrl { this._outputChannel.appendLine("[Warning] Auto checking serial port open is disabled"); return resolve(); } - + this._currentSerialPort.write("TestingOpen" + "\r\n", (err) => { // TODO: Fix this on the serial port lib: https://github.com/EmergingTechnologyAdvisors/node-serialport/issues/795 if (err && !(err.message.indexOf("Writing to COM port (GetOverlappedResult): Unknown error code 121") >= 0)) { @@ -79,10 +79,10 @@ export class SerialPortCtrl { reject(err); } else { this._outputChannel.appendLine(`[Info] Opened the serial port - ${this._currentPort}`); - this._currentSerialPort.set(['dtr=true'], (err) => { + this._currentSerialPort.set(["dtr=true"], (err) => { if (err) { reject(err); - } + } }); resolve(); } @@ -169,7 +169,7 @@ export class SerialPortCtrl { if (err) { reject(err); } else { - this._currentSerialPort.set(['dtr=true'], (err) => { + this._currentSerialPort.set(["dtr=true"], (err) => { if (err) { reject(err); } else { From a03ab8faa317982dac88b33545a2534636faeb22 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Wed, 18 Nov 2020 07:17:00 -0800 Subject: [PATCH 04/13] pre release v0.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f30bc901..04bebafb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-arduino", "displayName": "Arduino", "description": "Arduino for Visual Studio Code", - "version": "0.3.3", + "version": "0.3.4-rc", "publisher": "vsciot-vscode", "aiKey": "83dd2c27-6594-41d3-85a9-bdb22070eb42", "preview": true, From 8fc91d6a517d35b905062b214cbcef7f65edf517 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Thu, 19 Nov 2020 14:00:20 -0800 Subject: [PATCH 05/13] Add RTS signal on serial open, Add baudrates up to 2000000 (#1142) * add buad rates up to 2M * add rts signal on serial open and buad rate change * add missing space in baud rate array --- src/serialmonitor/serialMonitor.ts | 2 +- src/serialmonitor/serialportctrl.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/serialmonitor/serialMonitor.ts b/src/serialmonitor/serialMonitor.ts index 5153972c..812801d5 100644 --- a/src/serialmonitor/serialMonitor.ts +++ b/src/serialmonitor/serialMonitor.ts @@ -22,7 +22,7 @@ export class SerialMonitor implements vscode.Disposable { public static DEFAULT_BAUD_RATE: number = 115200; public static listBaudRates(): number[] { - return [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000]; + return [300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000, 500000, 1000000, 2000000]; } public static getInstance(): SerialMonitor { diff --git a/src/serialmonitor/serialportctrl.ts b/src/serialmonitor/serialportctrl.ts index ec02d6b9..27204eb6 100644 --- a/src/serialmonitor/serialportctrl.ts +++ b/src/serialmonitor/serialportctrl.ts @@ -79,7 +79,7 @@ export class SerialPortCtrl { reject(err); } else { this._outputChannel.appendLine(`[Info] Opened the serial port - ${this._currentPort}`); - this._currentSerialPort.set(["dtr=true"], (err) => { + this._currentSerialPort.set(["dtr=true", "rts=true"], (err) => { if (err) { reject(err); } @@ -169,7 +169,7 @@ export class SerialPortCtrl { if (err) { reject(err); } else { - this._currentSerialPort.set(["dtr=true"], (err) => { + this._currentSerialPort.set(["dtr=true", "rts=true"], (err) => { if (err) { reject(err); } else { From 03ca266ddbb59fbeb6b1f12c30bfa4ad66976f75 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Thu, 19 Nov 2020 19:43:52 -0800 Subject: [PATCH 06/13] Quick fix for Intellisense (#1144) * add hardware tool path * intellisense quick fix * add hardware tool path * intellisense quick fix * fix typo --- src/arduino/arduino.ts | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index 73619a7b..263a5069 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -320,15 +320,21 @@ export class ArduinoApp { return; } const cppConfigFile = fs.readFileSync(configFilePath, "utf8"); - const cppConfig = JSON.parse(cppConfigFile) as { configurations: Array<{ includePath: string[], forcedInclude: string[] }> }; + const cppConfig = JSON.parse(cppConfigFile) as { configurations: Array<{ + includePath: string[], + forcedInclude: string[], + defines: string[], + }> }; const libPaths = this.getDefaultPackageLibPaths(); const defaultForcedInclude = this.getDefaultForcedIncludeFiles(); + const defines = this.getDefaultDefines(); const configuration = cppConfig.configurations[0]; let cppConfigFileUpdated = false; - // cpp exntension changes \\ to \\\\ in paths in JSON string, revert them first + // cpp extension changes \\ to \\\\ in paths in JSON string, revert them first configuration.includePath = configuration.includePath.map((path) => path.replace(/\\\\/g, "\\")); configuration.forcedInclude = configuration.forcedInclude.map((path) => path.replace(/\\\\/g, "\\")); + configuration.defines = configuration.defines.map((path) => path.replace(/\\\\/g, "\\")); for (const libPath of libPaths) { if (configuration.includePath.indexOf(libPath) === -1) { @@ -343,6 +349,12 @@ export class ArduinoApp { } } + for (const define of defines) { + if (configuration.defines.indexOf(define) === -1) { + cppConfigFileUpdated = true; + configuration.defines.push(define); + } + } // remove all unexisting paths // concern mistake removal, comment temporary // for (let pathIndex = 0; pathIndex < configuration.includePath.length; pathIndex++) { @@ -386,6 +398,7 @@ export class ArduinoApp { } const defaultForcedInclude = this.getDefaultForcedIncludeFiles(); + const defaultDefines = this.getDefaultDefines(); if (!ArduinoWorkspace.rootPath) { return; @@ -444,6 +457,10 @@ export class ArduinoApp { configSection.forcedInclude = defaultForcedInclude.concat(configSection.forcedInclude); } + if (!configSection.defines) { + configSection.defines = defaultDefines; + } + fs.writeFileSync(configFilePath, JSON.stringify(deviceContext, null, 4)); } @@ -577,6 +594,16 @@ Please make sure the folder is not occupied by other procedures .`); } const toolsPath = boardDescriptor.platform.rootBoardPath; result.push(path.normalize(path.join(toolsPath, "**"))); + const hardwareToolPath = path.join(toolsPath, "..", "..", "tools"); + if (fs.existsSync(hardwareToolPath)) { + result.push(path.normalize(path.join(hardwareToolPath, "**"))); + } + + // Add default libraries to include path + result.push(path.normalize(path.join(this._settings.defaultLibPath, "**"))); + + const userLibsPath = (path.join(this._settings.sketchbookPath, "libraries", "**")); + result.push(userLibsPath); // if (util.directoryExistsSync(path.join(toolsPath, "cores"))) { // const coreLibs = fs.readdirSync(path.join(toolsPath, "cores")); // if (coreLibs && coreLibs.length > 0) { @@ -608,6 +635,13 @@ Please make sure the folder is not occupied by other procedures .`); return result; } + public getDefaultDefines(): string[] { + const result = []; + // USBCON is required in order for Serial to be recognized by intellisense + result.push("USBCON"); + return result; + } + public openExample(example) { function tmpName(name) { let counter = 0; From 3f58524ee1441d598d25b9edb520a3978b4f15c7 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Thu, 19 Nov 2020 19:52:56 -0800 Subject: [PATCH 07/13] pre release v0.3.4-rc2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 04bebafb..024d9794 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-arduino", "displayName": "Arduino", "description": "Arduino for Visual Studio Code", - "version": "0.3.4-rc", + "version": "0.3.4-rc2", "publisher": "vsciot-vscode", "aiKey": "83dd2c27-6594-41d3-85a9-bdb22070eb42", "preview": true, From 4efe14d2252f5aa718b790fa0057d8f513d6b313 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Sun, 22 Nov 2020 11:58:48 -0800 Subject: [PATCH 08/13] bump to v0.3.4 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 344c52e0..858ce039 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Change Log All notable changes to this project will be documented in this file. +## Version 0.3.4 + +- Release date: November 22, 2020 + +### Changed +- Add DTR and RTS signals on serial open and buad rate change +- Improves c_cpp_properties.json autogeneration for intelliSense + ## Version 0.3.3 - Release date: October 29, 2020 diff --git a/package.json b/package.json index 024d9794..0d526c16 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-arduino", "displayName": "Arduino", "description": "Arduino for Visual Studio Code", - "version": "0.3.4-rc2", + "version": "0.3.4", "publisher": "vsciot-vscode", "aiKey": "83dd2c27-6594-41d3-85a9-bdb22070eb42", "preview": true, From ae0ebd43ee4eab1bd8be1043c352197522edb2bf Mon Sep 17 00:00:00 2001 From: Giulio Date: Tue, 8 Dec 2020 00:41:05 +0100 Subject: [PATCH 09/13] Option to use arduino-cli instead of Arduino IDE (#1017) * Hardcoded Arduino-CLI commands for build and upload * Added menu checkbox for Arduino CLI - Upload with programmer is still not supported - Must be created an arduino symlink pointing to arduino-cli * If Arduino-CLI, check for arduino-cli instead of arduino. Not yet supported on Windows or MacOS * Typo * Fixed CI requests * Fixed CI requests * Update src/common/sys/darwin.ts MacOS patch for arduino-cli Co-authored-by: Marc Lage-Vianna * Update src/common/sys/win32.ts Windows patch for arduino-cli Co-authored-by: Marc Lage-Vianna * Trigger * add cli option in commandPath for win32 * add cli support to board and lib managers * rename isArduinoCli to useArduinoCli * adds support for uploading using programmer * simplify getProgrammer * add CLI upload * Update src/arduino/arduino.ts Co-authored-by: Jason Tranchida * refactor uploadUsingProgrammer * fix output path for CLI upload * Update package.json * update cli option text, thanks @maddogjt * update tests Co-authored-by: giuliof Co-authored-by: Marc Lage-Vianna Co-authored-by: Adi Azulay Co-authored-by: Adi Azulay Co-authored-by: Jason Tranchida --- package.json | 13 +++ src/arduino/arduino.ts | 161 +++++++++++++++---------------- src/arduino/arduinoSettings.ts | 10 +- src/arduino/programmerManager.ts | 34 ++++--- src/arduino/vscodeSettings.ts | 6 ++ src/common/platform.ts | 4 +- src/common/sys/darwin.ts | 5 +- src/common/sys/linux.ts | 4 +- src/common/sys/win32.ts | 5 +- src/common/util.ts | 7 ++ src/extension.ts | 37 ++++++- test/extension.test.ts | 2 + test/librarymanager.test.ts | 2 +- 13 files changed, 184 insertions(+), 106 deletions(-) diff --git a/package.json b/package.json index 0d526c16..20cf48a1 100644 --- a/package.json +++ b/package.json @@ -93,10 +93,18 @@ "light": "images/ArduinoUpload_16.svg" } }, + { + "command": "arduino.cliUpload", + "title": "Arduino CLI: Upload" + }, { "command": "arduino.uploadUsingProgrammer", "title": "Arduino: Upload Using Programmer" }, + { + "command": "arduino.cliUploadUsingProgrammer", + "title": "Arduino CLI: Upload Using Programmer" + }, { "command": "arduino.selectProgrammer", "title": "Arduino: Select Programmer" @@ -442,6 +450,11 @@ "type": "object", "title": "Arduino configuration", "properties": { + "arduino.useArduinoCli": { + "type": "boolean", + "default": false, + "markdownDescription": "Use Arduino CLI installed instead of Arduino IDE. `#arduino.path#` must be set, as there is no default path for 'arduino-cli'. (Requires a restart after change)" + }, "arduino.path": { "type": "string", "default": "", diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index 263a5069..5a59ca19 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -93,13 +93,23 @@ export class ArduinoApp { } } - public async upload() { + /** + * Upload code to selected board + * @param {bool} [compile=true] - Indicates whether to compile the code when using the CLI to upload + * @param {bool} [useProgrammer=false] - Indicate whether a specific programmer should be used + */ + public async upload(compile: boolean = true, useProgrammer: boolean = false) { const dc = DeviceContext.getInstance(); const boardDescriptor = this.getBoardBuildString(); if (!boardDescriptor) { return; } + const selectProgrammer = useProgrammer ? this.getProgrammerString() : null; + if (useProgrammer && !selectProgrammer) { + return; + } + if (!ArduinoWorkspace.rootPath) { vscode.window.showWarningMessage("Cannot find the sketch file."); return; @@ -140,8 +150,25 @@ export class ArduinoApp { } } + if (!compile && !this.useArduinoCli()) { + arduinoChannel.error("This command is only availble when using the Arduino CLI"); + return; + } + const appPath = path.join(ArduinoWorkspace.rootPath, dc.sketch); - const args = ["--upload", "--board", boardDescriptor]; + // TODO: add the --clean argument to the cli args when v 0.14 is released (this will clean up the build folder after uploading) + const args = (!compile && this.useArduinoCli()) ? ["upload", "-b", boardDescriptor] : + this.useArduinoCli() ? ["compile", "--upload", "-b", boardDescriptor] : + ["--upload", "--board", boardDescriptor]; + + if (useProgrammer) { + if (this.useArduinoCli()) { + args.push("--programmer", selectProgrammer) + } else { + args.push("--useprogrammer", "--pref", "programmer=" + selectProgrammer) + } + } + if (dc.port) { args.push("--port", dc.port); } @@ -149,7 +176,7 @@ export class ArduinoApp { if (VscodeSettings.getInstance().logLevel === "verbose") { args.push("--verbose"); } - if (dc.output) { + if (dc.output && compile) { const outputPath = path.resolve(ArduinoWorkspace.rootPath, dc.output); const dirPath = path.dirname(outputPath); if (!util.directoryExistsSync(dirPath)) { @@ -157,77 +184,13 @@ export class ArduinoApp { return; } - args.push("--pref", `build.path=${outputPath}`); - arduinoChannel.info(`Please see the build logs in Output path: ${outputPath}`); - } else { - const msg = "Output path is not specified. Unable to reuse previously compiled files. Upload could be slow. See README."; - arduinoChannel.warning(msg); - } - await util.spawn(this._settings.commandPath, arduinoChannel.channel, args).then(async () => { - UsbDetector.getInstance().resumeListening(); - if (needRestore) { - await serialMonitor.openSerialMonitor(); - } - arduinoChannel.end(`Uploaded the sketch: ${dc.sketch}${os.EOL}`); - }, (reason) => { - arduinoChannel.error(`Exit with code=${reason.code}${os.EOL}`); - }); - } - - public async uploadUsingProgrammer() { - const dc = DeviceContext.getInstance(); - const boardDescriptor = this.getBoardBuildString(); - if (!boardDescriptor) { - return; - } - - const selectProgrammer = this.getProgrammerString(); - if (!selectProgrammer) { - return; - } + if (this.useArduinoCli()) { + args.push("--build-path", outputPath); - if (!ArduinoWorkspace.rootPath) { - vscode.window.showWarningMessage("Cannot find the sketch file."); - return; - } - - if (!dc.sketch || !util.fileExistsSync(path.join(ArduinoWorkspace.rootPath, dc.sketch))) { - await this.getMainSketch(dc); - } - if (!dc.port) { - const choice = await vscode.window.showInformationMessage( - "Serial port is not specified. Do you want to select a serial port for uploading?", - "Yes", "No"); - if (choice === "Yes") { - vscode.commands.executeCommand("arduino.selectSerialPort"); - } - return; - } - - arduinoChannel.show(); - arduinoChannel.start(`Upload sketch - ${dc.sketch}`); - - const serialMonitor = SerialMonitor.getInstance(); - - const needRestore = await serialMonitor.closeSerialMonitor(dc.port); - UsbDetector.getInstance().pauseListening(); - await vscode.workspace.saveAll(false); - - const appPath = path.join(ArduinoWorkspace.rootPath, dc.sketch); - const args = ["--upload", "--board", boardDescriptor, "--port", dc.port, "--useprogrammer", - "--pref", "programmer=" + selectProgrammer, appPath]; - if (VscodeSettings.getInstance().logLevel === "verbose") { - args.push("--verbose"); - } - if (dc.output) { - const outputPath = path.resolve(ArduinoWorkspace.rootPath, dc.output); - const dirPath = path.dirname(outputPath); - if (!util.directoryExistsSync(dirPath)) { - Logger.notifyUserError("InvalidOutPutPath", new Error(constants.messages.INVALID_OUTPUT_PATH + outputPath)); - return; + } else { + args.push("--pref", `build.path=${outputPath}`); } - args.push("--pref", `build.path=${outputPath}`); arduinoChannel.info(`Please see the build logs in Output path: ${outputPath}`); } else { const msg = "Output path is not specified. Unable to reuse previously compiled files. Upload could be slow. See README."; @@ -277,7 +240,7 @@ export class ArduinoApp { } const appPath = path.join(ArduinoWorkspace.rootPath, dc.sketch); - const args = ["--verify", "--board", boardDescriptor, appPath]; + const args = this.useArduinoCli() ? ["compile", "-b", boardDescriptor, appPath] : ["--verify", "--board", boardDescriptor, appPath]; if (VscodeSettings.getInstance().logLevel === "verbose") { args.push("--verbose"); } @@ -289,7 +252,13 @@ export class ArduinoApp { return; } - args.push("--pref", `build.path=${outputPath}`); + if (this.useArduinoCli()) { + args.push("--build-path", outputPath); + + } else { + args.push("--pref", `build.path=${outputPath}`); + } + arduinoChannel.info(`Please see the build logs in Output path: ${outputPath}`); } else { const msg = "Output path is not specified. Unable to reuse previously compiled files. Verify could be slow. See README."; @@ -495,9 +464,14 @@ export class ArduinoApp { } } - /** - * Install arduino board package based on package name and platform hardware architecture. - */ + /** + * Installs arduino board package. + * (If using the aduino CLI this installs the corrosponding core.) + * @param {string} packageName - board vendor + * @param {string} arch - board architecture + * @param {string} version - version of board package or core to download + * @param {boolean} [showOutput=true] - show raw output from command + */ public async installBoard(packageName: string, arch: string = "", version: string = "", showOutput: boolean = true) { arduinoChannel.show(); const updatingIndex = packageName === "dummy" && !arch && !version; @@ -505,23 +479,28 @@ export class ArduinoApp { arduinoChannel.start(`Update package index files...`); } else { try { - const packagePath = path.join(this._settings.packagePath, "packages", packageName); + const packagePath = path.join(this._settings.packagePath, "packages", packageName, arch); if (util.directoryExistsSync(packagePath)) { util.rmdirRecursivelySync(packagePath); } arduinoChannel.start(`Install package - ${packageName}...`); } catch (error) { arduinoChannel.start(`Install package - ${packageName} failed under directory : ${error.path}${os.EOL} -Please make sure the folder is not occupied by other procedures .`); + Please make sure the folder is not occupied by other procedures .`); arduinoChannel.error(`Error message - ${error.message}${os.EOL}`); arduinoChannel.error(`Exit with code=${error.code}${os.EOL}`); return; } } + arduinoChannel.info(`${packageName}${arch && ":" + arch}${version && ":" + version}`); try { - await util.spawn(this._settings.commandPath, - showOutput ? arduinoChannel.channel : null, - ["--install-boards", `${packageName}${arch && ":" + arch}${version && ":" + version}`]); + this.useArduinoCli() ? + await util.spawn(this._settings.commandPath, + showOutput ? arduinoChannel.channel : null, + ["core", "install", `${packageName}${arch && ":" + arch}${version && "@" + version}`]) : + await util.spawn(this._settings.commandPath, + showOutput ? arduinoChannel.channel : null, + ["--install-boards", `${packageName}${arch && ":" + arch}${version && ":" + version}`]); if (updatingIndex) { arduinoChannel.end("Updated package index files."); @@ -548,6 +527,13 @@ Please make sure the folder is not occupied by other procedures .`); arduinoChannel.end(`Uninstalled board package - ${boardName}${os.EOL}`); } + /** + * Downloads or updates a library + * @param {string} libName - name of the library to download + * @param {string} version - version of library to download + * @param {boolean} [showOutput=true] - show raw output from command + */ + public async installLibrary(libName: string, version: string = "", showOutput: boolean = true) { arduinoChannel.show(); const updatingIndex = (libName === "dummy" && !version); @@ -557,6 +543,10 @@ Please make sure the folder is not occupied by other procedures .`); arduinoChannel.start(`Install library - ${libName}`); } try { + this.useArduinoCli() ? + await util.spawn(this._settings.commandPath, + showOutput ? arduinoChannel.channel : null, + ["lib", "install", `${libName}${version && "@" + version}`]) : await util.spawn(this._settings.commandPath, showOutput ? arduinoChannel.channel : null, ["--install-library", `${libName}${version && ":" + version}`]); @@ -769,6 +759,15 @@ Please make sure the folder is not occupied by other procedures .`); this._programmerManager = value; } + /** + * Checks if the arduino cli is being used + * @returns {bool} - true if arduino cli is being use + */ + private useArduinoCli() { + return this._settings.useArduinoCli; + // return VscodeSettings.getInstance().useArduinoCli; + } + private getProgrammerString(): string { const selectProgrammer = this.programmerManager.currentProgrammer; if (!selectProgrammer) { diff --git a/src/arduino/arduinoSettings.ts b/src/arduino/arduinoSettings.ts index 58419519..8d994d81 100644 --- a/src/arduino/arduinoSettings.ts +++ b/src/arduino/arduinoSettings.ts @@ -22,6 +22,7 @@ export interface IArduinoSettings { preferencePath: string; defaultBaudRate: number; preferences: Map; + useArduinoCli: boolean; reloadPreferences(): void; } @@ -38,18 +39,21 @@ export class ArduinoSettings implements IArduinoSettings { private _preferences: Map; + private _useArduinoCli: boolean; + public constructor() { } public async initialize() { const platform = os.platform(); this._commandPath = VscodeSettings.getInstance().commandPath; + this._useArduinoCli = VscodeSettings.getInstance().useArduinoCli; await this.tryResolveArduinoPath(); await this.tryGetDefaultBaudRate(); if (platform === "win32") { await this.updateWindowsPath(); if (this._commandPath === "") { - this._commandPath = "arduino_debug.exe"; + this._useArduinoCli ? this._commandPath = "arduino-cli.exe" : this._commandPath = "arduino_debug.exe"; } } else if (platform === "linux") { if (util.directoryExistsSync(path.join(this._arduinoPath, "portable"))) { @@ -150,6 +154,10 @@ export class ArduinoSettings implements IArduinoSettings { return this._preferences; } + public get useArduinoCli() { + return this._useArduinoCli; + } + public get defaultBaudRate() { return this._defaultBaudRate; } diff --git a/src/arduino/programmerManager.ts b/src/arduino/programmerManager.ts index a060f211..eee12725 100644 --- a/src/arduino/programmerManager.ts +++ b/src/arduino/programmerManager.ts @@ -58,46 +58,54 @@ export class ProgrammerManager { dc.programmer = chosen; } + /** + * Gets a specific programmer from the programmers list. + * If using the Arduino IDE, adds prefix "adruino:" + * @param {ProgrammerList} newProgrammer - a list of the available programmers + */ public getProgrammer(newProgrammer: ProgrammerList) { + let prefix = ""; + if (!this._settings.useArduinoCli) { + prefix = "arduino:"}; switch (newProgrammer) { case ProgrammerList["AVR ISP"]: - this._programmervalue = "arduino:avrisp"; + this._programmervalue = prefix + "avrisp"; break; case ProgrammerList["AVRISP mkII"]: - this._programmervalue = "arduino:avrispmkii"; + this._programmervalue = prefix + "avrispmkii"; break; case ProgrammerList.USBtinyISP: - this._programmervalue = "arduino:usbtinyisp"; + this._programmervalue = prefix + "usbtinyisp"; break; case ProgrammerList.ArduinoISP: - this._programmervalue = "arduino:arduinoisp"; + this._programmervalue = prefix + "arduinoisp"; break; case ProgrammerList.USBasp: - this._programmervalue = "arduino:usbasp"; + this._programmervalue = prefix + "usbasp"; break; case ProgrammerList["Parallel Programmer"]: - this._programmervalue = "arduino:parallel"; + this._programmervalue = prefix + "parallel"; break; case ProgrammerList["Arduino as ISP"]: - this._programmervalue = "arduino:arduinoasisp"; + this._programmervalue = prefix + "arduinoasisp"; break; case ProgrammerList["Arduino Gemma"]: - this._programmervalue = "arduino:usbGemma"; + this._programmervalue = prefix + "usbGemma"; break; case ProgrammerList["BusPirate as ISP"]: - this._programmervalue = "arduino:buspirate"; + this._programmervalue = prefix + "buspirate"; break; case ProgrammerList["Atmel STK500 development board"]: - this._programmervalue = "arduino:stk500"; + this._programmervalue = prefix + "stk500"; break; case ProgrammerList["Atmel JTAGICE3 (ISP mode)"]: - this._programmervalue = "arduino:jtag3isp"; + this._programmervalue = prefix + "jtag3isp"; break; case ProgrammerList["Atmel JTAGICE3 (JTAG mode)"]: - this._programmervalue = "arduino:jtag3"; + this._programmervalue = prefix + "jtag3"; break; case ProgrammerList["Atmel-ICE (AVR)"]: - this._programmervalue = "arduino:atmel_ice"; + this._programmervalue = prefix + "atmel_ice"; break; default: break; diff --git a/src/arduino/vscodeSettings.ts b/src/arduino/vscodeSettings.ts index f66e268b..14726cd8 100644 --- a/src/arduino/vscodeSettings.ts +++ b/src/arduino/vscodeSettings.ts @@ -15,6 +15,7 @@ const configKeys = { IGNORE_BOARDS: "arduino.ignoreBoards", SKIP_HEADER_PROVIDER: "arduino.skipHeaderProvider", DEFAULT_BAUD_RATE: "arduino.defaultBaudRate", + USE_ARDUINO_CLI: "arduino.useArduinoCli", }; export interface IVscodeSettings { @@ -28,6 +29,7 @@ export interface IVscodeSettings { ignoreBoards: string[]; skipHeaderProvider: boolean; defaultBaudRate: number; + useArduinoCli: boolean; updateAdditionalUrls(urls: string | string[]): void; } @@ -83,6 +85,10 @@ export class VscodeSettings implements IVscodeSettings { return this.getConfigValue(configKeys.DEFAULT_BAUD_RATE); } + public get useArduinoCli(): boolean { + return this.getConfigValue(configKeys.USE_ARDUINO_CLI); + } + public get skipHeaderProvider(): boolean { return this.getConfigValue(configKeys.SKIP_HEADER_PROVIDER); } diff --git a/src/common/platform.ts b/src/common/platform.ts index aa17cadf..1675c8b0 100644 --- a/src/common/platform.ts +++ b/src/common/platform.ts @@ -14,8 +14,8 @@ export function resolveArduinoPath(): string { return internalSysLib.resolveArduinoPath(); } -export function validateArduinoPath(arduinoPath: string): boolean { - return internalSysLib.validateArduinoPath(arduinoPath); +export function validateArduinoPath(arduinoPath: string, useArduinoCli = false): boolean { + return internalSysLib.validateArduinoPath(arduinoPath, useArduinoCli); } export function findFile(fileName: string, cwd: string): string { diff --git a/src/common/sys/darwin.ts b/src/common/sys/darwin.ts index 235aaf38..4d5c7e98 100644 --- a/src/common/sys/darwin.ts +++ b/src/common/sys/darwin.ts @@ -18,8 +18,9 @@ export function resolveArduinoPath(): string { return result || ""; } -export function validateArduinoPath(arduinoPath: string): boolean { - return fileExistsSync(path.join(resolveMacArduinoAppPath(arduinoPath), "/Contents/MacOS/Arduino")); +export function validateArduinoPath(arduinoPath: string, useArduinoCli = false): boolean { + return fileExistsSync(path.join(resolveMacArduinoAppPath(arduinoPath), useArduinoCli ? "arduino-cli" : "/Contents/MacOS/Arduino")); + } export function findFile(fileName: string, cwd: string): string { diff --git a/src/common/sys/linux.ts b/src/common/sys/linux.ts index 6c9189d7..fbb904b4 100644 --- a/src/common/sys/linux.ts +++ b/src/common/sys/linux.ts @@ -20,8 +20,8 @@ export function resolveArduinoPath(): string { return pathString || ""; } -export function validateArduinoPath(arduinoPath: string): boolean { - return fileExistsSync(path.join(arduinoPath, "arduino")); +export function validateArduinoPath(arduinoPath: string, useArduinoCli = false): boolean { + return fileExistsSync(path.join(arduinoPath, useArduinoCli ? "arduino-cli" : "arduino")); } export function findFile(fileName: string, cwd: string): string { diff --git a/src/common/sys/win32.ts b/src/common/sys/win32.ts index dbbbaaac..ad237e27 100644 --- a/src/common/sys/win32.ts +++ b/src/common/sys/win32.ts @@ -27,8 +27,9 @@ export async function resolveArduinoPath() { return pathString; } -export function validateArduinoPath(arduinoPath: string): boolean { - return fileExistsSync(path.join(arduinoPath, "arduino_debug.exe")); +export function validateArduinoPath(arduinoPath: string, useArduinoCli = false): boolean { + return fileExistsSync(path.join(arduinoPath, useArduinoCli ? "arduino-cli.exe" : "arduino_debug.exe")); + } export function findFile(fileName: string, cwd: string): string { diff --git a/src/common/util.ts b/src/common/util.ts index 2af4b83b..696c99ea 100644 --- a/src/common/util.ts +++ b/src/common/util.ts @@ -200,6 +200,13 @@ export function isArduinoFile(filePath): boolean { return fileExistsSync(filePath) && (path.extname(filePath) === ".ino" || path.extname(filePath) === ".pde"); } +/** + * Send a command to arduino + * @param {string} command - base command path (either Arduino IDE or CLI) + * @param {vscode.OutputChannel} outputChannel - output display channel + * @param {string[]} [args=[]] - arguments to pass to the command + * @param {any} [options={}] - options and flags for the arguments + */ export function spawn(command: string, outputChannel: vscode.OutputChannel, args: string[] = [], options: any = {}): Thenable { return new Promise((resolve, reject) => { const stdout = ""; diff --git a/src/extension.ts b/src/extension.ts index c4112bd7..b6cf7a78 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -91,7 +91,9 @@ export async function activate(context: vscode.ExtensionContext) { const arduinoPath = arduinoContextModule.default.arduinoApp.settings.arduinoPath; const commandPath = arduinoContextModule.default.arduinoApp.settings.commandPath; - if (!arduinoPath || !validateArduinoPath(arduinoPath)) { // Pop up vscode User Settings page when cannot resolve arduino path. + const useArduinoCli = arduinoContextModule.default.arduinoApp.settings.useArduinoCli; + // Pop up vscode User Settings page when cannot resolve arduino path. + if (!arduinoPath || !validateArduinoPath(arduinoPath, useArduinoCli)) { Logger.notifyUserError("InvalidArduinoPath", new Error(constants.messages.INVALID_ARDUINO_PATH)); vscode.commands.executeCommand("workbench.action.openGlobalSettings"); } else if (!commandPath || !util.fileExistsSync(commandPath)) { @@ -152,6 +154,24 @@ export async function activate(context: vscode.ExtensionContext) { return { board: arduinoContextModule.default.boardManager.currentBoard.name }; }); + registerArduinoCommand("arduino.cliUpload", async () => { + if (!status.compile) { + status.compile = "cliUpload"; + try { + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Window, + title: "Arduino: Using CLI to upload...", + }, async () => { + await arduinoContextModule.default.arduinoApp.upload(false); + }); + } catch (ex) { + } + delete status.compile; + } + }, () => { + return { board: arduinoContextModule.default.boardManager.currentBoard.name }; + }); + registerArduinoCommand("arduino.setSketchFile", async () => { const sketchFileName = deviceContext.sketch; const newSketchFileName = await vscode.window.showInputBox({ @@ -177,7 +197,20 @@ export async function activate(context: vscode.ExtensionContext) { if (!status.compile) { status.compile = "upload"; try { - await arduinoContextModule.default.arduinoApp.uploadUsingProgrammer(); + await arduinoContextModule.default.arduinoApp.upload(true, true); + } catch (ex) { + } + delete status.compile; + } + }, () => { + return { board: arduinoContextModule.default.boardManager.currentBoard.name }; + }); + + registerArduinoCommand("arduino.cliUploadUsingProgrammer", async () => { + if (!status.compile) { + status.compile = "cliUpload"; + try { + await arduinoContextModule.default.arduinoApp.upload(false, true); } catch (ex) { } delete status.compile; diff --git a/test/extension.test.ts b/test/extension.test.ts index e1a8de12..9c56fc41 100644 --- a/test/extension.test.ts +++ b/test/extension.test.ts @@ -55,6 +55,8 @@ suite("Arduino: Extension Tests", () => { "arduino.loadPackages", "arduino.installBoard", "arduino.setSketchFile", + "arduino.cliUpload", + "arduino.cliUploadUsingProgrammer", ]; const foundArduinoCommands = commands.filter((value) => { diff --git a/test/librarymanager.test.ts b/test/librarymanager.test.ts index 7e43af26..5ff5cc84 100644 --- a/test/librarymanager.test.ts +++ b/test/librarymanager.test.ts @@ -79,7 +79,7 @@ suite("Arduino: Library Manager.", () => { if (util.directoryExistsSync(libPath)) { done(); } else { - done(new Error("AzureIoTHub library install failure, can't find library path :" + libPath)); + done(new Error("AzureIoTHub library install failure, can't find library path: " + libPath)); } }); From d6459d0b8cbfbbaabe55f85c18178344b232ed9b Mon Sep 17 00:00:00 2001 From: Jason Tranchida Date: Tue, 8 Dec 2020 13:19:45 -0800 Subject: [PATCH 10/13] Improved handling of programmer selection (#1118) * Improved handling of programmer selection - Selected programmer is now saved to and loaded from the arduino.json file - Arduino.json is monitored for changes, and changing file will update selected programmer & ui - Programmer selection UI now shows both the friendly name of the programmer, as well as the arduino name - Minor fix to deviceContexts to fire change events after all states are modified - Layed groundwork to support querying list of programmers for the current board from arduino toolchain * fix dtr on serial open * fix dtr on serial open * fix linting * pre release v0.3.4 * Add RTS signal on serial open, Add baudrates up to 2000000 (#1142) * add buad rates up to 2M * add rts signal on serial open and buad rate change * add missing space in baud rate array * Quick fix for Intellisense (#1144) * add hardware tool path * intellisense quick fix * add hardware tool path * intellisense quick fix * fix typo * pre release v0.3.4-rc2 * bump to v0.3.4 * Option to use arduino-cli instead of Arduino IDE (#1017) * Hardcoded Arduino-CLI commands for build and upload * Added menu checkbox for Arduino CLI - Upload with programmer is still not supported - Must be created an arduino symlink pointing to arduino-cli * If Arduino-CLI, check for arduino-cli instead of arduino. Not yet supported on Windows or MacOS * Typo * Fixed CI requests * Fixed CI requests * Update src/common/sys/darwin.ts MacOS patch for arduino-cli Co-authored-by: Marc Lage-Vianna * Update src/common/sys/win32.ts Windows patch for arduino-cli Co-authored-by: Marc Lage-Vianna * Trigger * add cli option in commandPath for win32 * add cli support to board and lib managers * rename isArduinoCli to useArduinoCli * adds support for uploading using programmer * simplify getProgrammer * add CLI upload * Update src/arduino/arduino.ts Co-authored-by: Jason Tranchida * refactor uploadUsingProgrammer * fix output path for CLI upload * Update package.json * update cli option text, thanks @maddogjt * update tests Co-authored-by: giuliof Co-authored-by: Marc Lage-Vianna Co-authored-by: Adi Azulay Co-authored-by: Adi Azulay Co-authored-by: Jason Tranchida * Improved handling of programmer selection - Selected programmer is now saved to and loaded from the arduino.json file - Arduino.json is monitored for changes, and changing file will update selected programmer & ui - Programmer selection UI now shows both the friendly name of the programmer, as well as the arduino name - Minor fix to deviceContexts to fire change events after all states are modified - Layed groundwork to support querying list of programmers for the current board from arduino toolchain * add cli suppport for programmers * add documentation Co-authored-by: Marc Goodner Co-authored-by: Adi Azulay Co-authored-by: Giulio Co-authored-by: giuliof Co-authored-by: Marc Lage-Vianna Co-authored-by: Adi Azulay --- package-lock.json | 2 +- src/arduino/arduino.ts | 2 +- src/arduino/programmerManager.ts | 135 ++++++++++++------------------- src/deviceContext.ts | 6 +- 4 files changed, 56 insertions(+), 89 deletions(-) diff --git a/package-lock.json b/package-lock.json index d72659ed..a7a49f3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vscode-arduino", - "version": "0.3.3", + "version": "0.3.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index 5a59ca19..a4b9b1aa 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -165,7 +165,7 @@ export class ArduinoApp { if (this.useArduinoCli()) { args.push("--programmer", selectProgrammer) } else { - args.push("--useprogrammer", "--pref", "programmer=" + selectProgrammer) + args.push("--useprogrammer", "--pref", "programmer=arduino:" + selectProgrammer) } } diff --git a/src/arduino/programmerManager.ts b/src/arduino/programmerManager.ts index eee12725..08d3a425 100644 --- a/src/arduino/programmerManager.ts +++ b/src/arduino/programmerManager.ts @@ -4,111 +4,78 @@ import { DeviceContext } from "../deviceContext"; import { ArduinoApp } from "./arduino"; import { IArduinoSettings } from "./arduinoSettings"; -export enum ProgrammerList { - "AVR ISP", - "AVRISP mkII", - "USBtinyISP", - "ArduinoISP", - "ArduinoISP.org", - "USBasp", - "Parallel Programmer", - "Arduino as ISP", - "Arduino Gemma", - "BusPirate as ISP", - "Atmel STK500 development board", - "Atmel JTAGICE3 (ISP mode)", - "Atmel JTAGICE3 (JTAG mode)", - "Atmel-ICE (AVR)", -} - export class ProgrammerManager { - - private static _programmerManager: ProgrammerManager = null; - - private _currentprogrammer: ProgrammerList; - private _programmervalue: string; private _programmerStatusBar: vscode.StatusBarItem; + // Static list of 'available' programmers. This should be repopulated by the currently selected board type. + private _availableProgrammers = { + avrisp: "AVR ISP", + avrispmkii: "AVRISP mkII", + usbtinyisp: "USBtinyISP", + arduinoisp: "ArduinoISP", + usbasp: "USBasp", + parallel: "Parallel Programmer", + arduinoasisp: "Arduino as ISP", + usbGemma: "Arduino Gemma", + buspirate: "BusPirate as ISP", + stk500: "Atmel STK500 development board", + jtag3isp: "Atmel JTAGICE3 (ISP mode)", + jtag3: "Atmel JTAGICE3 (JTAG mode)", + atmel_ice: "Atmel-ICE (AVR)", + }; + constructor(private _settings: IArduinoSettings, private _arduinoApp: ArduinoApp) { - this._programmerStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, constants.statusBarPriority.PROGRAMMER); + this._programmerStatusBar = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Right, + constants.statusBarPriority.PROGRAMMER, + ); this._programmerStatusBar.command = "arduino.selectProgrammer"; this._programmerStatusBar.tooltip = "Select Programmer"; - this._programmerStatusBar.text = ""; + } + + private getFriendlyName(programmer: string): string { + const friendlyName = this._availableProgrammers[programmer]; + return friendlyName ? friendlyName : programmer; } } diff --git a/src/deviceContext.ts b/src/deviceContext.ts index 2e7f18e3..5e24aea1 100644 --- a/src/deviceContext.ts +++ b/src/deviceContext.ts @@ -151,9 +151,9 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { this._configuration = deviceConfigJson.configuration; this._output = deviceConfigJson.output; this._debugger = deviceConfigJson["debugger"]; - this._onDidChange.fire(); this._prebuild = deviceConfigJson.prebuild; this._programmer = deviceConfigJson.programmer; + this._onDidChange.fire(); } else { Logger.notifyUserError("arduinoFileError", new Error(constants.messages.ARDUINO_FILE_ERROR)); } @@ -164,9 +164,9 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { this._configuration = null; this._output = null; this._debugger = null; - this._onDidChange.fire(); this._prebuild = null; this._programmer = null; + this._onDidChange.fire(); } return this; }, (reason) => { @@ -182,9 +182,9 @@ export class DeviceContext implements IDeviceContext, vscode.Disposable { this._configuration = null; this._output = null; this._debugger = null; - this._onDidChange.fire(); this._prebuild = null; this._programmer = null; + this._onDidChange.fire(); return this; }); From 313d0cb2908e351277036d036ff0e1d89297affc Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Thu, 10 Dec 2020 13:14:51 -0500 Subject: [PATCH 11/13] package-lock update --- package-lock.json | 127 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 103 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index d72659ed..7d2b9b09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -214,8 +214,7 @@ "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, "@types/compare-versions": { "version": "3.3.0", @@ -480,15 +479,15 @@ } }, "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "json-schema-traverse": "^0.3.0" } }, "ajv-errors": { @@ -541,7 +540,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -551,7 +549,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -559,8 +556,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" } } }, @@ -1556,6 +1552,38 @@ "semver": "^5.4.1" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "cocopa": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/cocopa/-/cocopa-0.0.13.tgz", + "integrity": "sha512-MKWdCbaC9MpT+CMNXRP2rufpIndIaCKY1KD3XXwg6I2jNI1uFjEKNGXObL1mJ+7X53FTzKaZydJbPinCG+WJTQ==", + "requires": { + "chalk": "^3.0.0", + "commander": "^4.1.1", + "shlex": "^2.0.1" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + } + } + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -2424,6 +2452,18 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -2439,6 +2479,12 @@ "ms": "^2.1.1" } }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", @@ -2454,6 +2500,12 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2939,9 +2991,9 @@ } }, "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "fast-json-stable-stringify": { @@ -5467,9 +5519,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", "dev": true }, "json-stable-stringify-without-jsonify": { @@ -7642,6 +7694,11 @@ "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" }, + "shlex": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/shlex/-/shlex-2.0.2.tgz", + "integrity": "sha512-i4p9nNXgBTILspHwZlBCNsZzwuVWW8SFx5dyIONrjL0R+AbMOPbg7ndqgGfjYivkYRTtZMKqIT8HT+QyOhPQWA==" + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -8095,7 +8152,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" }, @@ -8103,8 +8159,7 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" } } }, @@ -8130,6 +8185,18 @@ "string-width": "^3.0.0" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -8142,12 +8209,24 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -8538,9 +8617,9 @@ } }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "dev": true }, "unc-path-regex": { From 45aa5dbc3696d55eb88b0d382e99a534f9a2b0d9 Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Thu, 10 Dec 2020 15:53:53 -0500 Subject: [PATCH 12/13] add support for cli --- src/arduino/arduino.ts | 17 +++++++++++------ src/arduino/programmerManager.ts | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index 66e7443f..a3f40faf 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -516,6 +516,9 @@ export class ArduinoApp { } const boardDescriptor = this.boardManager.currentBoard.getBuildConfig(); + if (mode === BuildMode.Analyze) { + args.push("compile"); + } this._settings.useArduinoCli ? args.push("-b", boardDescriptor) : args.push("--board", boardDescriptor); if (!ArduinoWorkspace.rootPath) { @@ -626,9 +629,8 @@ export class ArduinoApp { } // We always build verbosely but filter the output based on the settings - if (!this._settings.useArduinoCli) { - args.push("--verbose-build"); - } + + this._settings.useArduinoCli ? args.push("--verbose") : args.push("--verbose-build"); if (verbose) { this._settings.useArduinoCli ? args.push ("--verbose") : args.push("--verbose-upload"); @@ -675,13 +677,16 @@ export class ArduinoApp { // TODO EW: What should we do with pre-/post build commands when running // analysis? Some could use it to generate/manipulate code which could // be a prerequisite for a successful build - if (!await this.runPrePostBuildCommand(dc, env, "pre")) { + if (dc.prebuild && !await this.runPrePostBuildCommand(dc, env, "pre")) { return false; } // stop serial monitor when everything is prepared and good // what makes restoring of its previous state easier - if (mode === BuildMode.Upload || mode === BuildMode.UploadProgrammer) { + if (mode === BuildMode.Upload || + mode === BuildMode.UploadProgrammer || + mode === BuildMode.CliUpload || + mode === BuildMode.CliUploadProgrammer) { restoreSerialMonitor = await SerialMonitor.getInstance().closeSerialMonitor(dc.port); UsbDetector.getInstance().pauseListening(); } @@ -744,7 +749,7 @@ export class ArduinoApp { this._settings.commandPath, args, undefined, - { stdout: stdoutcb, stderr: stderrcb }, + { channel: arduinoChannel.channel, stdout: stdoutcb, stderr: stderrcb }, ).then(async () => { const ret = await cleanup("ok"); if (ret) { diff --git a/src/arduino/programmerManager.ts b/src/arduino/programmerManager.ts index 08d3a425..7a7e2991 100644 --- a/src/arduino/programmerManager.ts +++ b/src/arduino/programmerManager.ts @@ -35,7 +35,7 @@ export class ProgrammerManager { this._programmerStatusBar.tooltip = "Select Programmer"; this.setProgrammerValue(DeviceContext.getInstance().programmer); this._programmerStatusBar.show(); - DeviceContext.getInstance().onDidChange(() => { + DeviceContext.getInstance().onChangeProgrammer(() => { this.setProgrammerValue(DeviceContext.getInstance().programmer); }); } From 7825a46e117d22eb516d7876eac5da496990d7ca Mon Sep 17 00:00:00 2001 From: Adi Azulay Date: Thu, 10 Dec 2020 16:41:17 -0500 Subject: [PATCH 13/13] fix cli analyze mode --- src/arduino/arduino.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/arduino/arduino.ts b/src/arduino/arduino.ts index a3f40faf..62a6d0a2 100644 --- a/src/arduino/arduino.ts +++ b/src/arduino/arduino.ts @@ -516,9 +516,6 @@ export class ArduinoApp { } const boardDescriptor = this.boardManager.currentBoard.getBuildConfig(); - if (mode === BuildMode.Analyze) { - args.push("compile"); - } this._settings.useArduinoCli ? args.push("-b", boardDescriptor) : args.push("--board", boardDescriptor); if (!ArduinoWorkspace.rootPath) { @@ -616,7 +613,7 @@ export class ArduinoApp { "--port", dc.port); } else { - args.push("--verify"); + this._settings.useArduinoCli ? args.unshift("compile") : args.push("--verify"); } // TODO: Option to add prefrences when using the CLI @@ -749,7 +746,7 @@ export class ArduinoApp { this._settings.commandPath, args, undefined, - { channel: arduinoChannel.channel, stdout: stdoutcb, stderr: stderrcb }, + { /*channel: arduinoChannel.channel,*/ stdout: stdoutcb, stderr: stderrcb }, ).then(async () => { const ret = await cleanup("ok"); if (ret) {