Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Option to use arduino-cli instead of Arduino IDE #1017

Merged
merged 26 commits into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
20f5d3e
Hardcoded Arduino-CLI commands for build and upload
Apr 6, 2020
f26be79
Added menu checkbox for Arduino CLI
giuliof Apr 6, 2020
841a811
If Arduino-CLI, check for arduino-cli instead of arduino.
giuliof Apr 6, 2020
af86a19
Typo
giuliof Apr 10, 2020
a2d327f
Fixed CI requests
giuliof Apr 10, 2020
7b55f03
Fixed CI requests
giuliof Apr 10, 2020
8865b04
Merge branch 'develop' into testing/arduino-cli
giuliof Apr 21, 2020
b70a95e
Merge branch 'develop' into testing/arduino-cli
giuliof Jul 5, 2020
64d835b
Update src/common/sys/darwin.ts
giuliof Sep 16, 2020
5d1c538
Update src/common/sys/win32.ts
giuliof Sep 16, 2020
4b8053e
Merge branch 'develop' into testing/arduino-cli
giuliof Sep 16, 2020
806fe32
Trigger
giuliof Sep 22, 2020
8715854
add cli option in commandPath for win32
adiazulay Dec 1, 2020
8631e42
add cli support to board and lib managers
adiazulay Dec 3, 2020
b80f803
rename isArduinoCli to useArduinoCli
adiazulay Dec 3, 2020
a7e0561
adds support for uploading using programmer
adiazulay Dec 4, 2020
93e93a2
simplify getProgrammer
adiazulay Dec 4, 2020
87c9c35
add CLI upload
adiazulay Dec 7, 2020
2a38235
Update src/arduino/arduino.ts
adiazulay Dec 7, 2020
bc98e2d
Merge branch 'testing/arduino-cli' of https://github.com/giuliof/vsco…
adiazulay Dec 7, 2020
f0f4485
refactor uploadUsingProgrammer
adiazulay Dec 7, 2020
60b9823
fix output path for CLI upload
adiazulay Dec 7, 2020
170dd6f
Update package.json
adiazulay Dec 7, 2020
198d649
update cli option text, thanks @maddogjt
adiazulay Dec 7, 2020
f50ac5f
Merge branch 'develop' into testing/arduino-cli
adiazulay Dec 7, 2020
719ab07
update tests
adiazulay Dec 7, 2020
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
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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": "",
Expand Down
161 changes: 80 additions & 81 deletions src/arduino/arduino.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -140,94 +150,47 @@ 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);
}
args.push(appPath);
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)) {
Logger.notifyUserError("InvalidOutPutPath", new Error(constants.messages.INVALID_OUTPUT_PATH + outputPath));
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.";
Expand Down Expand Up @@ -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");
}
Expand All @@ -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.";
Expand Down Expand Up @@ -495,33 +464,43 @@ 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;
if (updatingIndex) {
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.");
Expand All @@ -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);
Expand All @@ -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}`]);
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 9 additions & 1 deletion src/arduino/arduinoSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface IArduinoSettings {
preferencePath: string;
defaultBaudRate: number;
preferences: Map<string, string>;
useArduinoCli: boolean;
reloadPreferences(): void;
}

Expand All @@ -38,18 +39,21 @@ export class ArduinoSettings implements IArduinoSettings {

private _preferences: Map<string, string>;

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"))) {
Expand Down Expand Up @@ -150,6 +154,10 @@ export class ArduinoSettings implements IArduinoSettings {
return this._preferences;
}

public get useArduinoCli() {
return this._useArduinoCli;
}

public get defaultBaudRate() {
return this._defaultBaudRate;
}
Expand Down
Loading