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

Commit a736cfc

Browse files
committed
Bundle arduino-cli with extension
1 parent fffcbf2 commit a736cfc

14 files changed

+352
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ node_modules
66
src/views/app/sprites-generated
77
test/**/c_cpp_properties.json
88
*.vsix
9+
assets/platform/*/arduino-cli

NOTICE_arduino-cli.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
NOTICES AND INFORMATION
2+
Do Not Translate or Localize
3+
4+
Microsoft makes the arduino-cli open source code available at
5+
https://3rdpartysource.microsoft.com, or you may send a check or money order for
6+
US $5.00, including the product name, the open source component name, platform,
7+
and version number, to:
8+
9+
Source Code Compliance Team
10+
Microsoft Corporation
11+
One Microsoft Way
12+
Redmond, WA 98052
13+
USA
14+
15+
Notwithstanding any other terms, you may reverse engineer this software to the extent
16+
required to debug changes to any libraries licensed under the GNU Lesser General Public License.

README.md

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,21 @@ Welcome to the Visual Studio Code extension for **Arduino** <sup>preview</sup> !
1515
* Integrated Arduino Debugging <sup>New</sup>
1616

1717
## Prerequisites
18-
Either the Arduino IDE or Arduino CLI are required.
18+
Either the Arduino IDE or Arduino CLI are required. The recommended approach is
19+
to use the version of Arduino CLI that comes bundled with the extension, which
20+
works out of the box.
21+
22+
### Arduino CLI
23+
To use the bundled version of Arduino CLI, `arduino.useArduinoCli` should be `true`,
24+
and `arduino.path` and `arduino.commandPath` should be empty or unset.
25+
`arduino.useArduinoCli` defaults to `false` while we deprecate support for the
26+
Arduino IDE, but there will be a prompt when the extension first activates to
27+
switch to the Arduino CLI.
28+
29+
If you want to use a custom version of Arduino CLI, it can be downloaded from
30+
the repository's [release page](https://github.com/arduino/arduino-cli/releases/).
31+
For custom versions, `arduino.path` must be set to the directory containing the
32+
Arduino CLI executable.
1933

2034
### Arduino IDE
2135
The Arduino IDE can be installed the Arduino [download page](https://www.arduino.cc/en/main/software#download).
@@ -24,11 +38,6 @@ The Arduino IDE can be installed the Arduino [download page](https://www.arduino
2438
- *Note:* Arduino IDE `1.8.7` had some breaking changes, causing board package and library installation failures. These failures were corrected in `1.8.8` and later.
2539
- *Note:* Arduino IDE `2.X.Y` is not supported at this time [issue 1477](https://github.com/microsoft/vscode-arduino/issues/1477)
2640

27-
### Arduino CLI
28-
The Arduino CLI can be downloaded from the repository's [release page](https://github.com/arduino/arduino-cli/releases/tag/0.13.0)
29-
- The extension has only been tested with v0.13.0.
30-
- If you use the CLI you will have to set `arduino.path` since the CLI does not have a default path.
31-
3241
## Installation
3342
Open VS Code and press <kbd>F1</kbd> or <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> *or* <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> to open command palette, select **Install Extension** and type `vscode-arduino`.
3443

@@ -71,9 +80,9 @@ This extension provides several commands in the Command Palette (<kbd>F1</kbd> o
7180
## Options
7281
| Option | Description |
7382
| --- | --- |
74-
| `arduino.useArduinoCli` | Whether to use the Arduino CLI (`true`) or the Arduino IDE (`false`) -- defaults to `false`. If using `true`, make sure to set the `arduino.path` and `arduino.commandPath` values correctly. |
75-
| `arduino.path` | Path to the Arduino installation. You can use a custom version of Arduino by modifying this setting to include the full path. Example: `C:\\Program Files\\Arduino` for Windows, `/Applications` for Mac, `/home/<username>/Downloads/arduino-1.8.1` for Linux. (Requires a restart after change). The default value is automatically detected from your Arduino IDE installation path. To use the Arduino CLI, use the path that contains the `arduino-cli` executable (e.g. `/usr/local/bin`). |
76-
| `arduino.commandPath` | Path to an executable (or script) relative to `arduino.path`. The default value is `arduino_debug.exe` for Windows, `Contents/MacOS/Arduino` for Mac and `arduino` for Linux, You also can use a custom launch script to run Arduino by modifying this setting. (Requires a restart after change) Example: `run-arduino.bat` for Windows, `Contents/MacOS/run-arduino.sh` for Mac and `bin/run-arduino.sh` for Linux. To use the Arduino CLI, use `arduino-cli`. |
83+
| `arduino.useArduinoCli` | Whether to use the Arduino CLI (`true`) or the Arduino IDE (`false`) -- defaults to `false`. If using `true`, either leave the `arduino.path` and `arduino.commandPath` values unset to use the bundled version of Arduino CLI, or point them at a custom version of Arduino CLI. Note that a future version of the extension will change this default to `true` and remove support for Arduino IDE. |
84+
| `arduino.path` | Path to the Arduino installation. You can use a custom version of Arduino by modifying this setting to include the full path. Example: `C:\\Program Files\\Arduino` for Windows, `/Applications` for Mac, `/home/<username>/Downloads/arduino-1.8.1` for Linux. (Requires a restart after change). The default value is automatically detected from your Arduino IDE installation path. To use the Arduino CLI, use the path that contains the `arduino-cli` executable (e.g. `/usr/local/bin`), or leave it unset to use the bundled version of Arduino CLI. |
85+
| `arduino.commandPath` | Path to an executable (or script) relative to `arduino.path`. The default value is `arduino_debug.exe` for Windows, `Contents/MacOS/Arduino` for Mac and `arduino` for Linux, You also can use a custom launch script to run Arduino by modifying this setting. (Requires a restart after change) Example: `run-arduino.bat` for Windows, `Contents/MacOS/run-arduino.sh` for Mac and `bin/run-arduino.sh` for Linux. To use the bundled version of Arduino CLI, leave this option unset. To use a custom version of Arduino CLI, use `arduino-cli`. |
7786
| `arduino.additionalUrls` | Additional Boards Manager URLs for 3rd party packages as a string array. The default value is empty. |
7887
| `arduino.logLevel` | CLI output log level. Could be info or verbose. The default value is `"info"`. |
7988
| `arduino.clearOutputOnBuild` | Clear the output logs before uploading or verifying. Default value is `false`. |
@@ -91,8 +100,7 @@ The following Visual Studio Code settings are available for the Arduino extensio
91100

92101
```json
93102
{
94-
"arduino.path": "C:/Program Files (x86)/Arduino",
95-
"arduino.commandPath": "arduino_debug.exe",
103+
"arduino.useArduinoCli": true,
96104
"arduino.logLevel": "info",
97105
"arduino.allowPDEFiletype": false,
98106
"arduino.enableUSBDetection": true,
@@ -105,7 +113,6 @@ The following Visual Studio Code settings are available for the Arduino extensio
105113
"arduino.defaultBaudRate": 115200
106114
}
107115
```
108-
*Note:* You only need to set `arduino.path` in Visual Studio Code settings, other options are not required.
109116

110117
The following settings are as per sketch settings of the Arduino extension. You can find them in
111118
`.vscode/arduino.json` under the workspace.

build/assets.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"version": "0.29.0",
3+
"assets": {
4+
"arduino-cli_0.29.0_Linux_64bit.tar.gz": {
5+
"hash": "febc558bb36a9aeb881ebcce0af6fff955234afda14435791ca41daf492c9cac",
6+
"platforms": ["linux-x64"]
7+
},
8+
"arduino-cli_0.29.0_Linux_ARM64.tar.gz": {
9+
"hash": "ce5cd44808462461c88ab3d2441363a7fa08035a1d0cc300823d357929223ae6",
10+
"platforms": ["linux-arm64"]
11+
},
12+
"arduino-cli_0.29.0_Linux_ARMv7.tar.gz": {
13+
"hash": "b2b98400a643324219f8fca1a4eeef3a129d6fe87356e4d126b1b56f88635c94",
14+
"platforms": ["linux-armhf"]
15+
},
16+
"arduino-cli_0.29.0_macOS_64bit.tar.gz": {
17+
"hash": "d2e5aa10c66440b27a55deca54d12fc6071bb4963423706aeae97bc68a5597de",
18+
"platforms": ["darwin-x64"]
19+
},
20+
"arduino-cli_0.29.0_macOS_ARM64.tar.gz": {
21+
"hash": "19da609c94383c98748ec79a751ac19dab38ce012880d9bb3e0e7e1d70128107",
22+
"platforms": ["darwin-arm64"]
23+
},
24+
"arduino-cli_0.29.0_Windows_32bit.zip": {
25+
"hash": "366a6d354083db5386ff5e0d92043d23940e11cba9c3a5cf46ccea5a849e21ea",
26+
"platforms": ["win32-ia32"]
27+
},
28+
"arduino-cli_0.29.0_Windows_64bit.zip": {
29+
"hash": "e7473a72e40c7d7a1b29c4a3ec4646f9b9163e46c35fd78e34f1e315c2dd1e38",
30+
"platforms": ["win32-x64"]
31+
}
32+
}
33+
}

build/downloadAssets.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
// This script downloads and verifies platform-specific arduino-cli binaries
5+
// from GitHub releases. The release is specified by the "version" field in
6+
// assets.json.
7+
8+
const { execSync } = require("child_process");
9+
const { createHash } = require("crypto");
10+
const { readFileSync, mkdirSync, rmSync, renameSync } = require("fs");
11+
const { resolve } = require("path");
12+
13+
function run(command) {
14+
console.log(command);
15+
execSync(command);
16+
}
17+
18+
const config = require('./assets.json');
19+
20+
for (const asset in config.assets) {
21+
if (Object.hasOwnProperty.call(config.assets, asset)) {
22+
const platforms = config.assets[asset].platforms;
23+
const hash = config.assets[asset].hash;
24+
for (const platform of platforms) {
25+
const directory = resolve(__dirname, "..", "assets", "platform", platform);
26+
const destination = resolve(directory, asset);
27+
28+
// Download the asset.
29+
run([
30+
"curl",
31+
`https://github.com/arduino/arduino-cli/releases/download/${config.version}/${asset}`,
32+
"--location",
33+
`--output-dir ${directory}`,
34+
`--remote-name`,
35+
"--silent",
36+
"--show-error",
37+
].join(" "));
38+
39+
// Verify the hash.
40+
const actualHash = createHash("sha256")
41+
.update(readFileSync(destination))
42+
.digest("hex");
43+
if (actualHash !== hash) {
44+
throw new Error(
45+
`Hash mismatch for ${asset} on ${platform}. Expected ${hash} but got ${actualHash}.`
46+
);
47+
}
48+
49+
// Extract to an "arduino-cli" directory.
50+
const extractDirectory = resolve(directory, "arduino-cli");
51+
mkdirSync(extractDirectory, { recursive: true });
52+
run(`tar -xf ${destination} -C ${extractDirectory}`);
53+
54+
// Remove the downloaded archive. We don't need to ship it.
55+
rmSync(destination);
56+
57+
// VSIX signing will silently strip any extensionless files. Artificially
58+
// add a ".app" extension to extensionless executables.
59+
const executable = resolve(extractDirectory, "arduino-cli");
60+
try {
61+
renameSync(executable, `${executable}.app`);
62+
} catch {
63+
// The file might not exist. This is expected for Windows.
64+
}
65+
}
66+
}
67+
}

cgmanifest.json

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"$schema": "https://json.schemastore.org/component-detection-manifest.json",
3+
"version": 1,
4+
"registrations": [
5+
{
6+
"component": {
7+
"type": "other",
8+
"other": {
9+
"name": "arduino-cli (Linux x64)",
10+
"version": "0.29.0",
11+
"downloadUrl": "https://github.com/arduino/arduino-cli/releases/download/0.29.0/arduino-cli_0.29.0_Linux_64bit.tar.gz",
12+
}
13+
}
14+
},
15+
{
16+
"component": {
17+
"type": "other",
18+
"other": {
19+
"name": "arduino-cli (Linux ARM64)",
20+
"version": "0.29.0",
21+
"downloadUrl": "https://github.com/arduino/arduino-cli/releases/download/0.29.0/arduino-cli_0.29.0_Linux_ARM64.tar.gz",
22+
}
23+
}
24+
},
25+
{
26+
"component": {
27+
"type": "other",
28+
"other": {
29+
"name": "arduino-cli (Linux ARMv7)",
30+
"version": "0.29.0",
31+
"downloadUrl": "https://github.com/arduino/arduino-cli/releases/download/0.29.0/arduino-cli_0.29.0_Linux_ARMv7.tar.gz",
32+
}
33+
}
34+
},
35+
{
36+
"component": {
37+
"type": "other",
38+
"other": {
39+
"name": "arduino-cli (macOS x64)",
40+
"version": "0.29.0",
41+
"downloadUrl": "https://github.com/arduino/arduino-cli/releases/download/0.29.0/arduino-cli_0.29.0_macOS_64bit.tar.gz",
42+
}
43+
}
44+
},
45+
{
46+
"component": {
47+
"type": "other",
48+
"other": {
49+
"name": "arduino-cli (macOS ARM64)",
50+
"version": "0.29.0",
51+
"downloadUrl": "https://github.com/arduino/arduino-cli/releases/download/0.29.0/arduino-cli_0.29.0_macOS_ARM64.tar.gz",
52+
}
53+
}
54+
},
55+
{
56+
"component": {
57+
"type": "other",
58+
"other": {
59+
"name": "arduino-cli (Windows x86)",
60+
"version": "0.29.0",
61+
"downloadUrl": "https://github.com/arduino/arduino-cli/releases/download/0.29.0/arduino-cli_0.29.0_Windows_32bit.zip",
62+
}
63+
}
64+
},
65+
{
66+
"component": {
67+
"type": "other",
68+
"other": {
69+
"name": "arduino-cli (Windows x64)",
70+
"version": "0.29.0",
71+
"downloadUrl": "https://github.com/arduino/arduino-cli/releases/download/0.29.0/arduino-cli_0.29.0_Windows_64bit.zip",
72+
}
73+
}
74+
}
75+
]
76+
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@
473473
"arduino.useArduinoCli": {
474474
"type": "boolean",
475475
"default": false,
476-
"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)"
476+
"markdownDescription": "Use Arduino CLI installed instead of Arduino IDE. If `#arduino.path#` and `#arduino.commandPath#` are not set, the extension will use a version of Arduino CLI bundled with the extension. (Requires a restart after change)"
477477
},
478478
"arduino.path": {
479479
"type": "string",
@@ -596,7 +596,7 @@
596596
},
597597
"scripts": {
598598
"build": "gulp build --mode=production",
599-
"postinstall": "cd ./src/views && npm install",
599+
"postinstall": "node ./build/downloadAssets.js && cd ./src/views && npm install",
600600
"test": "gulp test"
601601
},
602602
"extensionDependencies": [

src/arduino/arduinoSettings.ts

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
import * as os from "os";
55
import * as path from "path";
66
import * as WinReg from "winreg";
7+
import * as vscode from 'vscode';
8+
import { chmod } from "fs/promises";
79
import * as util from "../common/util";
810

911
import { resolveArduinoPath } from "../common/platform";
1012

1113
import { VscodeSettings } from "./vscodeSettings";
14+
import * as Logger from "../logger/logger";
1215

1316
export interface IArduinoSettings {
1417
arduinoPath: string;
@@ -22,6 +25,7 @@ export interface IArduinoSettings {
2225
defaultBaudRate: number;
2326
preferences: Map<string, string>;
2427
useArduinoCli: boolean;
28+
usingBundledArduinoCli: boolean;
2529
defaultTimestampFormat: string;
2630
analyzeOnSettingChange: boolean;
2731
reloadPreferences(): void;
@@ -44,7 +48,9 @@ export class ArduinoSettings implements IArduinoSettings {
4448

4549
private _defaultTimestampFormat: string;
4650

47-
public constructor() {
51+
private _usingBundledArduinoCli: boolean = false;
52+
53+
public constructor(private readonly _context: vscode.ExtensionContext) {
4854
}
4955

5056
public async initialize() {
@@ -136,7 +142,7 @@ export class ArduinoSettings implements IArduinoSettings {
136142

137143
public get commandPath(): string {
138144
const platform = os.platform();
139-
if (platform === "darwin") {
145+
if (platform === "darwin" && !this._usingBundledArduinoCli) {
140146
return path.join(util.resolveMacArduinoAppPath(this._arduinoPath, this._useArduinoCli), path.normalize(this._commandPath));
141147
} else {
142148
return path.join(this._arduinoPath, path.normalize(this._commandPath));
@@ -162,6 +168,10 @@ export class ArduinoSettings implements IArduinoSettings {
162168
return this._useArduinoCli;
163169
}
164170

171+
public get usingBundledArduinoCli() {
172+
return this._usingBundledArduinoCli;
173+
}
174+
165175
public get defaultBaudRate() {
166176
return this._defaultBaudRate;
167177
}
@@ -225,14 +235,43 @@ export class ArduinoSettings implements IArduinoSettings {
225235
}
226236
}
227237

238+
private readonly bundledArduinoCliName: { [platform: string]: string } = {
239+
'darwin-arm64': 'arduino-cli.app',
240+
'darwin-x64': 'arduino-cli.app',
241+
'linux-arm64': 'arduino-cli.app',
242+
'linux-armhf': 'arduino-cli.app',
243+
'linux-x64': 'arduino-cli.app',
244+
'win32-ia32': 'arduino-cli.exe',
245+
'win32-x64': 'arduino-cli.exe',
246+
};
247+
248+
private async bundledArduinoCliPath(): Promise<string | undefined> {
249+
const platform = await util.getPlatform();
250+
const name = this.bundledArduinoCliName[platform];
251+
if (!name) return undefined;
252+
return this._context.asAbsolutePath(path.join('assets', 'platform', platform, 'arduino-cli', name));
253+
}
254+
228255
private async tryResolveArduinoPath(): Promise<void> {
229256
// Query arduino path sequentially from the following places such as "vscode user settings", "system environment variables",
230257
// "usual software installation directory for each os".
231258
// 1. Search vscode user settings first.
232259
const configValue = VscodeSettings.getInstance().arduinoPath;
233260
if (!configValue || !configValue.trim()) {
234-
// 2 & 3. Resolve arduino path from system environment variables and usual software installation directory.
235-
this._arduinoPath = await Promise.resolve(resolveArduinoPath());
261+
// 2. Resolve arduino path from the bundled arduino-cli, if CLI support is enabled.
262+
const bundledPath = await this.bundledArduinoCliPath();
263+
if (bundledPath && this._useArduinoCli && !this._commandPath) {
264+
// The extension VSIX stipped the executable bit, so we need to set it.
265+
// 0x755 means rwxr-xr-x (read and execute for everyone, write for owner).
266+
await chmod(bundledPath, 0o755);
267+
this._usingBundledArduinoCli = true;
268+
Logger.traceUserData("using-bundled-arduino-cli");
269+
this._arduinoPath = path.dirname(bundledPath);
270+
this._commandPath = path.basename(bundledPath);
271+
} else {
272+
// 3 & 4. Resolve arduino path from system environment variables and usual software installation directory.
273+
this._arduinoPath = await Promise.resolve(resolveArduinoPath());
274+
}
236275
} else {
237276
this._arduinoPath = configValue;
238277
}

0 commit comments

Comments
 (0)