mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-02 08:08:32 +00:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
96b5edf427 | ||
![]() |
a5a6a0b611 | ||
![]() |
2a27a14a68 | ||
![]() |
f2d492b5dc | ||
![]() |
5979e5aad2 | ||
![]() |
baa9b5f7ab | ||
![]() |
481497e384 | ||
![]() |
0207778373 | ||
![]() |
d79f32efd7 | ||
![]() |
3ab03dd62f | ||
![]() |
bc3cb0c230 | ||
![]() |
473cb11053 | ||
![]() |
0a87fd00f3 | ||
![]() |
9b1f15def8 | ||
![]() |
77b430675d | ||
![]() |
f660058c75 | ||
![]() |
9ecff86bbe | ||
![]() |
5ab3a747a6 | ||
![]() |
877c1a1559 | ||
![]() |
2f9bf86d75 | ||
![]() |
112153fb96 | ||
![]() |
69ac1f4779 |
19
.github/workflows/build.yml
vendored
19
.github/workflows/build.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- os: windows-latest
|
||||
- os: windows-2019
|
||||
- os: ubuntu-18.04 # https://github.com/arduino/arduino-ide/issues/259
|
||||
- os: macos-latest
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
@@ -33,16 +33,16 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Node.js 12.x
|
||||
- name: Install Node.js 14.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12.14.1'
|
||||
node-version: '14.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install Python 2.7
|
||||
- name: Install Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '2.7'
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Package
|
||||
shell: bash
|
||||
@@ -50,6 +50,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
AC_USERNAME: ${{ secrets.AC_USERNAME }}
|
||||
AC_PASSWORD: ${{ secrets.AC_PASSWORD }}
|
||||
AC_TEAM_ID: ${{ secrets.AC_TEAM_ID }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
IS_NIGHTLY: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') }}
|
||||
@@ -96,9 +97,13 @@ jobs:
|
||||
matrix:
|
||||
artifact:
|
||||
- path: '*Linux_64bit.zip'
|
||||
name: Linux_X86-64
|
||||
name: Linux_X86-64_zip
|
||||
- path: '*Linux_64bit.AppImage'
|
||||
name: Linux_X86-64_app_image
|
||||
- path: '*macOS_64bit.dmg'
|
||||
name: macOS
|
||||
name: macOS_dmg
|
||||
- path: '*macOS_64bit.zip'
|
||||
name: macOS_zip
|
||||
- path: '*Windows_64bit.exe'
|
||||
name: Windows_X86-64_interactive_installer
|
||||
- path: '*Windows_64bit.msi'
|
||||
|
4
.github/workflows/check-i18n-task.yml
vendored
4
.github/workflows/check-i18n-task.yml
vendored
@@ -25,10 +25,10 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Node.js 12.x
|
||||
- name: Install Node.js 14.x
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12.14.1'
|
||||
node-version: '14.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install dependencies
|
||||
|
4
.github/workflows/i18n-nightly-push.yml
vendored
4
.github/workflows/i18n-nightly-push.yml
vendored
@@ -12,10 +12,10 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Node.js 12.x
|
||||
- name: Install Node.js 14.x
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12.14.1'
|
||||
node-version: '14.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install dependencies
|
||||
|
4
.github/workflows/i18n-weekly-pull.yml
vendored
4
.github/workflows/i18n-weekly-pull.yml
vendored
@@ -12,10 +12,10 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Node.js 12.x
|
||||
- name: Install Node.js 14.x
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12.14.1'
|
||||
node-version: '14.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install dependencies
|
||||
|
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@@ -37,6 +37,13 @@
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "attach",
|
||||
"name": "Attach to Electron Frontend",
|
||||
"port": 9222,
|
||||
"webRoot": "${workspaceFolder}/electron-app"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
@@ -104,5 +111,14 @@
|
||||
"program": "${workspaceRoot}/electron/packager/index.js",
|
||||
"cwd": "${workspaceFolder}/electron/packager"
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Launch Electron Backend & Frontend",
|
||||
"configurations": [
|
||||
"App (Electron)",
|
||||
"Attach to Electron Frontend"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -42,6 +42,7 @@ The _frontend_ is running as an Electron renderer process and can invoke service
|
||||
If you’re familiar with TypeScript, the [Theia IDE](https://theia-ide.org/), and if you want to contribute to the
|
||||
project, you should be able to build the Arduino IDE locally.
|
||||
Please refer to the [Theia IDE prerequisites](https://github.com/theia-ide/theia/blob/master/doc/) documentation for the setup instructions.
|
||||
> **Note**: Node.js 14 must be used instead of the version 12 recommended at the link above.
|
||||
|
||||
Once you have all the tools installed, you can build the editor following these steps
|
||||
|
||||
@@ -57,9 +58,7 @@ Once you have all the tools installed, you can build the editor following these
|
||||
|
||||
3. Rebuild the electron dependencies
|
||||
```sh
|
||||
cd electron-app
|
||||
yarn theia rebuild:electron
|
||||
cd ..
|
||||
yarn rebuild:electron
|
||||
```
|
||||
|
||||
4. Start the application
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "arduino-ide-extension",
|
||||
"version": "2.0.0-rc3",
|
||||
"version": "2.0.0-rc4",
|
||||
"description": "An extension for Theia building the Arduino IDE",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"scripts": {
|
||||
@@ -21,22 +21,23 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.3.7",
|
||||
"@theia/application-package": "1.19.0",
|
||||
"@theia/core": "1.19.0",
|
||||
"@theia/editor": "1.19.0",
|
||||
"@theia/editor-preview": "1.19.0",
|
||||
"@theia/filesystem": "1.19.0",
|
||||
"@theia/git": "1.19.0",
|
||||
"@theia/keymaps": "1.19.0",
|
||||
"@theia/markers": "1.19.0",
|
||||
"@theia/monaco": "1.19.0",
|
||||
"@theia/navigator": "1.19.0",
|
||||
"@theia/outline-view": "1.19.0",
|
||||
"@theia/output": "1.19.0",
|
||||
"@theia/preferences": "1.19.0",
|
||||
"@theia/search-in-workspace": "1.19.0",
|
||||
"@theia/terminal": "1.19.0",
|
||||
"@theia/workspace": "1.19.0",
|
||||
"@theia/application-package": "1.22.1",
|
||||
"@theia/core": "1.22.1",
|
||||
"@theia/editor": "1.22.1",
|
||||
"@theia/editor-preview": "1.22.1",
|
||||
"@theia/electron": "1.22.1",
|
||||
"@theia/filesystem": "1.22.1",
|
||||
"@theia/git": "1.22.1",
|
||||
"@theia/keymaps": "1.22.1",
|
||||
"@theia/markers": "1.22.1",
|
||||
"@theia/monaco": "1.22.1",
|
||||
"@theia/navigator": "1.22.1",
|
||||
"@theia/outline-view": "1.22.1",
|
||||
"@theia/output": "1.22.1",
|
||||
"@theia/preferences": "1.22.1",
|
||||
"@theia/search-in-workspace": "1.22.1",
|
||||
"@theia/terminal": "1.22.1",
|
||||
"@theia/workspace": "1.22.1",
|
||||
"@tippyjs/react": "^4.2.5",
|
||||
"@types/atob": "^2.1.2",
|
||||
"@types/auth0-js": "^9.14.0",
|
||||
@@ -64,6 +65,7 @@
|
||||
"css-element-queries": "^1.2.0",
|
||||
"dateformat": "^3.0.3",
|
||||
"deepmerge": "2.0.1",
|
||||
"electron-updater": "^4.6.5",
|
||||
"fuzzy": "^0.1.3",
|
||||
"glob": "^7.1.6",
|
||||
"google-protobuf": "^3.11.4",
|
||||
@@ -81,6 +83,7 @@
|
||||
"ps-tree": "^1.2.0",
|
||||
"query-string": "^7.0.1",
|
||||
"react-disable": "^0.1.0",
|
||||
"react-markdown": "^8.0.0",
|
||||
"react-select": "^3.0.4",
|
||||
"react-tabs": "^3.1.2",
|
||||
"react-window": "^1.8.6",
|
||||
@@ -153,7 +156,7 @@
|
||||
],
|
||||
"arduino": {
|
||||
"cli": {
|
||||
"version": "0.20.2"
|
||||
"version": "0.21.0"
|
||||
},
|
||||
"fwuploader": {
|
||||
"version": "2.0.0"
|
||||
@@ -165,4 +168,4 @@
|
||||
"version": "0.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,36 +1,42 @@
|
||||
// @ts-check
|
||||
|
||||
|
||||
(async () => {
|
||||
const { Octokit } = require('@octokit/rest');
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const octokit = new Octokit({
|
||||
userAgent: 'Arduino IDE compose-changelog.js',
|
||||
});
|
||||
|
||||
const response = await octokit.rest.repos.listReleases({
|
||||
owner: 'arduino',
|
||||
repo: 'arduino-ide',
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
})
|
||||
const response = await octokit.rest.repos
|
||||
.listReleases({
|
||||
owner: 'arduino',
|
||||
repo: 'arduino-ide',
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
const releases = response.data;
|
||||
|
||||
let fullChangelog = releases.reduce((acc, item) => {
|
||||
let fullChangelog = releases.reduce((acc, item, index) => {
|
||||
// Process each line separately
|
||||
const body = item.body.split('\n').map(processLine).join('\n')
|
||||
const body = item.body.split('\n').map(processLine).join('\n');
|
||||
// item.name is the name of the release changelog
|
||||
return acc + `# ${item.name}\n\n${body}\n\n---\n\n`;
|
||||
return (
|
||||
acc +
|
||||
`## ${item.name}\n\n${body}${
|
||||
index !== releases.length - 1 ? '\n\n---\n\n' : '\n'
|
||||
}`
|
||||
);
|
||||
}, '');
|
||||
|
||||
const args = process.argv.slice(2)
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length == 0) {
|
||||
console.error("Missing argument to destination file")
|
||||
process.exit(1)
|
||||
console.error('Missing argument to destination file');
|
||||
process.exit(1);
|
||||
}
|
||||
const changelogFile = path.resolve(args[0]);
|
||||
|
||||
@@ -38,19 +44,18 @@
|
||||
changelogFile,
|
||||
fullChangelog,
|
||||
{
|
||||
flag: "w+",
|
||||
flag: 'w+',
|
||||
},
|
||||
err => {
|
||||
(err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("Changelog written to", changelogFile);
|
||||
console.log('Changelog written to', changelogFile);
|
||||
}
|
||||
)
|
||||
);
|
||||
})();
|
||||
|
||||
|
||||
// processLine applies different substitutions to line string.
|
||||
// We're assuming that there are no more than one substitution
|
||||
// per line to be applied.
|
||||
@@ -61,7 +66,8 @@ const processLine = (line) => {
|
||||
// * [#123](https://github.com/arduino/arduino-ide/pull/123/)
|
||||
// * [#123](https://github.com/arduino/arduino-ide/issues/123/)
|
||||
// If it does return the line as is.
|
||||
let r = /(\(|\[)#\d+(\)|\])(\(|\[)https:\/\/github\.com\/arduino\/arduino-ide\/(pull|issues)\/(\d+)\/?(\)|\])/gm;
|
||||
let r =
|
||||
/(\(|\[)#\d+(\)|\])(\(|\[)https:\/\/github\.com\/arduino\/arduino-ide\/(pull|issues)\/(\d+)\/?(\)|\])/gm;
|
||||
if (r.test(line)) {
|
||||
return line;
|
||||
}
|
||||
@@ -70,9 +76,12 @@ const processLine = (line) => {
|
||||
// * #123
|
||||
// If it does it's changed to:
|
||||
// * [#123](https://github.com/arduino/arduino-ide/pull/123)
|
||||
r = /#(\d+)/gm;
|
||||
r = /(?<![\w\d\/_]{1})#((\d)+)(?![\w\d\/_]{1})/gm;
|
||||
if (r.test(line)) {
|
||||
return line.replace(r, `[#$1](https://github.com/arduino/arduino-ide/pull/$1)`)
|
||||
return line.replace(
|
||||
r,
|
||||
`[#$1](https://github.com/arduino/arduino-ide/pull/$1)`
|
||||
);
|
||||
}
|
||||
|
||||
// Check if a link with one of the following format exists:
|
||||
@@ -85,7 +94,8 @@ const processLine = (line) => {
|
||||
// * [#123](https://github.com/arduino/arduino-ide/issues/123)
|
||||
// * [#123](https://github.com/arduino/arduino-ide/pull/123/)
|
||||
// * [#123](https://github.com/arduino/arduino-ide/issues/123/)
|
||||
r = /(https:\/\/github\.com\/arduino\/arduino-ide\/(pull|issues)\/(\d+)\/?)/gm;
|
||||
r =
|
||||
/(https:\/\/github\.com\/arduino\/arduino-ide\/(pull|issues)\/(\d+)\/?)/gm;
|
||||
if (r.test(line)) {
|
||||
return line.replace(r, `[#$3]($1)`);
|
||||
}
|
||||
@@ -95,11 +105,12 @@ const processLine = (line) => {
|
||||
// * https://github.com/arduino/arduino-ide/compare/2.0.0-rc2...2.0.0-rc3/
|
||||
// If it does it's changed to:
|
||||
// * [`2.0.0-rc2...2.0.0-rc3`](https://github.com/arduino/arduino-ide/compare/2.0.0-rc2...2.0.0-rc3)
|
||||
r = /(https:\/\/github\.com\/arduino\/arduino-ide\/compare\/([^\/]*))\/?\s?/gm;
|
||||
r =
|
||||
/(https:\/\/github\.com\/arduino\/arduino-ide\/compare\/([^\/]*))\/?\s?/gm;
|
||||
if (r.test(line)) {
|
||||
return line.replace(r, '[`$2`]($1)');;
|
||||
return line.replace(r, '[`$2`]($1)');
|
||||
}
|
||||
|
||||
// If nothing matches just return the line as is
|
||||
return line;
|
||||
}
|
||||
};
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import * as React from 'react';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import {
|
||||
BoardsService,
|
||||
SketchesService,
|
||||
@@ -68,8 +68,11 @@ import { ArduinoPreferences } from './arduino-preferences';
|
||||
import { SketchesServiceClientImpl } from '../common/protocol/sketches-service-client-impl';
|
||||
import { SaveAsSketch } from './contributions/save-as-sketch';
|
||||
import { SketchbookWidgetContribution } from './widgets/sketchbook/sketchbook-widget-contribution';
|
||||
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
|
||||
import { IDEUpdater } from '../common/protocol/ide-updater';
|
||||
|
||||
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
|
||||
export const SKIP_IDE_VERSION = 'skipIDEVersion';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoFrontendContribution
|
||||
@@ -78,8 +81,7 @@ export class ArduinoFrontendContribution
|
||||
TabBarToolbarContribution,
|
||||
CommandContribution,
|
||||
MenuContribution,
|
||||
ColorContribution
|
||||
{
|
||||
ColorContribution {
|
||||
@inject(ILogger)
|
||||
protected logger: ILogger;
|
||||
|
||||
@@ -157,6 +159,12 @@ export class ArduinoFrontendContribution
|
||||
@inject(LocalStorageService)
|
||||
protected readonly localStorageService: LocalStorageService;
|
||||
|
||||
@inject(IDEUpdater)
|
||||
protected readonly updater: IDEUpdater;
|
||||
|
||||
@inject(IDEUpdaterDialog)
|
||||
protected readonly updaterDialog: IDEUpdaterDialog;
|
||||
|
||||
protected invalidConfigPopup:
|
||||
| Promise<void | 'No' | 'Yes' | undefined>
|
||||
| undefined;
|
||||
@@ -251,7 +259,7 @@ export class ArduinoFrontendContribution
|
||||
});
|
||||
}
|
||||
|
||||
onStart(app: FrontendApplication): void {
|
||||
async onStart(app: FrontendApplication): Promise<void> {
|
||||
// Initialize all `pro-mode` widgets. This is a NOOP if in normal mode.
|
||||
for (const viewContribution of [
|
||||
this.fileNavigatorContributions,
|
||||
@@ -266,6 +274,31 @@ export class ArduinoFrontendContribution
|
||||
viewContribution.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
|
||||
this.updater
|
||||
.init(
|
||||
this.arduinoPreferences.get('arduino.ide.updateChannel'),
|
||||
this.arduinoPreferences.get('arduino.ide.updateBaseUrl')
|
||||
)
|
||||
.then(() => this.updater.checkForUpdates(true))
|
||||
.then(async (updateInfo) => {
|
||||
if (!updateInfo) return;
|
||||
const versionToSkip = await this.localStorageService.getData<string>(
|
||||
SKIP_IDE_VERSION
|
||||
);
|
||||
if (versionToSkip === updateInfo.version) return;
|
||||
this.updaterDialog.open(updateInfo);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/errorCheckingForUpdates',
|
||||
'Error while checking for Arduino IDE updates.\n{0}',
|
||||
e.message
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
const start = async ({ selectedBoard }: BoardsConfig.Config) => {
|
||||
if (selectedBoard) {
|
||||
const { name, fqbn } = selectedBoard;
|
||||
@@ -276,11 +309,25 @@ export class ArduinoFrontendContribution
|
||||
};
|
||||
this.boardsServiceClientImpl.onBoardsConfigChanged(start);
|
||||
this.arduinoPreferences.onPreferenceChanged((event) => {
|
||||
if (
|
||||
event.preferenceName === 'arduino.language.log' &&
|
||||
event.newValue !== event.oldValue
|
||||
) {
|
||||
start(this.boardsServiceClientImpl.boardsConfig);
|
||||
if (event.newValue !== event.oldValue) {
|
||||
switch (event.preferenceName) {
|
||||
case 'arduino.language.log':
|
||||
start(this.boardsServiceClientImpl.boardsConfig);
|
||||
break;
|
||||
case 'arduino.window.zoomLevel':
|
||||
if (typeof event.newValue === 'number') {
|
||||
const webContents = remote.getCurrentWebContents();
|
||||
webContents.setZoomLevel(event.newValue || 0);
|
||||
}
|
||||
break;
|
||||
case 'arduino.ide.updateChannel':
|
||||
case 'arduino.ide.updateBaseUrl':
|
||||
this.updater.init(
|
||||
this.arduinoPreferences.get('arduino.ide.updateChannel'),
|
||||
this.arduinoPreferences.get('arduino.ide.updateBaseUrl')
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.arduinoPreferences.ready.then(() => {
|
||||
@@ -288,16 +335,7 @@ export class ArduinoFrontendContribution
|
||||
const zoomLevel = this.arduinoPreferences.get('arduino.window.zoomLevel');
|
||||
webContents.setZoomLevel(zoomLevel);
|
||||
});
|
||||
this.arduinoPreferences.onPreferenceChanged((event) => {
|
||||
if (
|
||||
event.preferenceName === 'arduino.window.zoomLevel' &&
|
||||
typeof event.newValue === 'number' &&
|
||||
event.newValue !== event.oldValue
|
||||
) {
|
||||
const webContents = remote.getCurrentWebContents();
|
||||
webContents.setZoomLevel(event.newValue || 0);
|
||||
}
|
||||
});
|
||||
|
||||
app.shell.leftPanelHandler.removeBottomMenu('settings-menu');
|
||||
}
|
||||
|
||||
|
@@ -262,6 +262,19 @@ import {
|
||||
UserFieldsDialogWidget,
|
||||
} from './dialogs/user-fields/user-fields-dialog';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { IDEUpdaterCommands } from './ide-updater/ide-updater-commands';
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
IDEUpdaterPath,
|
||||
} from '../common/protocol/ide-updater';
|
||||
import { IDEUpdaterClientImpl } from './ide-updater/ide-updater-client-impl';
|
||||
import {
|
||||
IDEUpdaterDialog,
|
||||
IDEUpdaterDialogProps,
|
||||
IDEUpdaterDialogWidget,
|
||||
} from './dialogs/ide-updater/ide-updater-dialog';
|
||||
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
|
||||
|
||||
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
||||
|
||||
@@ -407,8 +420,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(SerialService)
|
||||
.toDynamicValue((context) => {
|
||||
const connection = context.container.get(WebSocketConnectionProvider);
|
||||
const client =
|
||||
context.container.get<SerialServiceClient>(SerialServiceClient);
|
||||
const client = context.container.get<SerialServiceClient>(
|
||||
SerialServiceClient
|
||||
);
|
||||
return connection.createProxy(SerialServicePath, client);
|
||||
})
|
||||
.inSingletonScope();
|
||||
@@ -472,12 +486,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
.inSingletonScope();
|
||||
rebind(TheiaEditorWidgetFactory).to(EditorWidgetFactory).inSingletonScope();
|
||||
rebind(TabBarToolbarFactory).toFactory(
|
||||
({ container: parentContainer }) =>
|
||||
() => {
|
||||
const container = parentContainer.createChild();
|
||||
container.bind(TabBarToolbar).toSelf().inSingletonScope();
|
||||
return container.get(TabBarToolbar);
|
||||
}
|
||||
({ container: parentContainer }) => () => {
|
||||
const container = parentContainer.createChild();
|
||||
container.bind(TabBarToolbar).toSelf().inSingletonScope();
|
||||
return container.get(TabBarToolbar);
|
||||
}
|
||||
);
|
||||
bind(OutputWidget).toSelf().inSingletonScope();
|
||||
rebind(TheiaOutputWidget).toService(OutputWidget);
|
||||
@@ -642,13 +655,15 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
|
||||
// Enable the dirty indicator on uncloseable widgets.
|
||||
rebind(TabBarRendererFactory).toFactory((context) => () => {
|
||||
const contextMenuRenderer =
|
||||
context.container.get<ContextMenuRenderer>(ContextMenuRenderer);
|
||||
const contextMenuRenderer = context.container.get<ContextMenuRenderer>(
|
||||
ContextMenuRenderer
|
||||
);
|
||||
const decoratorService = context.container.get<TabBarDecoratorService>(
|
||||
TabBarDecoratorService
|
||||
);
|
||||
const iconThemeService =
|
||||
context.container.get<IconThemeService>(IconThemeService);
|
||||
const iconThemeService = context.container.get<IconThemeService>(
|
||||
IconThemeService
|
||||
);
|
||||
return new TabBarRenderer(
|
||||
contextMenuRenderer,
|
||||
decoratorService,
|
||||
@@ -756,9 +771,32 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
title: 'UploadCertificate',
|
||||
});
|
||||
|
||||
bind(IDEUpdaterDialogWidget).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterDialog).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterDialogProps).toConstantValue({
|
||||
title: 'IDEUpdater',
|
||||
});
|
||||
|
||||
bind(UserFieldsDialogWidget).toSelf().inSingletonScope();
|
||||
bind(UserFieldsDialog).toSelf().inSingletonScope();
|
||||
bind(UserFieldsDialogProps).toConstantValue({
|
||||
title: 'UserFields',
|
||||
});
|
||||
|
||||
bind(IDEUpdaterCommands).toSelf().inSingletonScope();
|
||||
bind(CommandContribution).toService(IDEUpdaterCommands);
|
||||
|
||||
// Frontend binding for the IDE Updater service
|
||||
bind(IDEUpdaterClientImpl).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterClient).toService(IDEUpdaterClientImpl);
|
||||
bind(IDEUpdater)
|
||||
.toDynamicValue((context) => {
|
||||
const client = context.container.get(IDEUpdaterClientImpl);
|
||||
return ElectronIpcConnectionProvider.createProxy(
|
||||
context.container,
|
||||
IDEUpdaterPath,
|
||||
client
|
||||
);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
|
@@ -9,6 +9,11 @@ import {
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { CompilerWarningLiterals, CompilerWarnings } from '../common/protocol';
|
||||
|
||||
export enum UpdateChannel {
|
||||
Stable = 'stable',
|
||||
Nightly = 'nightly',
|
||||
}
|
||||
|
||||
export const ArduinoConfigSchema: PreferenceSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -64,13 +69,22 @@ export const ArduinoConfigSchema: PreferenceSchema = {
|
||||
),
|
||||
default: 0,
|
||||
},
|
||||
'arduino.ide.autoUpdate': {
|
||||
type: 'boolean',
|
||||
'arduino.ide.updateChannel': {
|
||||
type: 'string',
|
||||
enum: Object.values(UpdateChannel) as UpdateChannel[],
|
||||
default: UpdateChannel.Stable,
|
||||
description: nls.localize(
|
||||
'arduino/preferences/ide.autoUpdate',
|
||||
'True to enable automatic update checks. The IDE will check for updates automatically and periodically.'
|
||||
'arduino/preferences/ide.updateChannel',
|
||||
"Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build."
|
||||
),
|
||||
},
|
||||
'arduino.ide.updateBaseUrl': {
|
||||
type: 'string',
|
||||
default: 'https://downloads.arduino.cc/arduino-ide',
|
||||
description: nls.localize(
|
||||
'arduino/preferences/ide.updateBaseUrl',
|
||||
`The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'`
|
||||
),
|
||||
default: true,
|
||||
},
|
||||
'arduino.board.certificates': {
|
||||
type: 'string',
|
||||
@@ -171,7 +185,8 @@ export interface ArduinoConfiguration {
|
||||
'arduino.upload.verify': boolean;
|
||||
'arduino.window.autoScale': boolean;
|
||||
'arduino.window.zoomLevel': number;
|
||||
'arduino.ide.autoUpdate': boolean;
|
||||
'arduino.ide.updateChannel': UpdateChannel;
|
||||
'arduino.ide.updateBaseUrl': string;
|
||||
'arduino.board.certificates': string;
|
||||
'arduino.sketchbook.showAllFiles': boolean;
|
||||
'arduino.cloud.enabled': boolean;
|
||||
@@ -188,16 +203,10 @@ export interface ArduinoConfiguration {
|
||||
export const ArduinoPreferences = Symbol('ArduinoPreferences');
|
||||
export type ArduinoPreferences = PreferenceProxy<ArduinoConfiguration>;
|
||||
|
||||
export function createArduinoPreferences(
|
||||
preferences: PreferenceService
|
||||
): ArduinoPreferences {
|
||||
return createPreferenceProxy(preferences, ArduinoConfigSchema);
|
||||
}
|
||||
|
||||
export function bindArduinoPreferences(bind: interfaces.Bind): void {
|
||||
bind(ArduinoPreferences).toDynamicValue((ctx) => {
|
||||
const preferences = ctx.container.get<PreferenceService>(PreferenceService);
|
||||
return createArduinoPreferences(preferences);
|
||||
return createPreferenceProxy(preferences, ArduinoConfigSchema);
|
||||
});
|
||||
bind(PreferenceContribution).toConstantValue({
|
||||
schema: ArduinoConfigSchema,
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { toUnix } from 'upath';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { URI } from '@theia/core/shared/vscode-uri';
|
||||
import { isWindows } from '@theia/core/lib/common/os';
|
||||
import { notEmpty } from '@theia/core/lib/common/objects';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
@@ -61,12 +60,8 @@ export class ArduinoWorkspaceRootResolver {
|
||||
// - https://github.com/eclipse-theia/theia/blob/8196e9dcf9c8de8ea0910efeb5334a974f426966/packages/workspace/src/browser/workspace-service.ts#L423
|
||||
protected hashToUri(hash: string | undefined): string | undefined {
|
||||
if (hash && hash.length > 1 && hash.startsWith('#')) {
|
||||
const path = hash.slice(1); // Trim the leading `#`.
|
||||
return new URI(
|
||||
toUnix(path.slice(isWindows && hash.startsWith('/') ? 1 : 0))
|
||||
)
|
||||
.withScheme('file')
|
||||
.toString();
|
||||
const path = decodeURI(hash.slice(1)).replace(/\\/g, '/'); // Trim the leading `#`, decode the URI and replace Windows separators
|
||||
return URI.file(path.slice(isWindows && hash.startsWith('/') ? 1 : 0)).toString();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import { injectable, inject, named } from 'inversify';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { deepClone } from '@theia/core/lib/common/objects';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { Event, Emitter } from '@theia/core/lib/common/event';
|
||||
import {
|
||||
FrontendApplicationContribution,
|
||||
@@ -11,7 +10,6 @@ import { notEmpty } from '../../common/utils';
|
||||
import {
|
||||
BoardsService,
|
||||
ConfigOption,
|
||||
Installable,
|
||||
BoardDetails,
|
||||
Programmer,
|
||||
} from '../../common/protocol';
|
||||
@@ -36,16 +34,12 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
|
||||
onStart(): void {
|
||||
this.notificationCenter.onPlatformInstalled(async ({ item }) => {
|
||||
const { installedVersion: version } = item;
|
||||
if (!version) {
|
||||
return;
|
||||
}
|
||||
let shouldFireChanged = false;
|
||||
for (const fqbn of item.boards
|
||||
.map(({ fqbn }) => fqbn)
|
||||
.filter(notEmpty)
|
||||
.filter((fqbn) => !!fqbn)) {
|
||||
const key = this.getStorageKey(fqbn, version);
|
||||
const key = this.getStorageKey(fqbn);
|
||||
let data = await this.storageService.getData<
|
||||
ConfigOption[] | undefined
|
||||
>(key);
|
||||
@@ -72,33 +66,20 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
|
||||
async appendConfigToFqbn(
|
||||
fqbn: string | undefined,
|
||||
boardsPackageVersion: MaybePromise<
|
||||
Installable.Version | undefined
|
||||
> = this.getBoardsPackageVersion(fqbn)
|
||||
): Promise<string | undefined> {
|
||||
if (!fqbn) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { configOptions } = await this.getData(fqbn, boardsPackageVersion);
|
||||
const { configOptions } = await this.getData(fqbn);
|
||||
return ConfigOption.decorate(fqbn, configOptions);
|
||||
}
|
||||
|
||||
async getData(
|
||||
fqbn: string | undefined,
|
||||
boardsPackageVersion: MaybePromise<
|
||||
Installable.Version | undefined
|
||||
> = this.getBoardsPackageVersion(fqbn)
|
||||
): Promise<BoardsDataStore.Data> {
|
||||
async getData(fqbn: string | undefined): Promise<BoardsDataStore.Data> {
|
||||
if (!fqbn) {
|
||||
return BoardsDataStore.Data.EMPTY;
|
||||
}
|
||||
|
||||
const version = await boardsPackageVersion;
|
||||
if (!version) {
|
||||
return BoardsDataStore.Data.EMPTY;
|
||||
}
|
||||
const key = this.getStorageKey(fqbn, version);
|
||||
const key = this.getStorageKey(fqbn);
|
||||
let data = await this.storageService.getData<
|
||||
BoardsDataStore.Data | undefined
|
||||
>(key, undefined);
|
||||
@@ -124,25 +105,16 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
fqbn,
|
||||
selectedProgrammer,
|
||||
}: { fqbn: string; selectedProgrammer: Programmer },
|
||||
boardsPackageVersion: MaybePromise<
|
||||
Installable.Version | undefined
|
||||
> = this.getBoardsPackageVersion(fqbn)
|
||||
): Promise<boolean> {
|
||||
const data = deepClone(await this.getData(fqbn, boardsPackageVersion));
|
||||
const data = deepClone(await this.getData(fqbn));
|
||||
const { programmers } = data;
|
||||
if (!programmers.find((p) => Programmer.equals(selectedProgrammer, p))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const version = await boardsPackageVersion;
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.setData({
|
||||
fqbn,
|
||||
data: { ...data, selectedProgrammer },
|
||||
version,
|
||||
});
|
||||
this.fireChanged();
|
||||
return true;
|
||||
@@ -153,12 +125,9 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
fqbn,
|
||||
option,
|
||||
selectedValue,
|
||||
}: { fqbn: string; option: string; selectedValue: string },
|
||||
boardsPackageVersion: MaybePromise<
|
||||
Installable.Version | undefined
|
||||
> = this.getBoardsPackageVersion(fqbn)
|
||||
}: { fqbn: string; option: string; selectedValue: string }
|
||||
): Promise<boolean> {
|
||||
const data = deepClone(await this.getData(fqbn, boardsPackageVersion));
|
||||
const data = deepClone(await this.getData(fqbn));
|
||||
const { configOptions } = data;
|
||||
const configOption = configOptions.find((c) => c.option === option);
|
||||
if (!configOption) {
|
||||
@@ -176,12 +145,7 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
if (!updated) {
|
||||
return false;
|
||||
}
|
||||
const version = await boardsPackageVersion;
|
||||
if (!version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.setData({ fqbn, data, version });
|
||||
await this.setData({ fqbn, data });
|
||||
this.fireChanged();
|
||||
return true;
|
||||
}
|
||||
@@ -189,18 +153,16 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
protected async setData({
|
||||
fqbn,
|
||||
data,
|
||||
version,
|
||||
}: {
|
||||
fqbn: string;
|
||||
data: BoardsDataStore.Data;
|
||||
version: Installable.Version;
|
||||
}): Promise<void> {
|
||||
const key = this.getStorageKey(fqbn, version);
|
||||
const key = this.getStorageKey(fqbn);
|
||||
return this.storageService.setData(key, data);
|
||||
}
|
||||
|
||||
protected getStorageKey(fqbn: string, version: Installable.Version): string {
|
||||
return `.arduinoIDE-configOptions-${version}-${fqbn}`;
|
||||
protected getStorageKey(fqbn: string): string {
|
||||
return `.arduinoIDE-configOptions-${fqbn}`;
|
||||
}
|
||||
|
||||
protected async getBoardDetailsSafe(
|
||||
@@ -231,21 +193,6 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
protected fireChanged(): void {
|
||||
this.onChangedEmitter.fire();
|
||||
}
|
||||
|
||||
protected async getBoardsPackageVersion(
|
||||
fqbn: string | undefined
|
||||
): Promise<Installable.Version | undefined> {
|
||||
if (!fqbn) {
|
||||
return undefined;
|
||||
}
|
||||
const boardsPackage = await this.boardsService.getContainerBoardPackage({
|
||||
fqbn,
|
||||
});
|
||||
if (!boardsPackage) {
|
||||
return undefined;
|
||||
}
|
||||
return boardsPackage.installedVersion;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace BoardsDataStore {
|
||||
|
28
arduino-ide-extension/src/browser/components/ProgressBar.tsx
Normal file
28
arduino-ide-extension/src/browser/components/ProgressBar.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export type ProgressBarProps = {
|
||||
percent?: number;
|
||||
showPercentage?: boolean;
|
||||
};
|
||||
|
||||
export default function ProgressBar({
|
||||
percent = 0,
|
||||
showPercentage = false,
|
||||
}: ProgressBarProps): React.ReactElement {
|
||||
const roundedPercent = Math.round(percent);
|
||||
return (
|
||||
<div className="progress-bar">
|
||||
<div className="progress-bar--outer">
|
||||
<div
|
||||
className="progress-bar--inner"
|
||||
style={{ width: `${roundedPercent}%` }}
|
||||
/>
|
||||
</div>
|
||||
{showPercentage && (
|
||||
<div className="progress-bar--percentage">
|
||||
<div className="progress-bar--percentage-text">{roundedPercent}%</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import * as moment from 'moment';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { isOSX, isWindows } from '@theia/core/lib/common/os';
|
||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
||||
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import {
|
||||
SketchContribution,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
|
||||
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import * as dateFormat from 'dateformat';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import {
|
||||
DisposableCollection,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { toArray } from '@phosphor/algorithm';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
||||
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
||||
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
||||
|
@@ -13,6 +13,7 @@ import {
|
||||
KeybindingRegistry,
|
||||
} from './contribution';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { IDEUpdaterCommands } from '../ide-updater/ide-updater-commands';
|
||||
|
||||
@injectable()
|
||||
export class Help extends Contribution {
|
||||
@@ -115,6 +116,10 @@ export class Help extends Contribution {
|
||||
commandId: Help.Commands.VISIT_ARDUINO.id,
|
||||
order: '6',
|
||||
});
|
||||
registry.registerMenuAction(ArduinoMenus.HELP__FIND_GROUP, {
|
||||
commandId: IDEUpdaterCommands.CHECK_FOR_UPDATES.id,
|
||||
order: '7',
|
||||
});
|
||||
}
|
||||
|
||||
registerKeybindings(registry: KeybindingRegistry): void {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { Widget, ContextMenuRenderer } from '@theia/core/lib/browser';
|
||||
import {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { isOSX } from '@theia/core/lib/common/os';
|
||||
import {
|
||||
Contribution,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import * as dateFormat from 'dateformat';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import {
|
||||
|
@@ -0,0 +1,210 @@
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { shell } from 'electron';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { ProgressInfo, UpdateInfo } from '../../../common/protocol/ide-updater';
|
||||
import ProgressBar from '../../components/ProgressBar';
|
||||
|
||||
export type IDEUpdaterComponentProps = {
|
||||
updateInfo: UpdateInfo;
|
||||
windowService: WindowService;
|
||||
downloadFinished?: boolean;
|
||||
downloadStarted?: boolean;
|
||||
progress?: ProgressInfo;
|
||||
error?: Error;
|
||||
onDownload: () => void;
|
||||
onClose: () => void;
|
||||
onSkipVersion: () => void;
|
||||
onCloseAndInstall: () => void;
|
||||
};
|
||||
|
||||
export const IDEUpdaterComponent = ({
|
||||
updateInfo: { version, releaseNotes },
|
||||
downloadStarted = false,
|
||||
downloadFinished = false,
|
||||
windowService,
|
||||
progress,
|
||||
error,
|
||||
onDownload,
|
||||
onClose,
|
||||
onSkipVersion,
|
||||
onCloseAndInstall,
|
||||
}: IDEUpdaterComponentProps): React.ReactElement => {
|
||||
const changelogDivRef = React.useRef() as React.MutableRefObject<
|
||||
HTMLDivElement
|
||||
>;
|
||||
React.useEffect(() => {
|
||||
if (!!releaseNotes) {
|
||||
let changelog: string;
|
||||
if (typeof releaseNotes === 'string') changelog = releaseNotes;
|
||||
else
|
||||
changelog = releaseNotes.reduce((acc, item) => {
|
||||
return item.note ? (acc += `${item.note}\n\n`) : acc;
|
||||
}, '');
|
||||
ReactDOM.render(
|
||||
<ReactMarkdown
|
||||
components={{
|
||||
a: ({ href, children, ...props }) => (
|
||||
<a onClick={() => href && shell.openExternal(href)} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{changelog}
|
||||
</ReactMarkdown>,
|
||||
changelogDivRef.current
|
||||
);
|
||||
}
|
||||
}, [releaseNotes]);
|
||||
const closeButton = (
|
||||
<button onClick={onClose} type="button" className="theia-button secondary">
|
||||
{nls.localize('arduino/ide-updater/notNowButton', 'Not now')}
|
||||
</button>
|
||||
);
|
||||
|
||||
const DownloadCompleted: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--downloaded">
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/versionDownloaded',
|
||||
'Arduino IDE {0} has been downloaded.',
|
||||
version
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/closeToInstallNotice',
|
||||
'Close the software and install the update on your machine.'
|
||||
)}
|
||||
</div>
|
||||
<div className="buttons-container">
|
||||
{closeButton}
|
||||
<button
|
||||
onClick={onCloseAndInstall}
|
||||
type="button"
|
||||
className="theia-button close-and-install"
|
||||
>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/closeAndInstallButton',
|
||||
'Close and Install'
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const DownloadStarted: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--downloading">
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/downloadingNotice',
|
||||
'Downloading the latest version of the Arduino IDE.'
|
||||
)}
|
||||
</div>
|
||||
<ProgressBar percent={progress?.percent} showPercentage />
|
||||
</div>
|
||||
);
|
||||
|
||||
const PreDownload: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--pre-download">
|
||||
<div className="ide-updater-dialog--logo-container">
|
||||
<div className="ide-updater-dialog--logo"></div>
|
||||
</div>
|
||||
<div className="ide-updater-dialog--new-version-text dialogSection">
|
||||
<div className="dialogRow">
|
||||
<div className="bold">
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/updateAvailable',
|
||||
'Update Available'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="dialogRow">
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/newVersionAvailable',
|
||||
'A new version of Arduino IDE ({0}) is available for download.',
|
||||
version
|
||||
)}
|
||||
</div>
|
||||
{releaseNotes && (
|
||||
<div className="dialogRow">
|
||||
<div className="changelog-container" ref={changelogDivRef} />
|
||||
</div>
|
||||
)}
|
||||
<div className="buttons-container">
|
||||
<button
|
||||
onClick={onSkipVersion}
|
||||
type="button"
|
||||
className="theia-button secondary skip-version"
|
||||
>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/skipVersionButton',
|
||||
'Skip Version'
|
||||
)}
|
||||
</button>
|
||||
<div className="push"></div>
|
||||
{closeButton}
|
||||
<button
|
||||
onClick={onDownload}
|
||||
type="button"
|
||||
className="theia-button primary"
|
||||
>
|
||||
{nls.localize('arduino/ide-updater/downloadButton', 'Download')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const onGoToDownloadClick = (
|
||||
event: React.SyntheticEvent<HTMLAnchorElement, Event>
|
||||
) => {
|
||||
const { target } = event.nativeEvent;
|
||||
if (target instanceof HTMLAnchorElement) {
|
||||
event.nativeEvent.preventDefault();
|
||||
windowService.openNewWindow(target.href, { external: true });
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
const GoToDownloadPage: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--go-to-download-page">
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/goToDownloadPage',
|
||||
"An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there."
|
||||
)}
|
||||
</div>
|
||||
<div className="buttons-container">
|
||||
{closeButton}
|
||||
<a
|
||||
className="theia-button primary"
|
||||
href="https://www.arduino.cc/en/software#experimental-software"
|
||||
onClick={onGoToDownloadClick}
|
||||
>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/goToDownloadButton',
|
||||
'Go To Download'
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="ide-updater-dialog--content">
|
||||
{!!error ? (
|
||||
<GoToDownloadPage />
|
||||
) : downloadFinished ? (
|
||||
<DownloadCompleted />
|
||||
) : downloadStarted ? (
|
||||
<DownloadStarted />
|
||||
) : (
|
||||
<PreDownload />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
@@ -0,0 +1,173 @@
|
||||
import * as React from 'react';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||
import { Widget } from '@phosphor/widgets';
|
||||
import { Message } from '@phosphor/messaging';
|
||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||
import { nls } from '@theia/core';
|
||||
import { IDEUpdaterComponent } from './ide-updater-component';
|
||||
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
ProgressInfo,
|
||||
UpdateInfo,
|
||||
} from '../../../common/protocol/ide-updater';
|
||||
import { LocalStorageService } from '@theia/core/lib/browser';
|
||||
import { SKIP_IDE_VERSION } from '../../arduino-frontend-contribution';
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialogWidget extends ReactWidget {
|
||||
protected isOpen = new Object();
|
||||
updateInfo: UpdateInfo;
|
||||
progressInfo: ProgressInfo | undefined;
|
||||
error: Error | undefined;
|
||||
downloadFinished: boolean;
|
||||
downloadStarted: boolean;
|
||||
onClose: () => void;
|
||||
|
||||
@inject(IDEUpdater)
|
||||
protected readonly updater: IDEUpdater;
|
||||
|
||||
@inject(IDEUpdaterClient)
|
||||
protected readonly updaterClient: IDEUpdaterClient;
|
||||
|
||||
@inject(LocalStorageService)
|
||||
protected readonly localStorageService: LocalStorageService;
|
||||
|
||||
@inject(WindowService)
|
||||
protected windowService: WindowService;
|
||||
|
||||
init(updateInfo: UpdateInfo, onClose: () => void): void {
|
||||
this.updateInfo = updateInfo;
|
||||
this.progressInfo = undefined;
|
||||
this.error = undefined;
|
||||
this.downloadStarted = false;
|
||||
this.downloadFinished = false;
|
||||
this.onClose = onClose;
|
||||
|
||||
this.updaterClient.onError((e) => {
|
||||
this.error = e;
|
||||
this.update();
|
||||
});
|
||||
this.updaterClient.onDownloadProgressChanged((e) => {
|
||||
this.progressInfo = e;
|
||||
this.update();
|
||||
});
|
||||
this.updaterClient.onDownloadFinished((e) => {
|
||||
this.downloadFinished = true;
|
||||
this.update();
|
||||
});
|
||||
}
|
||||
|
||||
async onSkipVersion(): Promise<void> {
|
||||
this.localStorageService.setData<string>(
|
||||
SKIP_IDE_VERSION,
|
||||
this.updateInfo.version
|
||||
);
|
||||
this.close();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
super.close();
|
||||
this.onClose();
|
||||
}
|
||||
|
||||
onDispose(): void {
|
||||
if (this.downloadStarted && !this.downloadFinished)
|
||||
this.updater.stopDownload();
|
||||
}
|
||||
|
||||
async onDownload(): Promise<void> {
|
||||
this.progressInfo = undefined;
|
||||
this.downloadStarted = true;
|
||||
this.error = undefined;
|
||||
this.updater.downloadUpdate();
|
||||
this.update();
|
||||
}
|
||||
|
||||
onCloseAndInstall(): void {
|
||||
this.updater.quitAndInstall();
|
||||
}
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return !!this.updateInfo ? (
|
||||
<form>
|
||||
<IDEUpdaterComponent
|
||||
updateInfo={this.updateInfo}
|
||||
windowService={this.windowService}
|
||||
downloadStarted={this.downloadStarted}
|
||||
downloadFinished={this.downloadFinished}
|
||||
progress={this.progressInfo}
|
||||
error={this.error}
|
||||
onClose={this.close.bind(this)}
|
||||
onSkipVersion={this.onSkipVersion.bind(this)}
|
||||
onDownload={this.onDownload.bind(this)}
|
||||
onCloseAndInstall={this.onCloseAndInstall.bind(this)}
|
||||
/>
|
||||
</form>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
||||
@inject(IDEUpdaterDialogWidget)
|
||||
protected readonly widget: IDEUpdaterDialogWidget;
|
||||
|
||||
constructor(
|
||||
@inject(IDEUpdaterDialogProps)
|
||||
protected readonly props: IDEUpdaterDialogProps
|
||||
) {
|
||||
super({
|
||||
title: nls.localize(
|
||||
'arduino/ide-updater/ideUpdaterDialog',
|
||||
'Software Update'
|
||||
),
|
||||
});
|
||||
this.contentNode.classList.add('ide-updater-dialog');
|
||||
this.acceptButton = undefined;
|
||||
}
|
||||
|
||||
get value(): UpdateInfo {
|
||||
return this.widget.updateInfo;
|
||||
}
|
||||
|
||||
protected onAfterAttach(msg: Message): void {
|
||||
if (this.widget.isAttached) {
|
||||
Widget.detach(this.widget);
|
||||
}
|
||||
Widget.attach(this.widget, this.contentNode);
|
||||
super.onAfterAttach(msg);
|
||||
this.update();
|
||||
}
|
||||
|
||||
async open(
|
||||
data: UpdateInfo | undefined = undefined
|
||||
): Promise<UpdateInfo | undefined> {
|
||||
if (data && data.version) {
|
||||
this.widget.init(data, this.close.bind(this));
|
||||
return super.open();
|
||||
}
|
||||
}
|
||||
|
||||
protected onUpdateRequest(msg: Message): void {
|
||||
super.onUpdateRequest(msg);
|
||||
this.widget.update();
|
||||
}
|
||||
|
||||
protected onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
this.widget.activate();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.widget.dispose();
|
||||
super.close();
|
||||
}
|
||||
}
|
@@ -260,18 +260,6 @@ export class SettingsComponent extends React.Component<
|
||||
'Verify code after upload'
|
||||
)}
|
||||
</label>
|
||||
<label className="flex-line">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={this.state.checkForUpdates}
|
||||
onChange={this.checkForUpdatesDidChange}
|
||||
disabled={true}
|
||||
/>
|
||||
{nls.localize(
|
||||
'arduino/preferences/checkForUpdates',
|
||||
'Check for updates on startup'
|
||||
)}
|
||||
</label>
|
||||
<label className="flex-line">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -444,7 +432,9 @@ export class SettingsComponent extends React.Component<
|
||||
);
|
||||
}
|
||||
|
||||
protected noopKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
protected noopKeyDown = (
|
||||
event: React.KeyboardEvent<HTMLInputElement>
|
||||
): void => {
|
||||
if (this.isControlKey(event)) {
|
||||
return;
|
||||
}
|
||||
@@ -454,7 +444,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected numbersOnlyKeyDown = (
|
||||
event: React.KeyboardEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.isControlKey(event)) {
|
||||
return;
|
||||
}
|
||||
@@ -466,7 +456,7 @@ export class SettingsComponent extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
protected browseSketchbookDidClick = async () => {
|
||||
protected browseSketchbookDidClick = async (): Promise<void> => {
|
||||
const uri = await this.props.fileDialogService.showOpenDialog({
|
||||
title: nls.localize(
|
||||
'arduino/preferences/newSketchbookLocation',
|
||||
@@ -483,7 +473,7 @@ export class SettingsComponent extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
protected editAdditionalUrlDidClick = async () => {
|
||||
protected editAdditionalUrlDidClick = async (): Promise<void> => {
|
||||
const additionalUrls = await new AdditionalUrlsDialog(
|
||||
this.state.additionalUrls,
|
||||
this.props.windowService
|
||||
@@ -495,7 +485,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected editorFontSizeDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
const { value } = event.target;
|
||||
if (value) {
|
||||
this.setState({ editorFontSize: parseInt(value, 10) });
|
||||
@@ -504,7 +494,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected additionalUrlsDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({
|
||||
additionalUrls: event.target.value.split(',').map((url) => url.trim()),
|
||||
});
|
||||
@@ -512,13 +502,13 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected autoScaleInterfaceDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ autoScaleInterface: event.target.checked });
|
||||
};
|
||||
|
||||
protected interfaceScaleDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
const { value } = event.target;
|
||||
const percentage = parseInt(value, 10);
|
||||
if (isNaN(percentage)) {
|
||||
@@ -532,31 +522,25 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected verifyAfterUploadDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ verifyAfterUpload: event.target.checked });
|
||||
};
|
||||
|
||||
protected checkForUpdatesDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
this.setState({ checkForUpdates: event.target.checked });
|
||||
};
|
||||
|
||||
protected sketchbookShowAllFilesDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ sketchbookShowAllFiles: event.target.checked });
|
||||
};
|
||||
|
||||
protected autoSaveDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ autoSave: event.target.checked ? 'on' : 'off' });
|
||||
};
|
||||
|
||||
protected quickSuggestionsOtherDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
// need to persist react events through lifecycle https://reactjs.org/docs/events.html#event-pooling
|
||||
const newVal = event.target.checked ? true : false;
|
||||
|
||||
@@ -570,7 +554,9 @@ export class SettingsComponent extends React.Component<
|
||||
});
|
||||
};
|
||||
|
||||
protected themeDidChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
protected themeDidChange = (
|
||||
event: React.ChangeEvent<HTMLSelectElement>
|
||||
): void => {
|
||||
const { selectedIndex } = event.target.options;
|
||||
const theme = ThemeService.get().getThemes()[selectedIndex];
|
||||
if (theme) {
|
||||
@@ -580,14 +566,14 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected languageDidChange = (
|
||||
event: React.ChangeEvent<HTMLSelectElement>
|
||||
) => {
|
||||
): void => {
|
||||
const selectedLanguage = event.target.value;
|
||||
this.setState({ currentLanguage: selectedLanguage });
|
||||
};
|
||||
|
||||
protected compilerWarningsDidChange = (
|
||||
event: React.ChangeEvent<HTMLSelectElement>
|
||||
) => {
|
||||
): void => {
|
||||
const { selectedIndex } = event.target.options;
|
||||
const compilerWarnings = CompilerWarningLiterals[selectedIndex];
|
||||
if (compilerWarnings) {
|
||||
@@ -597,26 +583,28 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected verboseOnCompileDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ verboseOnCompile: event.target.checked });
|
||||
};
|
||||
|
||||
protected verboseOnUploadDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ verboseOnUpload: event.target.checked });
|
||||
};
|
||||
|
||||
protected sketchpathDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
const sketchbookPath = event.target.value;
|
||||
if (sketchbookPath) {
|
||||
this.setState({ sketchbookPath });
|
||||
}
|
||||
};
|
||||
|
||||
protected noProxyDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
protected noProxyDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
): void => {
|
||||
if (event.target.checked) {
|
||||
this.setState({ network: 'none' });
|
||||
} else {
|
||||
@@ -626,7 +614,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected manualProxyDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (event.target.checked) {
|
||||
this.setState({ network: Network.Default() });
|
||||
} else {
|
||||
@@ -636,7 +624,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected httpProtocolDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.protocol = event.target.checked ? 'http' : 'socks';
|
||||
@@ -646,7 +634,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected socksProtocolDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.protocol = event.target.checked ? 'socks' : 'http';
|
||||
@@ -656,7 +644,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected hostnameDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.hostname = event.target.value;
|
||||
@@ -664,7 +652,9 @@ export class SettingsComponent extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
protected portDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
protected portDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.port = event.target.value;
|
||||
@@ -674,7 +664,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected usernameDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.username = event.target.value;
|
||||
@@ -684,7 +674,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected passwordDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.password = event.target.value;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { injectable, inject, postConstruct } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { Deferred, timeout } from '@theia/core/lib/common/promise-util';
|
||||
import { deepClone } from '@theia/core/lib/common/objects';
|
||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||
import { ThemeService } from '@theia/core/lib/browser/theming';
|
||||
@@ -18,24 +18,22 @@ import {
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { AsyncLocalizationProvider } from '@theia/core/lib/common/i18n/localization';
|
||||
|
||||
const EDITOR_SETTING = 'editor';
|
||||
const FONT_SIZE_SETTING = `${EDITOR_SETTING}.fontSize`;
|
||||
const AUTO_SAVE_SETTING = `${EDITOR_SETTING}.autoSave`;
|
||||
const QUICK_SUGGESTIONS_SETTING = `${EDITOR_SETTING}.quickSuggestions`;
|
||||
const ARDUINO_SETTING = 'arduino';
|
||||
const WINDOW_SETTING = `${ARDUINO_SETTING}.window`;
|
||||
// const IDE_SETTING = `${ARDUINO_SETTING}.ide`;
|
||||
const COMPILE_SETTING = `${ARDUINO_SETTING}.compile`;
|
||||
const UPLOAD_SETTING = `${ARDUINO_SETTING}.upload`;
|
||||
const SKETCHBOOK_SETTING = `${ARDUINO_SETTING}.sketchbook`;
|
||||
const AUTO_SCALE_SETTING = `${WINDOW_SETTING}.autoScale`;
|
||||
const ZOOM_LEVEL_SETTING = `${WINDOW_SETTING}.zoomLevel`;
|
||||
// const AUTO_UPDATE_SETTING = `${IDE_SETTING}.autoUpdate`;
|
||||
const COMPILE_VERBOSE_SETTING = `${COMPILE_SETTING}.verbose`;
|
||||
const COMPILE_WARNINGS_SETTING = `${COMPILE_SETTING}.warnings`;
|
||||
const UPLOAD_VERBOSE_SETTING = `${UPLOAD_SETTING}.verbose`;
|
||||
const UPLOAD_VERIFY_SETTING = `${UPLOAD_SETTING}.verify`;
|
||||
const SHOW_ALL_FILES_SETTING = `${SKETCHBOOK_SETTING}.showAllFiles`;
|
||||
export const EDITOR_SETTING = 'editor';
|
||||
export const FONT_SIZE_SETTING = `${EDITOR_SETTING}.fontSize`;
|
||||
export const AUTO_SAVE_SETTING = `${EDITOR_SETTING}.autoSave`;
|
||||
export const QUICK_SUGGESTIONS_SETTING = `${EDITOR_SETTING}.quickSuggestions`;
|
||||
export const ARDUINO_SETTING = 'arduino';
|
||||
export const WINDOW_SETTING = `${ARDUINO_SETTING}.window`;
|
||||
export const COMPILE_SETTING = `${ARDUINO_SETTING}.compile`;
|
||||
export const UPLOAD_SETTING = `${ARDUINO_SETTING}.upload`;
|
||||
export const SKETCHBOOK_SETTING = `${ARDUINO_SETTING}.sketchbook`;
|
||||
export const AUTO_SCALE_SETTING = `${WINDOW_SETTING}.autoScale`;
|
||||
export const ZOOM_LEVEL_SETTING = `${WINDOW_SETTING}.zoomLevel`;
|
||||
export const COMPILE_VERBOSE_SETTING = `${COMPILE_SETTING}.verbose`;
|
||||
export const COMPILE_WARNINGS_SETTING = `${COMPILE_SETTING}.warnings`;
|
||||
export const UPLOAD_VERBOSE_SETTING = `${UPLOAD_SETTING}.verbose`;
|
||||
export const UPLOAD_VERIFY_SETTING = `${UPLOAD_SETTING}.verify`;
|
||||
export const SHOW_ALL_FILES_SETTING = `${SKETCHBOOK_SETTING}.showAllFiles`;
|
||||
|
||||
export interface Settings extends Index {
|
||||
editorFontSize: number; // `editor.fontSize`
|
||||
@@ -48,7 +46,6 @@ export interface Settings extends Index {
|
||||
|
||||
autoScaleInterface: boolean; // `arduino.window.autoScale`
|
||||
interfaceScale: number; // `arduino.window.zoomLevel` https://github.com/eclipse-theia/theia/issues/8751
|
||||
checkForUpdates?: boolean; // `arduino.ide.autoUpdate`
|
||||
verboseOnCompile: boolean; // `arduino.compile.verbose`
|
||||
compilerWarnings: CompilerWarnings; // `arduino.compile.warnings`
|
||||
verboseOnUpload: boolean; // `arduino.upload.verbose`
|
||||
@@ -93,7 +90,6 @@ export class SettingsService {
|
||||
|
||||
@postConstruct()
|
||||
protected async init(): Promise<void> {
|
||||
await this.appStateService.reachedState('ready'); // Hack for https://github.com/eclipse-theia/theia/issues/8993
|
||||
const settings = await this.loadSettings();
|
||||
this._settings = deepClone(settings);
|
||||
this.ready.resolve();
|
||||
@@ -110,7 +106,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -135,7 +130,6 @@ export class SettingsService {
|
||||
}),
|
||||
this.preferenceService.get<boolean>(AUTO_SCALE_SETTING, true),
|
||||
this.preferenceService.get<number>(ZOOM_LEVEL_SETTING, 0),
|
||||
// this.preferenceService.get<string>(AUTO_UPDATE_SETTING, true),
|
||||
this.preferenceService.get<boolean>(COMPILE_VERBOSE_SETTING, true),
|
||||
this.preferenceService.get<any>(COMPILE_WARNINGS_SETTING, 'None'),
|
||||
this.preferenceService.get<boolean>(UPLOAD_VERBOSE_SETTING, true),
|
||||
@@ -154,7 +148,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -224,6 +217,11 @@ export class SettingsService {
|
||||
}
|
||||
}
|
||||
|
||||
private async savePreference(name: string, value: unknown): Promise<void> {
|
||||
await this.preferenceService.set(name, value, PreferenceScope.User);
|
||||
await timeout(5);
|
||||
}
|
||||
|
||||
async save(): Promise<string | true> {
|
||||
await this.ready.promise;
|
||||
const {
|
||||
@@ -234,7 +232,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -253,70 +250,29 @@ export class SettingsService {
|
||||
(config as any).network = network;
|
||||
(config as any).locale = currentLanguage;
|
||||
|
||||
await Promise.all([
|
||||
this.preferenceService.set(
|
||||
'editor.fontSize',
|
||||
editorFontSize,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
'workbench.colorTheme',
|
||||
themeId,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
'editor.autoSave',
|
||||
autoSave,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
'editor.quickSuggestions',
|
||||
quickSuggestions,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
AUTO_SCALE_SETTING,
|
||||
autoScaleInterface,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
ZOOM_LEVEL_SETTING,
|
||||
interfaceScale,
|
||||
PreferenceScope.User
|
||||
),
|
||||
// this.preferenceService.set(AUTO_UPDATE_SETTING, checkForUpdates, PreferenceScope.User),
|
||||
this.preferenceService.set(
|
||||
COMPILE_VERBOSE_SETTING,
|
||||
verboseOnCompile,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
COMPILE_WARNINGS_SETTING,
|
||||
compilerWarnings,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
UPLOAD_VERBOSE_SETTING,
|
||||
verboseOnUpload,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
UPLOAD_VERIFY_SETTING,
|
||||
verifyAfterUpload,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
SHOW_ALL_FILES_SETTING,
|
||||
sketchbookShowAllFiles,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.configService.setConfiguration(config),
|
||||
]);
|
||||
await this.savePreference('editor.fontSize', editorFontSize);
|
||||
await this.savePreference('workbench.colorTheme', themeId);
|
||||
await this.savePreference('editor.autoSave', autoSave);
|
||||
await this.savePreference('editor.quickSuggestions', quickSuggestions);
|
||||
await this.savePreference(AUTO_SCALE_SETTING, autoScaleInterface);
|
||||
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
||||
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
||||
await this.savePreference(COMPILE_VERBOSE_SETTING, verboseOnCompile);
|
||||
await this.savePreference(COMPILE_WARNINGS_SETTING, compilerWarnings);
|
||||
await this.savePreference(UPLOAD_VERBOSE_SETTING, verboseOnUpload);
|
||||
await this.savePreference(UPLOAD_VERIFY_SETTING, verifyAfterUpload);
|
||||
await this.savePreference(SHOW_ALL_FILES_SETTING, sketchbookShowAllFiles);
|
||||
await this.configService.setConfiguration(config);
|
||||
this.onDidChangeEmitter.fire(this._settings);
|
||||
|
||||
// after saving all the settings, if we need to change the language we need to perform a reload
|
||||
if (currentLanguage !== nls.locale) {
|
||||
window.localStorage.setItem(nls.localeId, currentLanguage);
|
||||
// Only reload if the language differs from the current locale. `nls.locale === undefined` signals english as well
|
||||
if (currentLanguage !== nls.locale && !(currentLanguage === 'en' && nls.locale === undefined)) {
|
||||
if (currentLanguage === 'en') {
|
||||
window.localStorage.removeItem(nls.localeId);
|
||||
} else {
|
||||
window.localStorage.setItem(nls.localeId, currentLanguage);
|
||||
}
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,40 @@
|
||||
import { Emitter } from '@theia/core';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { UpdateInfo, ProgressInfo } from 'electron-updater';
|
||||
import { IDEUpdaterClient } from '../../common/protocol/ide-updater';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterClientImpl implements IDEUpdaterClient {
|
||||
protected readonly onErrorEmitter = new Emitter<Error>();
|
||||
protected readonly onCheckingForUpdateEmitter = new Emitter<void>();
|
||||
protected readonly onUpdateAvailableEmitter = new Emitter<UpdateInfo>();
|
||||
protected readonly onUpdateNotAvailableEmitter = new Emitter<UpdateInfo>();
|
||||
protected readonly onDownloadProgressEmitter = new Emitter<ProgressInfo>();
|
||||
protected readonly onDownloadFinishedEmitter = new Emitter<UpdateInfo>();
|
||||
|
||||
readonly onError = this.onErrorEmitter.event;
|
||||
readonly onCheckingForUpdate = this.onCheckingForUpdateEmitter.event;
|
||||
readonly onUpdateAvailable = this.onUpdateAvailableEmitter.event;
|
||||
readonly onUpdateNotAvailable = this.onUpdateNotAvailableEmitter.event;
|
||||
readonly onDownloadProgressChanged = this.onDownloadProgressEmitter.event;
|
||||
readonly onDownloadFinished = this.onDownloadFinishedEmitter.event;
|
||||
|
||||
notifyError(message: Error): void {
|
||||
this.onErrorEmitter.fire(message);
|
||||
}
|
||||
notifyCheckingForUpdate(message: void): void {
|
||||
this.onCheckingForUpdateEmitter.fire(message);
|
||||
}
|
||||
notifyUpdateAvailable(message: UpdateInfo): void {
|
||||
this.onUpdateAvailableEmitter.fire(message);
|
||||
}
|
||||
notifyUpdateNotAvailable(message: UpdateInfo): void {
|
||||
this.onUpdateNotAvailableEmitter.fire(message);
|
||||
}
|
||||
notifyDownloadProgressChanged(message: ProgressInfo): void {
|
||||
this.onDownloadProgressEmitter.fire(message);
|
||||
}
|
||||
notifyDownloadFinished(message: UpdateInfo): void {
|
||||
this.onDownloadFinishedEmitter.fire(message);
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
Command,
|
||||
CommandContribution,
|
||||
CommandRegistry,
|
||||
MessageService,
|
||||
nls,
|
||||
} from '@theia/core';
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { IDEUpdater, UpdateInfo } from '../../common/protocol/ide-updater';
|
||||
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterCommands implements CommandContribution {
|
||||
constructor(
|
||||
@inject(IDEUpdater)
|
||||
private readonly updater: IDEUpdater,
|
||||
@inject(MessageService)
|
||||
protected readonly messageService: MessageService,
|
||||
@inject(IDEUpdaterDialog)
|
||||
protected readonly updaterDialog: IDEUpdaterDialog
|
||||
) {}
|
||||
|
||||
registerCommands(registry: CommandRegistry): void {
|
||||
registry.registerCommand(IDEUpdaterCommands.CHECK_FOR_UPDATES, {
|
||||
execute: this.checkForUpdates.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
async checkForUpdates(initialCheck?: boolean): Promise<UpdateInfo | void> {
|
||||
try {
|
||||
const updateInfo = await this.updater.checkForUpdates(initialCheck);
|
||||
if (!!updateInfo) {
|
||||
this.updaterDialog.open(updateInfo);
|
||||
} else {
|
||||
this.messageService.info(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/noUpdatesAvailable',
|
||||
'There are no recent updates available for the Arduino IDE'
|
||||
)
|
||||
);
|
||||
}
|
||||
return updateInfo;
|
||||
} catch (e) {
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/errorCheckingForUpdates',
|
||||
'Error while checking for Arduino IDE updates.\n{0}',
|
||||
e.message
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
export namespace IDEUpdaterCommands {
|
||||
export const CHECK_FOR_UPDATES: Command = {
|
||||
id: 'arduino-ide-check-for-updates',
|
||||
category: 'Arduino',
|
||||
label: 'Check for Arduino IDE updates',
|
||||
};
|
||||
}
|
@@ -10,7 +10,7 @@ import { SerialModel } from '../serial-model';
|
||||
import { ArduinoMenus } from '../../menu/arduino-menus';
|
||||
import { Contribution } from '../../contributions/contribution';
|
||||
import { Endpoint, FrontendApplication } from '@theia/core/lib/browser';
|
||||
import { ipcRenderer } from '@theia/core/shared/electron';
|
||||
import { ipcRenderer } from '@theia/electron/shared/electron';
|
||||
import { SerialConfig } from '../../../common/protocol';
|
||||
import { SerialConnectionManager } from '../serial-connection-manager';
|
||||
import { SerialPlotter } from './protocol';
|
||||
|
BIN
arduino-ide-extension/src/browser/style/ide-logo.png
Normal file
BIN
arduino-ide-extension/src/browser/style/ide-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,78 @@
|
||||
.ide-updater-dialog {
|
||||
width: 546px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--pre-download {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--logo-container {
|
||||
margin-right: 28px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--logo {
|
||||
background: url('./ide-logo.png') round;
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
.dialogContent.ide-updater-dialog
|
||||
.ide-updater-dialog--content
|
||||
.ide-updater-dialog--new-version-text.dialogSection {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container {
|
||||
background: white;
|
||||
border: 1px solid #dae3e3;
|
||||
border-radius: 2px;
|
||||
font-size: 12px;
|
||||
height: 180px;
|
||||
overflow: auto;
|
||||
padding: 0 12px;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container a {
|
||||
color: #018184;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container a:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container code {
|
||||
background: #ecf1f1;
|
||||
border-radius: 2px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container a code {
|
||||
color: #018184;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container a.theia-button {
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container a.theia-button:hover {
|
||||
color: var(--theia-button-foreground);
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container .push {
|
||||
margin-right: auto;
|
||||
}
|
@@ -9,6 +9,7 @@
|
||||
@import './editor.css';
|
||||
@import './settings-dialog.css';
|
||||
@import './firmware-uploader-dialog.css';
|
||||
@import './ide-updater-dialog.css';
|
||||
@import './certificate-uploader-dialog.css';
|
||||
@import './user-fields-dialog.css';
|
||||
@import './debug.css';
|
||||
@@ -16,6 +17,7 @@
|
||||
@import './cloud-sketchbook.css';
|
||||
@import './fonts.css';
|
||||
@import './custom-codicon.css';
|
||||
@import './progress-bar.css';
|
||||
|
||||
.theia-input.warning:focus {
|
||||
outline-width: 1px;
|
||||
|
32
arduino-ide-extension/src/browser/style/progress-bar.css
Normal file
32
arduino-ide-extension/src/browser/style/progress-bar.css
Normal file
@@ -0,0 +1,32 @@
|
||||
.progress-bar {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.progress-bar--outer {
|
||||
background: #e5e5e5;
|
||||
border-radius: 11px;
|
||||
height: 6px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar--inner {
|
||||
transition: width 1s;
|
||||
height: 100%;
|
||||
background: #008184;
|
||||
border-radius: 11px;
|
||||
}
|
||||
|
||||
.progress-bar--percentage {
|
||||
align-items: flex-end;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-bar--percentage-text {
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
}
|
@@ -62,9 +62,15 @@ export class DebugSessionManager extends TheiaDebugSessionManager {
|
||||
}
|
||||
);
|
||||
}
|
||||
// TODO: remove as https://github.com/eclipse-theia/theia/issues/10164 is fixed
|
||||
async terminateSessions(): Promise<void> {
|
||||
await super.terminateSessions();
|
||||
this.destroy(this.currentSession?.id);
|
||||
async terminateSession(session?: DebugSession): Promise<void> {
|
||||
if (!session) {
|
||||
this.updateCurrentSession(this._currentSession);
|
||||
session = this._currentSession;
|
||||
}
|
||||
// The cortex-debug extension does not respond to close requests
|
||||
// So we simply terminate the debug session immediately
|
||||
// Alternatively the `super.terminateSession` call will terminate it after 5 seconds without a response
|
||||
await this.debug.terminateDebugSession(session!.id);
|
||||
await super.terminateSession(session);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/workspace-delete-handler';
|
||||
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { injectable, inject } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
@@ -18,6 +19,7 @@ import { ArduinoWorkspaceRootResolver } from '../../arduino-workspace-resolver';
|
||||
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
||||
import { BoardsConfig } from '../../boards/boards-config';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { URI as VSCodeUri } from '@theia/core/shared/vscode-uri';
|
||||
|
||||
@injectable()
|
||||
export class WorkspaceService extends TheiaWorkspaceService {
|
||||
@@ -67,7 +69,7 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
this.workspaceUri = (async () => {
|
||||
try {
|
||||
const hash = window.location.hash;
|
||||
const [recentWorkspaces, recentSketches] = await Promise.all([
|
||||
const [recentWorkspacesPaths, recentSketches] = await Promise.all([
|
||||
this.server.getRecentWorkspaces(),
|
||||
this.sketchService
|
||||
.getSketches({})
|
||||
@@ -75,6 +77,10 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
SketchContainer.toArray(container).map((s) => s.uri)
|
||||
),
|
||||
]);
|
||||
// On Dindows, `getRecentWorkspaces` returns only file paths, not URIs as expected by the `isValid` method.
|
||||
const recentWorkspaces = recentWorkspacesPaths.map((e) =>
|
||||
VSCodeUri.file(e).toString()
|
||||
);
|
||||
const toOpen = await new ArduinoWorkspaceRootResolver({
|
||||
isValid: this.isValid.bind(this),
|
||||
}).resolve({ hash, recentWorkspaces, recentSketches });
|
||||
@@ -124,6 +130,8 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
}: FocusTracker.IChangedArgs<Widget>): void {
|
||||
if (newValue instanceof EditorWidget) {
|
||||
const { uri } = newValue.editor;
|
||||
const currentWindow = remote.getCurrentWindow();
|
||||
currentWindow.setRepresentedFilename(uri.path.toString());
|
||||
if (Sketch.isSketchFile(uri.toString())) {
|
||||
this.updateTitle();
|
||||
} else {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
@@ -80,7 +80,7 @@ export class SketchbookWidgetContribution
|
||||
}
|
||||
|
||||
onStart(): void {
|
||||
this.shell.currentChanged.connect(() =>
|
||||
this.shell.onDidChangeCurrentWidget(() =>
|
||||
this.onCurrentWidgetChangedHandler()
|
||||
);
|
||||
|
||||
|
71
arduino-ide-extension/src/common/protocol/ide-updater.ts
Normal file
71
arduino-ide-extension/src/common/protocol/ide-updater.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { JsonRpcServer } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||
import { Event } from '@theia/core/lib/common/event';
|
||||
import { UpdateChannel } from '../../browser/arduino-preferences';
|
||||
|
||||
export interface ProgressInfo {
|
||||
total: number;
|
||||
delta: number;
|
||||
transferred: number;
|
||||
percent: number;
|
||||
bytesPerSecond: number;
|
||||
}
|
||||
|
||||
export interface ReleaseNoteInfo {
|
||||
readonly version: string;
|
||||
readonly note: string | null;
|
||||
}
|
||||
|
||||
export interface BlockMapDataHolder {
|
||||
size?: number;
|
||||
blockMapSize?: number;
|
||||
readonly sha512: string;
|
||||
readonly isAdminRightsRequired?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateFileInfo extends BlockMapDataHolder {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export type UpdateInfo = {
|
||||
readonly version: string;
|
||||
readonly files: Array<UpdateFileInfo>;
|
||||
releaseName?: string | null;
|
||||
releaseNotes?: string | Array<ReleaseNoteInfo> | null;
|
||||
releaseDate: string;
|
||||
readonly stagingPercentage?: number;
|
||||
};
|
||||
|
||||
export interface ProgressInfo {
|
||||
total: number;
|
||||
delta: number;
|
||||
transferred: number;
|
||||
percent: number;
|
||||
bytesPerSecond: number;
|
||||
}
|
||||
|
||||
export const IDEUpdaterPath = '/services/ide-updater';
|
||||
export const IDEUpdater = Symbol('IDEUpdater');
|
||||
export interface IDEUpdater extends JsonRpcServer<IDEUpdaterClient> {
|
||||
init(channel: UpdateChannel, baseUrl: string): Promise<void>;
|
||||
checkForUpdates(initialCheck?: boolean): Promise<UpdateInfo | void>;
|
||||
downloadUpdate(): Promise<void>;
|
||||
quitAndInstall(): void;
|
||||
stopDownload(): void;
|
||||
disconnectClient(client: IDEUpdaterClient): void;
|
||||
}
|
||||
|
||||
export const IDEUpdaterClient = Symbol('IDEUpdaterClient');
|
||||
export interface IDEUpdaterClient {
|
||||
onError: Event<Error>;
|
||||
onCheckingForUpdate: Event<void>;
|
||||
onUpdateAvailable: Event<UpdateInfo>;
|
||||
onUpdateNotAvailable: Event<UpdateInfo>;
|
||||
onDownloadProgressChanged: Event<ProgressInfo>;
|
||||
onDownloadFinished: Event<UpdateInfo>;
|
||||
notifyError(message: Error): void;
|
||||
notifyCheckingForUpdate(message: void): void;
|
||||
notifyUpdateAvailable(message: UpdateInfo): void;
|
||||
notifyUpdateNotAvailable(message: UpdateInfo): void;
|
||||
notifyDownloadProgressChanged(message: ProgressInfo): void;
|
||||
notifyDownloadFinished(message: UpdateInfo): void;
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import {
|
||||
ConnectionStatus,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { isOSX } from '@theia/core/lib/common/os';
|
||||
import { Keybinding } from '@theia/core/lib/common/keybinding';
|
||||
import {
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
ArduinoMenus,
|
||||
PlaceholderMenuNode,
|
||||
} from '../../../browser/menu/arduino-menus';
|
||||
import electron = require('@theia/core/shared/electron');
|
||||
|
||||
@injectable()
|
||||
export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
@@ -35,9 +34,9 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
await this.preferencesService.ready;
|
||||
const createdMenuBar = this.createElectronMenuBar();
|
||||
if (isOSX) {
|
||||
electron.remote.Menu.setApplicationMenu(createdMenuBar);
|
||||
remote.Menu.setApplicationMenu(createdMenuBar);
|
||||
} else {
|
||||
electron.remote.getCurrentWindow().setMenu(createdMenuBar);
|
||||
remote.getCurrentWindow().setMenu(createdMenuBar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +80,7 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
protected createOSXMenu(): Electron.MenuItemConstructorOptions {
|
||||
const { submenu } = super.createOSXMenu();
|
||||
const label = 'Arduino IDE';
|
||||
if (!!submenu && !(submenu instanceof remote.Menu)) {
|
||||
if (!!submenu && Array.isArray(submenu)) {
|
||||
const [, , /* about */ /* preferences */ ...rest] = submenu;
|
||||
const about = this.fillMenuTemplate(
|
||||
[],
|
||||
|
@@ -2,7 +2,10 @@ import { ContainerModule } from 'inversify';
|
||||
import { JsonRpcConnectionHandler } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||
import { ElectronConnectionHandler } from '@theia/core/lib/electron-common/messaging/electron-connection-handler';
|
||||
import { ElectronMainWindowService } from '@theia/core/lib/electron-common/electron-main-window-service';
|
||||
import { ElectronMainApplication as TheiaElectronMainApplication } from '@theia/core/lib/electron-main/electron-main-application';
|
||||
import {
|
||||
ElectronMainApplication as TheiaElectronMainApplication,
|
||||
ElectronMainApplicationContribution,
|
||||
} from '@theia/core/lib/electron-main/electron-main-application';
|
||||
import {
|
||||
SplashService,
|
||||
splashServicePath,
|
||||
@@ -10,6 +13,12 @@ import {
|
||||
import { SplashServiceImpl } from './splash/splash-service-impl';
|
||||
import { ElectronMainApplication } from './theia/electron-main-application';
|
||||
import { ElectronMainWindowServiceImpl } from './theia/electron-main-window-service';
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
IDEUpdaterPath,
|
||||
} from '../common/protocol/ide-updater';
|
||||
import { IDEUpdaterImpl } from './ide-updater/ide-updater-impl';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(ElectronMainApplication).toSelf().inSingletonScope();
|
||||
@@ -28,4 +37,23 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
)
|
||||
)
|
||||
.inSingletonScope();
|
||||
|
||||
// IDE updater bindings
|
||||
bind(IDEUpdaterImpl).toSelf().inSingletonScope();
|
||||
bind(IDEUpdater).toService(IDEUpdaterImpl);
|
||||
bind(ElectronMainApplicationContribution).toService(IDEUpdater);
|
||||
bind(ElectronConnectionHandler)
|
||||
.toDynamicValue(
|
||||
(context) =>
|
||||
new JsonRpcConnectionHandler<IDEUpdaterClient>(
|
||||
IDEUpdaterPath,
|
||||
(client) => {
|
||||
const server = context.container.get<IDEUpdater>(IDEUpdater);
|
||||
server.setClient(client);
|
||||
client.onDidCloseConnection(() => server.disconnectClient(client));
|
||||
return server;
|
||||
}
|
||||
)
|
||||
)
|
||||
.inSingletonScope();
|
||||
});
|
||||
|
@@ -0,0 +1,131 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { UpdateInfo, CancellationToken, autoUpdater } from 'electron-updater';
|
||||
import fetch, { Response } from 'node-fetch';
|
||||
import { UpdateChannel } from '../../browser/arduino-preferences';
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
} from '../../common/protocol/ide-updater';
|
||||
|
||||
const CHANGELOG_BASE_URL = 'https://downloads.arduino.cc/arduino-ide/changelog';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterImpl implements IDEUpdater {
|
||||
private isAlreadyChecked = false;
|
||||
private updater = autoUpdater;
|
||||
private cancellationToken?: CancellationToken;
|
||||
protected theiaFEClient?: IDEUpdaterClient;
|
||||
protected clients: Array<IDEUpdaterClient> = [];
|
||||
|
||||
constructor() {
|
||||
this.updater.on('checking-for-update', (e) => {
|
||||
this.clients.forEach((c) => c.notifyCheckingForUpdate(e));
|
||||
});
|
||||
this.updater.on('update-available', (e) => {
|
||||
this.clients.forEach((c) => c.notifyUpdateAvailable(e));
|
||||
});
|
||||
this.updater.on('update-not-available', (e) => {
|
||||
this.clients.forEach((c) => c.notifyUpdateNotAvailable(e));
|
||||
});
|
||||
this.updater.on('download-progress', (e) => {
|
||||
this.clients.forEach((c) => c.notifyDownloadProgressChanged(e));
|
||||
});
|
||||
this.updater.on('update-downloaded', (e) => {
|
||||
this.clients.forEach((c) => c.notifyDownloadFinished(e));
|
||||
});
|
||||
this.updater.on('error', (e) => {
|
||||
this.clients.forEach((c) => c.notifyError(e));
|
||||
});
|
||||
}
|
||||
|
||||
async init(channel: UpdateChannel, baseUrl: string): Promise<void> {
|
||||
this.updater.autoDownload = false;
|
||||
this.updater.channel = channel;
|
||||
this.updater.setFeedURL({
|
||||
provider: 'generic',
|
||||
url: `${baseUrl}/${channel === UpdateChannel.Nightly ? 'nightly' : ''}`,
|
||||
channel,
|
||||
});
|
||||
}
|
||||
|
||||
setClient(client: IDEUpdaterClient | undefined): void {
|
||||
if (client) this.clients.push(client);
|
||||
}
|
||||
|
||||
async checkForUpdates(initialCheck?: boolean): Promise<UpdateInfo | void> {
|
||||
if (initialCheck) {
|
||||
if (this.isAlreadyChecked) return Promise.resolve();
|
||||
this.isAlreadyChecked = true;
|
||||
}
|
||||
|
||||
const {
|
||||
updateInfo,
|
||||
cancellationToken,
|
||||
} = await this.updater.checkForUpdates();
|
||||
|
||||
this.cancellationToken = cancellationToken;
|
||||
if (this.updater.currentVersion.compare(updateInfo.version) === -1) {
|
||||
/*
|
||||
'latest.txt' points to the latest changelog that has been generated by the CI,
|
||||
so we need to make a first GET request to get the filename of the changelog
|
||||
and a second GET to the actual changelog file
|
||||
*/
|
||||
try {
|
||||
let response: Response | null = await fetch(
|
||||
`${CHANGELOG_BASE_URL}/latest.txt`
|
||||
);
|
||||
const latestChangelogFileName = response.ok
|
||||
? await response.text()
|
||||
: null;
|
||||
response = latestChangelogFileName
|
||||
? await fetch(`${CHANGELOG_BASE_URL}/${latestChangelogFileName}`)
|
||||
: null;
|
||||
const changelog = response?.ok ? await response?.text() : null;
|
||||
|
||||
// We only want to see the release notes of newer versions
|
||||
const currentVersionIndex = changelog?.indexOf(
|
||||
`\r\n\r\n---\r\n\r\n## ${this.updater.currentVersion}\r\n\r\n`
|
||||
);
|
||||
const newChangelog =
|
||||
currentVersionIndex && currentVersionIndex > 0
|
||||
? changelog?.slice(0, currentVersionIndex)
|
||||
: changelog;
|
||||
updateInfo.releaseNotes = newChangelog;
|
||||
} catch {
|
||||
/*
|
||||
if the request for the changelog fails, we'll just avoid to show it
|
||||
to the user, but we will still show the update info
|
||||
*/
|
||||
}
|
||||
return updateInfo;
|
||||
}
|
||||
}
|
||||
|
||||
async downloadUpdate(): Promise<void> {
|
||||
try {
|
||||
await this.updater.downloadUpdate(this.cancellationToken);
|
||||
} catch (e) {
|
||||
if (e.message === 'cancelled') return;
|
||||
this.clients.forEach((c) => c.notifyError(e));
|
||||
}
|
||||
}
|
||||
|
||||
stopDownload(): void {
|
||||
this.cancellationToken?.cancel();
|
||||
}
|
||||
|
||||
quitAndInstall(): void {
|
||||
this.updater.quitAndInstall();
|
||||
}
|
||||
|
||||
disconnectClient(client: IDEUpdaterClient): void {
|
||||
const index = this.clients.indexOf(client);
|
||||
if (index !== -1) {
|
||||
this.clients.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.clients.forEach(this.disconnectClient.bind(this));
|
||||
}
|
||||
}
|
@@ -1,29 +1,44 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import {
|
||||
app,
|
||||
BrowserWindow,
|
||||
BrowserWindowConstructorOptions,
|
||||
screen,
|
||||
} from 'electron';
|
||||
import { app, BrowserWindow, BrowserWindowConstructorOptions, ipcMain, screen, Event as ElectronEvent } from '@theia/core/electron-shared/electron';
|
||||
import { fork } from 'child_process';
|
||||
import { AddressInfo } from 'net';
|
||||
import { join } from 'path';
|
||||
import { join, dirname } from 'path';
|
||||
import * as fs from 'fs-extra';
|
||||
import { initSplashScreen } from '../splash/splash-screen';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token';
|
||||
import { FrontendApplicationConfig } from '@theia/application-package/lib/application-props';
|
||||
import {
|
||||
ElectronMainApplication as TheiaElectronMainApplication,
|
||||
ElectronMainExecutionParams,
|
||||
TheiaBrowserWindowOptions,
|
||||
} from '@theia/core/lib/electron-main/electron-main-application';
|
||||
import { SplashServiceImpl } from '../splash/splash-service-impl';
|
||||
import { ipcMain } from '@theia/core/shared/electron';
|
||||
import { URI } from '@theia/core/shared/vscode-uri';
|
||||
import * as electronRemoteMain from '@theia/core/electron-shared/@electron/remote/main';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import * as os from '@theia/core/lib/common/os';
|
||||
|
||||
app.commandLine.appendSwitch('disable-http-cache');
|
||||
|
||||
interface WorkspaceOptions {
|
||||
file: string
|
||||
x: number
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
isMaximized: boolean
|
||||
isFullScreen: boolean
|
||||
time: number
|
||||
}
|
||||
|
||||
const WORKSPACES = 'workspaces';
|
||||
|
||||
@injectable()
|
||||
export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
protected _windows: BrowserWindow[] = [];
|
||||
protected startup = false;
|
||||
protected openFilePromise = new Deferred();
|
||||
|
||||
@inject(SplashServiceImpl)
|
||||
protected readonly splashService: SplashServiceImpl;
|
||||
@@ -33,9 +48,106 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
// See: https://github.com/electron-userland/electron-builder/issues/2468
|
||||
// Regression in Theia: https://github.com/eclipse-theia/theia/issues/8701
|
||||
app.on('ready', () => app.setName(config.applicationName));
|
||||
this.attachFileAssociations();
|
||||
return super.start(config);
|
||||
}
|
||||
|
||||
attachFileAssociations() {
|
||||
// OSX: register open-file event
|
||||
if (os.isOSX) {
|
||||
app.on('open-file', async (event, uri) => {
|
||||
event.preventDefault();
|
||||
if (uri.endsWith('.ino') && await fs.pathExists(uri)) {
|
||||
this.openFilePromise.reject();
|
||||
await this.openSketch(dirname(uri));
|
||||
}
|
||||
});
|
||||
setTimeout(() => this.openFilePromise.resolve(), 500);
|
||||
} else {
|
||||
this.openFilePromise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
protected async isValidSketchPath(uri: string): Promise<boolean | undefined> {
|
||||
return typeof uri === 'string' && await fs.pathExists(uri);
|
||||
}
|
||||
|
||||
protected async launch(params: ElectronMainExecutionParams): Promise<void> {
|
||||
try {
|
||||
// When running on MacOS, we either have to wait until
|
||||
// 1. The `open-file` command has been received by the app, rejecting the promise
|
||||
// 2. A short timeout resolves the promise automatically, falling back to the usual app launch
|
||||
await this.openFilePromise.promise;
|
||||
} catch {
|
||||
// Application has received the `open-file` event and will skip the default application launch
|
||||
return;
|
||||
}
|
||||
|
||||
if (!os.isOSX && await this.launchFromArgs(params)) {
|
||||
// Application has received a file in its arguments and will skip the default application launch
|
||||
return;
|
||||
}
|
||||
|
||||
this.startup = true;
|
||||
const workspaces: WorkspaceOptions[] | undefined = this.electronStore.get(WORKSPACES);
|
||||
let useDefault = true;
|
||||
if (workspaces && workspaces.length > 0) {
|
||||
for (const workspace of workspaces) {
|
||||
if (await this.isValidSketchPath(workspace.file)) {
|
||||
useDefault = false;
|
||||
await this.openSketch(workspace);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.startup = false;
|
||||
if (useDefault) {
|
||||
super.launch(params);
|
||||
}
|
||||
}
|
||||
|
||||
protected async launchFromArgs(params: ElectronMainExecutionParams): Promise<boolean> {
|
||||
// Copy to prevent manipulation of original array
|
||||
const argCopy = [...params.argv];
|
||||
let uri: string | undefined;
|
||||
for (const possibleUri of argCopy) {
|
||||
if (possibleUri.endsWith('.ino') && await this.isValidSketchPath(possibleUri)) {
|
||||
uri = possibleUri;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uri) {
|
||||
await this.openSketch(dirname(uri));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected async openSketch(workspace: WorkspaceOptions | string): Promise<BrowserWindow> {
|
||||
const options = await this.getLastWindowOptions();
|
||||
let file: string;
|
||||
if (typeof workspace === 'object') {
|
||||
options.x = workspace.x;
|
||||
options.y = workspace.y;
|
||||
options.width = workspace.width;
|
||||
options.height = workspace.height;
|
||||
options.isMaximized = workspace.isMaximized;
|
||||
options.isFullScreen = workspace.isFullScreen;
|
||||
file = workspace.file;
|
||||
} else {
|
||||
file = workspace;
|
||||
}
|
||||
const [uri, electronWindow] = await Promise.all([this.createWindowUri(), this.createWindow(options)]);
|
||||
electronWindow.loadURL(uri.withFragment(encodeURI(file)).toString(true));
|
||||
return electronWindow;
|
||||
}
|
||||
|
||||
protected avoidOverlap(options: TheiaBrowserWindowOptions): TheiaBrowserWindowOptions {
|
||||
if (this.startup) {
|
||||
return options;
|
||||
}
|
||||
return super.avoidOverlap(options);
|
||||
}
|
||||
|
||||
protected getTitleBarStyle(): 'native' | 'custom' {
|
||||
return 'native';
|
||||
}
|
||||
@@ -50,6 +162,14 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
});
|
||||
}
|
||||
|
||||
protected async onSecondInstance(event: ElectronEvent, argv: string[], cwd: string): Promise<void> {
|
||||
if (!os.isOSX && await this.launchFromArgs({ cwd, argv, secondInstance: true })) {
|
||||
// Application has received a file in its arguments
|
||||
return;
|
||||
}
|
||||
super.onSecondInstance(event, argv, cwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this rather than creating `BrowserWindow` instances from scratch, since some security parameters need to be set, this method will do it.
|
||||
*
|
||||
@@ -148,10 +268,12 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
}
|
||||
}
|
||||
});
|
||||
this.attachClosedWorkspace(electronWindow);
|
||||
this.attachReadyToShow(electronWindow);
|
||||
this.attachSaveWindowState(electronWindow);
|
||||
this.attachGlobalShortcuts(electronWindow);
|
||||
this.restoreMaximizedState(electronWindow, options);
|
||||
electronRemoteMain.enable(electronWindow.webContents);
|
||||
return electronWindow;
|
||||
}
|
||||
|
||||
@@ -218,6 +340,44 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
}
|
||||
}
|
||||
|
||||
protected closedWorkspaces: WorkspaceOptions[] = [];
|
||||
|
||||
protected attachClosedWorkspace(window: BrowserWindow): void {
|
||||
// Since the `before-quit` event is only fired when closing the *last* window
|
||||
// We need to keep track of recently closed windows/workspaces manually
|
||||
window.on('close', () => {
|
||||
const url = window.webContents.getURL();
|
||||
const workspace = URI.parse(url).fragment;
|
||||
if (workspace) {
|
||||
const workspaceUri = URI.file(workspace);
|
||||
const bounds = window.getNormalBounds();
|
||||
this.closedWorkspaces.push({
|
||||
...bounds,
|
||||
isMaximized: window.isMaximized(),
|
||||
isFullScreen: window.isFullScreen(),
|
||||
file: workspaceUri.fsPath,
|
||||
time: Date.now()
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected onWillQuit(event: Electron.Event): void {
|
||||
// Only add workspaces which were closed within the last second (1000 milliseconds)
|
||||
const threshold = Date.now() - 1000;
|
||||
const visited = new Set<string>();
|
||||
const workspaces = this.closedWorkspaces.filter(e => {
|
||||
if (e.time < threshold || visited.has(e.file)) {
|
||||
return false;
|
||||
}
|
||||
visited.add(e.file);
|
||||
return true;
|
||||
}).sort((a, b) => a.file.localeCompare(b.file));
|
||||
this.electronStore.set(WORKSPACES, workspaces);
|
||||
|
||||
super.onWillQuit(event);
|
||||
}
|
||||
|
||||
get windows(): BrowserWindow[] {
|
||||
return this._windows.slice();
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import * as cc_arduino_cli_commands_v1_common_pb from "../../../../../cc/arduino
|
||||
import * as cc_arduino_cli_commands_v1_board_pb from "../../../../../cc/arduino/cli/commands/v1/board_pb";
|
||||
import * as cc_arduino_cli_commands_v1_compile_pb from "../../../../../cc/arduino/cli/commands/v1/compile_pb";
|
||||
import * as cc_arduino_cli_commands_v1_core_pb from "../../../../../cc/arduino/cli/commands/v1/core_pb";
|
||||
import * as cc_arduino_cli_commands_v1_monitor_pb from "../../../../../cc/arduino/cli/commands/v1/monitor_pb";
|
||||
import * as cc_arduino_cli_commands_v1_upload_pb from "../../../../../cc/arduino/cli/commands/v1/upload_pb";
|
||||
import * as cc_arduino_cli_commands_v1_lib_pb from "../../../../../cc/arduino/cli/commands/v1/lib_pb";
|
||||
|
||||
@@ -25,6 +26,7 @@ interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.Untyped
|
||||
outdated: IArduinoCoreServiceService_IOutdated;
|
||||
upgrade: IArduinoCoreServiceService_IUpgrade;
|
||||
version: IArduinoCoreServiceService_IVersion;
|
||||
newSketch: IArduinoCoreServiceService_INewSketch;
|
||||
loadSketch: IArduinoCoreServiceService_ILoadSketch;
|
||||
archiveSketch: IArduinoCoreServiceService_IArchiveSketch;
|
||||
boardDetails: IArduinoCoreServiceService_IBoardDetails;
|
||||
@@ -54,6 +56,8 @@ interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.Untyped
|
||||
libraryResolveDependencies: IArduinoCoreServiceService_ILibraryResolveDependencies;
|
||||
librarySearch: IArduinoCoreServiceService_ILibrarySearch;
|
||||
libraryList: IArduinoCoreServiceService_ILibraryList;
|
||||
monitor: IArduinoCoreServiceService_IMonitor;
|
||||
enumerateMonitorPortSettings: IArduinoCoreServiceService_IEnumerateMonitorPortSettings;
|
||||
}
|
||||
|
||||
interface IArduinoCoreServiceService_ICreate extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.CreateRequest, cc_arduino_cli_commands_v1_commands_pb.CreateResponse> {
|
||||
@@ -137,6 +141,15 @@ interface IArduinoCoreServiceService_IVersion extends grpc.MethodDefinition<cc_a
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.VersionResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.VersionResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_INewSketch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/NewSketch";
|
||||
requestStream: false;
|
||||
responseStream: false;
|
||||
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest>;
|
||||
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest>;
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_ILoadSketch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LoadSketch";
|
||||
requestStream: false;
|
||||
@@ -398,6 +411,24 @@ interface IArduinoCoreServiceService_ILibraryList extends grpc.MethodDefinition<
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_IMonitor extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest, cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Monitor";
|
||||
requestStream: true;
|
||||
responseStream: true;
|
||||
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest>;
|
||||
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest>;
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_IEnumerateMonitorPortSettings extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/EnumerateMonitorPortSettings";
|
||||
requestStream: false;
|
||||
responseStream: false;
|
||||
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest>;
|
||||
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest>;
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse>;
|
||||
}
|
||||
|
||||
export const ArduinoCoreServiceService: IArduinoCoreServiceService;
|
||||
|
||||
@@ -411,6 +442,7 @@ export interface IArduinoCoreServiceServer {
|
||||
outdated: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse>;
|
||||
upgrade: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest, cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
|
||||
version: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.VersionRequest, cc_arduino_cli_commands_v1_commands_pb.VersionResponse>;
|
||||
newSketch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse>;
|
||||
loadSketch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse>;
|
||||
archiveSketch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse>;
|
||||
boardDetails: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse>;
|
||||
@@ -440,6 +472,8 @@ export interface IArduinoCoreServiceServer {
|
||||
libraryResolveDependencies: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse>;
|
||||
librarySearch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse>;
|
||||
libraryList: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse>;
|
||||
monitor: grpc.handleBidiStreamingCall<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest, cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
enumerateMonitorPortSettings: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse>;
|
||||
}
|
||||
|
||||
export interface IArduinoCoreServiceClient {
|
||||
@@ -465,6 +499,9 @@ export interface IArduinoCoreServiceClient {
|
||||
version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
|
||||
version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
|
||||
version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
|
||||
newSketch(request: cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
newSketch(request: cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
newSketch(request: cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
@@ -537,6 +574,12 @@ export interface IArduinoCoreServiceClient {
|
||||
libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
|
||||
libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
|
||||
libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
|
||||
monitor(): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest, cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
monitor(options: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest, cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
monitor(metadata: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest, cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
enumerateMonitorPortSettings(request: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse) => void): grpc.ClientUnaryCall;
|
||||
enumerateMonitorPortSettings(request: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse) => void): grpc.ClientUnaryCall;
|
||||
enumerateMonitorPortSettings(request: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse) => void): grpc.ClientUnaryCall;
|
||||
}
|
||||
|
||||
export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCoreServiceClient {
|
||||
@@ -563,6 +606,9 @@ export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCor
|
||||
public version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
|
||||
public version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
|
||||
public version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
|
||||
public newSketch(request: cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public newSketch(request: cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public newSketch(request: cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
@@ -634,4 +680,9 @@ export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCor
|
||||
public libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
|
||||
public libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
|
||||
public libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
|
||||
public monitor(options?: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest, cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
public monitor(metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest, cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse>;
|
||||
public enumerateMonitorPortSettings(request: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse) => void): grpc.ClientUnaryCall;
|
||||
public enumerateMonitorPortSettings(request: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse) => void): grpc.ClientUnaryCall;
|
||||
public enumerateMonitorPortSettings(request: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse) => void): grpc.ClientUnaryCall;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ var cc_arduino_cli_commands_v1_common_pb = require('../../../../../cc/arduino/cl
|
||||
var cc_arduino_cli_commands_v1_board_pb = require('../../../../../cc/arduino/cli/commands/v1/board_pb.js');
|
||||
var cc_arduino_cli_commands_v1_compile_pb = require('../../../../../cc/arduino/cli/commands/v1/compile_pb.js');
|
||||
var cc_arduino_cli_commands_v1_core_pb = require('../../../../../cc/arduino/cli/commands/v1/core_pb.js');
|
||||
var cc_arduino_cli_commands_v1_monitor_pb = require('../../../../../cc/arduino/cli/commands/v1/monitor_pb.js');
|
||||
var cc_arduino_cli_commands_v1_upload_pb = require('../../../../../cc/arduino/cli/commands/v1/upload_pb.js');
|
||||
var cc_arduino_cli_commands_v1_lib_pb = require('../../../../../cc/arduino/cli/commands/v1/lib_pb.js');
|
||||
|
||||
@@ -268,6 +269,28 @@ function deserialize_cc_arduino_cli_commands_v1_DestroyResponse(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_commands_pb.DestroyResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsRequest');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsRequest(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsResponse(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.EnumerateMonitorPortSettingsResponse');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsResponse(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_GitLibraryInstallRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.GitLibraryInstallRequest');
|
||||
@@ -510,6 +533,50 @@ function deserialize_cc_arduino_cli_commands_v1_LoadSketchResponse(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_MonitorRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.MonitorRequest');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_MonitorRequest(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_MonitorResponse(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.MonitorResponse');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_MonitorResponse(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_NewSketchRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.NewSketchRequest');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_NewSketchRequest(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_NewSketchResponse(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.NewSketchResponse');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_NewSketchResponse(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_OutdatedRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.OutdatedRequest');
|
||||
@@ -974,6 +1041,18 @@ version: {
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_VersionResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_VersionResponse,
|
||||
},
|
||||
// Create a new Sketch
|
||||
newSketch: {
|
||||
path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/NewSketch',
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest,
|
||||
responseType: cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse,
|
||||
requestSerialize: serialize_cc_arduino_cli_commands_v1_NewSketchRequest,
|
||||
requestDeserialize: deserialize_cc_arduino_cli_commands_v1_NewSketchRequest,
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_NewSketchResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_NewSketchResponse,
|
||||
},
|
||||
// Returns all files composing a Sketch
|
||||
loadSketch: {
|
||||
path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/LoadSketch',
|
||||
@@ -1331,6 +1410,30 @@ libraryList: {
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_LibraryListResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_LibraryListResponse,
|
||||
},
|
||||
// Open a monitor connection to a board port
|
||||
monitor: {
|
||||
path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/Monitor',
|
||||
requestStream: true,
|
||||
responseStream: true,
|
||||
requestType: cc_arduino_cli_commands_v1_monitor_pb.MonitorRequest,
|
||||
responseType: cc_arduino_cli_commands_v1_monitor_pb.MonitorResponse,
|
||||
requestSerialize: serialize_cc_arduino_cli_commands_v1_MonitorRequest,
|
||||
requestDeserialize: deserialize_cc_arduino_cli_commands_v1_MonitorRequest,
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_MonitorResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_MonitorResponse,
|
||||
},
|
||||
// Returns the parameters that can be set in the MonitorRequest calls
|
||||
enumerateMonitorPortSettings: {
|
||||
path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/EnumerateMonitorPortSettings',
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsRequest,
|
||||
responseType: cc_arduino_cli_commands_v1_monitor_pb.EnumerateMonitorPortSettingsResponse,
|
||||
requestSerialize: serialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsRequest,
|
||||
requestDeserialize: deserialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsRequest,
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_EnumerateMonitorPortSettingsResponse,
|
||||
},
|
||||
};
|
||||
|
||||
// BOOTSTRAP COMMANDS
|
||||
|
@@ -10,6 +10,7 @@ import * as cc_arduino_cli_commands_v1_common_pb from "../../../../../cc/arduino
|
||||
import * as cc_arduino_cli_commands_v1_board_pb from "../../../../../cc/arduino/cli/commands/v1/board_pb";
|
||||
import * as cc_arduino_cli_commands_v1_compile_pb from "../../../../../cc/arduino/cli/commands/v1/compile_pb";
|
||||
import * as cc_arduino_cli_commands_v1_core_pb from "../../../../../cc/arduino/cli/commands/v1/core_pb";
|
||||
import * as cc_arduino_cli_commands_v1_monitor_pb from "../../../../../cc/arduino/cli/commands/v1/monitor_pb";
|
||||
import * as cc_arduino_cli_commands_v1_upload_pb from "../../../../../cc/arduino/cli/commands/v1/upload_pb";
|
||||
import * as cc_arduino_cli_commands_v1_lib_pb from "../../../../../cc/arduino/cli/commands/v1/lib_pb";
|
||||
|
||||
@@ -489,6 +490,59 @@ export namespace VersionResponse {
|
||||
}
|
||||
}
|
||||
|
||||
export class NewSketchRequest extends jspb.Message {
|
||||
|
||||
hasInstance(): boolean;
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): NewSketchRequest;
|
||||
|
||||
getSketchName(): string;
|
||||
setSketchName(value: string): NewSketchRequest;
|
||||
|
||||
getSketchDir(): string;
|
||||
setSketchDir(value: string): NewSketchRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): NewSketchRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: NewSketchRequest): NewSketchRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: NewSketchRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): NewSketchRequest;
|
||||
static deserializeBinaryFromReader(message: NewSketchRequest, reader: jspb.BinaryReader): NewSketchRequest;
|
||||
}
|
||||
|
||||
export namespace NewSketchRequest {
|
||||
export type AsObject = {
|
||||
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
||||
sketchName: string,
|
||||
sketchDir: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class NewSketchResponse extends jspb.Message {
|
||||
getMainFile(): string;
|
||||
setMainFile(value: string): NewSketchResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): NewSketchResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: NewSketchResponse): NewSketchResponse.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: NewSketchResponse, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): NewSketchResponse;
|
||||
static deserializeBinaryFromReader(message: NewSketchResponse, reader: jspb.BinaryReader): NewSketchResponse;
|
||||
}
|
||||
|
||||
export namespace NewSketchResponse {
|
||||
export type AsObject = {
|
||||
mainFile: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class LoadSketchRequest extends jspb.Message {
|
||||
|
||||
hasInstance(): boolean;
|
||||
|
@@ -25,6 +25,8 @@ var cc_arduino_cli_commands_v1_compile_pb = require('../../../../../cc/arduino/c
|
||||
goog.object.extend(proto, cc_arduino_cli_commands_v1_compile_pb);
|
||||
var cc_arduino_cli_commands_v1_core_pb = require('../../../../../cc/arduino/cli/commands/v1/core_pb.js');
|
||||
goog.object.extend(proto, cc_arduino_cli_commands_v1_core_pb);
|
||||
var cc_arduino_cli_commands_v1_monitor_pb = require('../../../../../cc/arduino/cli/commands/v1/monitor_pb.js');
|
||||
goog.object.extend(proto, cc_arduino_cli_commands_v1_monitor_pb);
|
||||
var cc_arduino_cli_commands_v1_upload_pb = require('../../../../../cc/arduino/cli/commands/v1/upload_pb.js');
|
||||
goog.object.extend(proto, cc_arduino_cli_commands_v1_upload_pb);
|
||||
var cc_arduino_cli_commands_v1_lib_pb = require('../../../../../cc/arduino/cli/commands/v1/lib_pb.js');
|
||||
@@ -41,6 +43,8 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.InitResponse.MessageCase', n
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.InitResponse.Progress', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LoadSketchRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LoadSketchResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.NewSketchRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.NewSketchResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.OutdatedRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.OutdatedResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UpdateCoreLibrariesIndexRequest', null, global);
|
||||
@@ -452,6 +456,48 @@ if (goog.DEBUG && !COMPILED) {
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.VersionResponse.displayName = 'proto.cc.arduino.cli.commands.v1.VersionResponse';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.NewSketchRequest, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.displayName = 'proto.cc.arduino.cli.commands.v1.NewSketchRequest';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.NewSketchResponse, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.displayName = 'proto.cc.arduino.cli.commands.v1.NewSketchResponse';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
@@ -3508,6 +3554,347 @@ proto.cc.arduino.cli.commands.v1.VersionResponse.prototype.setVersion = function
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.NewSketchRequest.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
|
||||
sketchName: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
sketchDir: jspb.Message.getFieldWithDefault(msg, 3, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.NewSketchRequest;
|
||||
return proto.cc.arduino.cli.commands.v1.NewSketchRequest.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.Instance;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Instance.deserializeBinaryFromReader);
|
||||
msg.setInstance(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setSketchName(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setSketchDir(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getInstance();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
1,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getSketchName();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getSketchDir();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
3,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional Instance instance = 1;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.Instance}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.getInstance = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.Instance} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Instance, 1));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.Instance|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.setInstance = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.clearInstance = function() {
|
||||
return this.setInstance(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.hasInstance = function() {
|
||||
return jspb.Message.getField(this, 1) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string sketch_name = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.getSketchName = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.setSketchName = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string sketch_dir = 3;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.getSketchDir = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.setSketchDir = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 3, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.NewSketchResponse.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.NewSketchResponse} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
mainFile: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.NewSketchResponse;
|
||||
return proto.cc.arduino.cli.commands.v1.NewSketchResponse.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.NewSketchResponse} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setMainFile(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.NewSketchResponse} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getMainFile();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string main_file = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.prototype.getMainFile = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchResponse.prototype.setMainFile = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
|
@@ -74,6 +74,9 @@ export class TaskProgress extends jspb.Message {
|
||||
getCompleted(): boolean;
|
||||
setCompleted(value: boolean): TaskProgress;
|
||||
|
||||
getPercent(): number;
|
||||
setPercent(value: number): TaskProgress;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): TaskProgress.AsObject;
|
||||
@@ -90,6 +93,7 @@ export namespace TaskProgress {
|
||||
name: string,
|
||||
message: string,
|
||||
completed: boolean,
|
||||
percent: number,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +185,31 @@ export namespace Platform {
|
||||
}
|
||||
}
|
||||
|
||||
export class PlatformReference extends jspb.Message {
|
||||
getId(): string;
|
||||
setId(value: string): PlatformReference;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): PlatformReference;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformReference.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformReference): PlatformReference.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: PlatformReference, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): PlatformReference;
|
||||
static deserializeBinaryFromReader(message: PlatformReference, reader: jspb.BinaryReader): PlatformReference;
|
||||
}
|
||||
|
||||
export namespace PlatformReference {
|
||||
export type AsObject = {
|
||||
id: string,
|
||||
version: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class Board extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): Board;
|
||||
|
@@ -19,6 +19,7 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Board', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.DownloadProgress', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Instance', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Platform', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.PlatformReference', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.Programmer', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.TaskProgress', null, global);
|
||||
/**
|
||||
@@ -126,6 +127,27 @@ if (goog.DEBUG && !COMPILED) {
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.Platform.displayName = 'proto.cc.arduino.cli.commands.v1.Platform';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.PlatformReference, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.displayName = 'proto.cc.arduino.cli.commands.v1.PlatformReference';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
@@ -561,7 +583,8 @@ proto.cc.arduino.cli.commands.v1.TaskProgress.toObject = function(includeInstanc
|
||||
var f, obj = {
|
||||
name: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
message: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
completed: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
|
||||
completed: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
|
||||
percent: jspb.Message.getFloatingPointFieldWithDefault(msg, 4, 0.0)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@@ -610,6 +633,10 @@ proto.cc.arduino.cli.commands.v1.TaskProgress.deserializeBinaryFromReader = func
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setCompleted(value);
|
||||
break;
|
||||
case 4:
|
||||
var value = /** @type {number} */ (reader.readFloat());
|
||||
msg.setPercent(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@@ -660,6 +687,13 @@ proto.cc.arduino.cli.commands.v1.TaskProgress.serializeBinaryToWriter = function
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getPercent();
|
||||
if (f !== 0.0) {
|
||||
writer.writeFloat(
|
||||
4,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -717,6 +751,24 @@ proto.cc.arduino.cli.commands.v1.TaskProgress.prototype.setCompleted = function(
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional float percent = 4;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.TaskProgress.prototype.getPercent = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 4, 0.0));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.TaskProgress} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.TaskProgress.prototype.setPercent = function(value) {
|
||||
return jspb.Message.setProto3FloatField(this, 4, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1340,6 +1392,166 @@ proto.cc.arduino.cli.commands.v1.Platform.prototype.setDeprecated = function(val
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.PlatformReference.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.PlatformReference} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
id: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
version: jspb.Message.getFieldWithDefault(msg, 2, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.PlatformReference}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.PlatformReference;
|
||||
return proto.cc.arduino.cli.commands.v1.PlatformReference.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.PlatformReference} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.PlatformReference}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setId(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setVersion(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.cc.arduino.cli.commands.v1.PlatformReference} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getId();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getVersion();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string id = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.prototype.getId = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.PlatformReference} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.prototype.setId = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string version = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.prototype.getVersion = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.PlatformReference} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.PlatformReference.prototype.setVersion = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
|
@@ -149,6 +149,24 @@ export class CompileResponse extends jspb.Message {
|
||||
addExecutableSectionsSize(value?: ExecutableSectionSize, index?: number): ExecutableSectionSize;
|
||||
|
||||
|
||||
hasBoardPlatform(): boolean;
|
||||
clearBoardPlatform(): void;
|
||||
getBoardPlatform(): cc_arduino_cli_commands_v1_common_pb.PlatformReference | undefined;
|
||||
setBoardPlatform(value?: cc_arduino_cli_commands_v1_common_pb.PlatformReference): CompileResponse;
|
||||
|
||||
|
||||
hasBuildPlatform(): boolean;
|
||||
clearBuildPlatform(): void;
|
||||
getBuildPlatform(): cc_arduino_cli_commands_v1_common_pb.PlatformReference | undefined;
|
||||
setBuildPlatform(value?: cc_arduino_cli_commands_v1_common_pb.PlatformReference): CompileResponse;
|
||||
|
||||
|
||||
hasProgress(): boolean;
|
||||
clearProgress(): void;
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): CompileResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): CompileResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: CompileResponse): CompileResponse.AsObject;
|
||||
@@ -166,6 +184,9 @@ export namespace CompileResponse {
|
||||
buildPath: string,
|
||||
usedLibrariesList: Array<cc_arduino_cli_commands_v1_lib_pb.Library.AsObject>,
|
||||
executableSectionsSizeList: Array<ExecutableSectionSize.AsObject>,
|
||||
boardPlatform?: cc_arduino_cli_commands_v1_common_pb.PlatformReference.AsObject,
|
||||
buildPlatform?: cc_arduino_cli_commands_v1_common_pb.PlatformReference.AsObject,
|
||||
progress?: cc_arduino_cli_commands_v1_common_pb.TaskProgress.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -971,7 +971,10 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.toObject = function(includeInst
|
||||
usedLibrariesList: jspb.Message.toObjectList(msg.getUsedLibrariesList(),
|
||||
cc_arduino_cli_commands_v1_lib_pb.Library.toObject, includeInstance),
|
||||
executableSectionsSizeList: jspb.Message.toObjectList(msg.getExecutableSectionsSizeList(),
|
||||
proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject, includeInstance)
|
||||
proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.toObject, includeInstance),
|
||||
boardPlatform: (f = msg.getBoardPlatform()) && cc_arduino_cli_commands_v1_common_pb.PlatformReference.toObject(includeInstance, f),
|
||||
buildPlatform: (f = msg.getBuildPlatform()) && cc_arduino_cli_commands_v1_common_pb.PlatformReference.toObject(includeInstance, f),
|
||||
progress: (f = msg.getProgress()) && cc_arduino_cli_commands_v1_common_pb.TaskProgress.toObject(includeInstance, f)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@@ -1030,6 +1033,21 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.deserializeBinaryFromReader = f
|
||||
reader.readMessage(value,proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.deserializeBinaryFromReader);
|
||||
msg.addExecutableSectionsSize(value);
|
||||
break;
|
||||
case 6:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.PlatformReference;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.PlatformReference.deserializeBinaryFromReader);
|
||||
msg.setBoardPlatform(value);
|
||||
break;
|
||||
case 7:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.PlatformReference;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.PlatformReference.deserializeBinaryFromReader);
|
||||
msg.setBuildPlatform(value);
|
||||
break;
|
||||
case 8:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.TaskProgress;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.TaskProgress.deserializeBinaryFromReader);
|
||||
msg.setProgress(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@@ -1096,6 +1114,30 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.serializeBinaryToWriter = funct
|
||||
proto.cc.arduino.cli.commands.v1.ExecutableSectionSize.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getBoardPlatform();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
6,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.PlatformReference.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getBuildPlatform();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
7,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.PlatformReference.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getProgress();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
8,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.TaskProgress.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1277,6 +1319,117 @@ proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearExecutableSectio
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional PlatformReference board_platform = 6;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.PlatformReference}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getBoardPlatform = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.PlatformReference} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.PlatformReference, 6));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.PlatformReference|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setBoardPlatform = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 6, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearBoardPlatform = function() {
|
||||
return this.setBoardPlatform(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasBoardPlatform = function() {
|
||||
return jspb.Message.getField(this, 6) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional PlatformReference build_platform = 7;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.PlatformReference}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getBuildPlatform = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.PlatformReference} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.PlatformReference, 7));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.PlatformReference|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setBuildPlatform = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 7, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearBuildPlatform = function() {
|
||||
return this.setBuildPlatform(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasBuildPlatform = function() {
|
||||
return jspb.Message.getField(this, 7) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional TaskProgress progress = 8;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.TaskProgress}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.getProgress = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.TaskProgress} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.TaskProgress, 8));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.TaskProgress|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.setProgress = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 8, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.CompileResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.clearProgress = function() {
|
||||
return this.setProgress(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.CompileResponse.prototype.hasProgress = function() {
|
||||
return jspb.Message.getField(this, 8) != null;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -371,6 +371,9 @@ export class SupportedUserFieldsRequest extends jspb.Message {
|
||||
getProtocol(): string;
|
||||
setProtocol(value: string): SupportedUserFieldsRequest;
|
||||
|
||||
getAddress(): string;
|
||||
setAddress(value: string): SupportedUserFieldsRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SupportedUserFieldsRequest.AsObject;
|
||||
@@ -387,6 +390,7 @@ export namespace SupportedUserFieldsRequest {
|
||||
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
||||
fqbn: string,
|
||||
protocol: string,
|
||||
address: string,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2718,7 +2718,8 @@ proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.toObject = function(
|
||||
var f, obj = {
|
||||
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
|
||||
fqbn: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
protocol: jspb.Message.getFieldWithDefault(msg, 3, "")
|
||||
protocol: jspb.Message.getFieldWithDefault(msg, 3, ""),
|
||||
address: jspb.Message.getFieldWithDefault(msg, 4, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@@ -2768,6 +2769,10 @@ proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.deserializeBinaryFro
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setProtocol(value);
|
||||
break;
|
||||
case 4:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setAddress(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@@ -2819,6 +2824,13 @@ proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.serializeBinaryToWri
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getAddress();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
4,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2895,6 +2907,24 @@ proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.prototype.setProtoco
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string address = 4;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.prototype.getAddress = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.prototype.setAddress = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 4, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -43,7 +43,10 @@ function deserialize_cc_arduino_cli_monitor_v1_StreamingOpenResponse(buffer_arg)
|
||||
}
|
||||
|
||||
|
||||
// MonitorService provides services for boards monitor
|
||||
// MonitorService provides services for boards monitor.
|
||||
// DEPRECATION WARNING: MonitorService is deprecated and will be removed in a
|
||||
// future release. Use ArduinoCoreService.Monitor and
|
||||
// ArduinoCoreService.EnumerateMonitorPortSettings instead.
|
||||
var MonitorServiceService = exports['cc.arduino.cli.monitor.v1.MonitorService'] = {
|
||||
// Open a bidirectional monitor stream. This can be used to implement
|
||||
// something similar to the Arduino IDE's Serial Monitor.
|
||||
|
@@ -70,9 +70,11 @@ export abstract class GrpcClientProvider<C> {
|
||||
protected abstract close(client: C): void;
|
||||
|
||||
protected get channelOptions(): Record<string, unknown> {
|
||||
const pjson = require('../../package.json') || { version: '0.0.0' };
|
||||
return {
|
||||
'grpc.max_send_message_length': 512 * 1024 * 1024,
|
||||
'grpc.max_receive_message_length': 512 * 1024 * 1024,
|
||||
'grpc.primary_user_agent': `arduino-ide/${pjson.version}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,29 +1,29 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "browser-app",
|
||||
"version": "2.0.0-rc3",
|
||||
"version": "2.0.0-rc4",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@theia/core": "1.19.0",
|
||||
"@theia/debug": "1.19.0",
|
||||
"@theia/editor": "1.19.0",
|
||||
"@theia/editor-preview": "1.19.0",
|
||||
"@theia/file-search": "1.19.0",
|
||||
"@theia/filesystem": "1.19.0",
|
||||
"@theia/keymaps": "1.19.0",
|
||||
"@theia/messages": "1.19.0",
|
||||
"@theia/monaco": "1.19.0",
|
||||
"@theia/navigator": "1.19.0",
|
||||
"@theia/plugin-ext": "1.19.0",
|
||||
"@theia/plugin-ext-vscode": "1.19.0",
|
||||
"@theia/preferences": "1.19.0",
|
||||
"@theia/process": "1.19.0",
|
||||
"@theia/terminal": "1.19.0",
|
||||
"@theia/workspace": "1.19.0",
|
||||
"arduino-ide-extension": "2.0.0-rc3"
|
||||
"@theia/core": "1.22.1",
|
||||
"@theia/debug": "1.22.1",
|
||||
"@theia/editor": "1.22.1",
|
||||
"@theia/editor-preview": "1.22.1",
|
||||
"@theia/file-search": "1.22.1",
|
||||
"@theia/filesystem": "1.22.1",
|
||||
"@theia/keymaps": "1.22.1",
|
||||
"@theia/messages": "1.22.1",
|
||||
"@theia/monaco": "1.22.1",
|
||||
"@theia/navigator": "1.22.1",
|
||||
"@theia/plugin-ext": "1.22.1",
|
||||
"@theia/plugin-ext-vscode": "1.22.1",
|
||||
"@theia/preferences": "1.22.1",
|
||||
"@theia/process": "1.22.1",
|
||||
"@theia/terminal": "1.22.1",
|
||||
"@theia/workspace": "1.22.1",
|
||||
"arduino-ide-extension": "2.0.0-rc4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0"
|
||||
"@theia/cli": "1.22.1"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "theia build --mode development",
|
||||
@@ -60,4 +60,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,19 +2,18 @@
|
||||
|
||||
Building the Pro IDE on Linux `armv7l` (aka `armhf`) and `aarch64` (aka `arm64`):
|
||||
|
||||
1. Install Node.js 12.x with [nvm](https://github.com/nvm-sh/nvm#install--update-script):
|
||||
1. Install Node.js 14.x with [nvm](https://github.com/nvm-sh/nvm#install--update-script):
|
||||
```
|
||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
|
||||
```
|
||||
Restart your shell then:
|
||||
```
|
||||
nvm install 12.14.1
|
||||
nvm use 12.14.1
|
||||
nvm install 14
|
||||
nvm use 14
|
||||
```
|
||||
Verify:
|
||||
```
|
||||
node -v
|
||||
v12.14.1
|
||||
```
|
||||
|
||||
2. Install [Yarn](https://classic.yarnpkg.com/en/docs/install/#debian-stable):
|
||||
|
@@ -18,9 +18,9 @@ sudo apt update \
|
||||
build-essential \
|
||||
&& wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash \
|
||||
&& source ~/.bashrc \
|
||||
&& nvm install 12.14.1 \
|
||||
&& nvm use 12.14.1 \
|
||||
&& nvm alias default 12.14.1 \
|
||||
&& nvm install 14 \
|
||||
&& nvm use 14 \
|
||||
&& nvm alias default 14 \
|
||||
&& curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - \
|
||||
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list \
|
||||
&& sudo apt update && sudo apt install --no-install-recommends yarn \
|
||||
|
@@ -1,31 +1,32 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "electron-app",
|
||||
"version": "2.0.0-rc3",
|
||||
"version": "2.0.0-rc4",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"main": "src-gen/frontend/electron-main.js",
|
||||
"dependencies": {
|
||||
"@theia/core": "1.19.0",
|
||||
"@theia/debug": "1.19.0",
|
||||
"@theia/editor": "1.19.0",
|
||||
"@theia/editor-preview": "1.19.0",
|
||||
"@theia/electron": "1.19.0",
|
||||
"@theia/file-search": "1.19.0",
|
||||
"@theia/filesystem": "1.19.0",
|
||||
"@theia/keymaps": "1.19.0",
|
||||
"@theia/messages": "1.19.0",
|
||||
"@theia/monaco": "1.19.0",
|
||||
"@theia/navigator": "1.19.0",
|
||||
"@theia/plugin-ext": "1.19.0",
|
||||
"@theia/plugin-ext-vscode": "1.19.0",
|
||||
"@theia/preferences": "1.19.0",
|
||||
"@theia/process": "1.19.0",
|
||||
"@theia/terminal": "1.19.0",
|
||||
"@theia/workspace": "1.19.0",
|
||||
"arduino-ide-extension": "2.0.0-rc3"
|
||||
"@theia/core": "1.22.1",
|
||||
"@theia/debug": "1.22.1",
|
||||
"@theia/editor": "1.22.1",
|
||||
"@theia/editor-preview": "1.22.1",
|
||||
"@theia/electron": "1.22.1",
|
||||
"@theia/file-search": "1.22.1",
|
||||
"@theia/filesystem": "1.22.1",
|
||||
"@theia/keymaps": "1.22.1",
|
||||
"@theia/messages": "1.22.1",
|
||||
"@theia/monaco": "1.22.1",
|
||||
"@theia/navigator": "1.22.1",
|
||||
"@theia/plugin-ext": "1.22.1",
|
||||
"@theia/plugin-ext-vscode": "1.22.1",
|
||||
"@theia/preferences": "1.22.1",
|
||||
"@theia/process": "1.22.1",
|
||||
"@theia/terminal": "1.22.1",
|
||||
"@theia/workspace": "1.22.1",
|
||||
"arduino-ide-extension": "2.0.0-rc4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0"
|
||||
"@theia/cli": "1.22.1",
|
||||
"electron": "^15.3.5"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "theia build --mode development",
|
||||
@@ -63,4 +64,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,27 +2,31 @@ const isCI = require('is-ci');
|
||||
const { notarize } = require('electron-notarize');
|
||||
|
||||
exports.default = async function notarizing(context) {
|
||||
if (!isCI) {
|
||||
console.log('Skipping notarization: not on CI.');
|
||||
return;
|
||||
}
|
||||
if (process.env.IS_FORK === 'true') {
|
||||
console.log('Skipping the app notarization: building from a fork.');
|
||||
return;
|
||||
}
|
||||
const { electronPlatformName, appOutDir } = context;
|
||||
if (electronPlatformName !== 'darwin') {
|
||||
return;
|
||||
}
|
||||
if (!isCI) {
|
||||
console.log('Skipping notarization: not on CI.');
|
||||
return;
|
||||
}
|
||||
if (process.env.IS_FORK === 'true') {
|
||||
console.log('Skipping the app notarization: building from a fork.');
|
||||
return;
|
||||
}
|
||||
const { electronPlatformName, appOutDir } = context;
|
||||
if (electronPlatformName !== 'darwin') {
|
||||
return;
|
||||
}
|
||||
|
||||
const appName = context.packager.appInfo.productFilename;
|
||||
const appBundleId = context.packager.config.appId;
|
||||
console.log(`>>> Notarizing ${appBundleId} at ${appOutDir}/${appName}.app...`);
|
||||
const appName = context.packager.appInfo.productFilename;
|
||||
const appBundleId = context.packager.config.appId;
|
||||
console.log(
|
||||
`>>> Notarizing ${appBundleId} at ${appOutDir}/${appName}.app...`
|
||||
);
|
||||
|
||||
return await notarize({
|
||||
appBundleId,
|
||||
appPath: `${appOutDir}/${appName}.app`,
|
||||
appleId: process.env.AC_USERNAME,
|
||||
appleIdPassword: process.env.AC_PASSWORD,
|
||||
});
|
||||
await notarize({
|
||||
appBundleId,
|
||||
appPath: `${appOutDir}/${appName}.app`,
|
||||
appleId: process.env.AC_USERNAME,
|
||||
appleIdPassword: process.env.AC_PASSWORD,
|
||||
teamId: process.env.AC_TEAM_ID,
|
||||
tool: 'notarytool',
|
||||
});
|
||||
};
|
||||
|
@@ -3,16 +3,18 @@
|
||||
"author": "Arduino SA",
|
||||
"resolutions": {
|
||||
"**/fs-extra": "^4.0.3",
|
||||
"electron-builder": "22.7.0"
|
||||
"electron-builder": "22.10.5",
|
||||
"find-git-exec": "0.0.4",
|
||||
"dugite-extra": "0.1.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-log-rotate": "^0.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0",
|
||||
"@theia/cli": "1.22.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"electron-builder": "22.7.0",
|
||||
"electron-notarize": "^0.3.0",
|
||||
"electron-builder": "22.10.5",
|
||||
"electron-notarize": "^1.1.1",
|
||||
"is-ci": "^2.0.0",
|
||||
"ncp": "^2.0.0",
|
||||
"shelljs": "^0.8.3"
|
||||
@@ -20,13 +22,14 @@
|
||||
"scripts": {
|
||||
"build": "yarn download:plugins && theia build --mode development && yarn patch",
|
||||
"build:publish": "yarn download:plugins && theia build --mode production && yarn patch",
|
||||
"rebuild": "yarn theia rebuild:electron",
|
||||
"package": "cross-env DEBUG=* && electron-builder --publish=never",
|
||||
"package:publish": "cross-env DEBUG=* && electron-builder --publish=always",
|
||||
"download:plugins": "theia download:plugins",
|
||||
"patch": "ncp ./patch/main.js ./src-gen/backend/main.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.14.1 <13"
|
||||
"node": ">=14.0.0 <15"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -51,9 +54,18 @@
|
||||
"build": {
|
||||
"productName": "Arduino IDE",
|
||||
"asar": false,
|
||||
"detectUpdateChannel": false,
|
||||
"generateUpdatesFilesForAllChannels": true,
|
||||
"npmRebuild": false,
|
||||
"directories": {
|
||||
"buildResources": "resources"
|
||||
},
|
||||
"fileAssociations": [
|
||||
{
|
||||
"ext": "ino",
|
||||
"role": "Editor"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
"src-gen",
|
||||
"lib",
|
||||
@@ -65,8 +77,7 @@
|
||||
"!node_modules/@theia/**/lib/*browser/*",
|
||||
"node_modules/@theia/core/lib/browser/*",
|
||||
"!node_modules/@typefox/monaco-editor-core/*",
|
||||
"!node_modules/oniguruma/*",
|
||||
"!node_modules/onigasm/*"
|
||||
"!node_modules/electron/**"
|
||||
],
|
||||
"extraResources": [
|
||||
{
|
||||
@@ -86,16 +97,12 @@
|
||||
"hardenedRuntime": true,
|
||||
"gatekeeperAssess": false,
|
||||
"entitlements": "resources/entitlements.mac.plist",
|
||||
"entitlementsInherit": "resources/entitlements.mac.plist",
|
||||
"target": [
|
||||
"dmg"
|
||||
]
|
||||
"entitlementsInherit": "resources/entitlements.mac.plist"
|
||||
},
|
||||
"linux": {
|
||||
"target": [
|
||||
{
|
||||
"target": "zip"
|
||||
}
|
||||
"zip",
|
||||
"AppImage"
|
||||
],
|
||||
"category": "Development",
|
||||
"icon": "resources/icons"
|
||||
@@ -139,9 +146,9 @@
|
||||
"theiaPluginsDir": "plugins",
|
||||
"theiaPlugins": {
|
||||
"vscode-builtin-cpp": "https://open-vsx.org/api/vscode/cpp/1.52.1/file/vscode.cpp-1.52.1.vsix",
|
||||
"vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.1.vsix",
|
||||
"vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.2.vsix",
|
||||
"vscode-builtin-json": "https://open-vsx.org/api/vscode/json/1.46.1/file/vscode.json-1.46.1.vsix",
|
||||
"vscode-builtin-json-language-features": "https://open-vsx.org/api/vscode/json-language-features/1.46.1/file/vscode.json-language-features-1.46.1.vsix",
|
||||
"cortex-debug": "https://open-vsx.org/api/marus25/cortex-debug/0.3.10/file/marus25.cortex-debug-0.3.10.vsix"
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,87 +8,106 @@ const dateFormat = require('dateformat');
|
||||
const { isNightly, isRelease, git } = require('./utils');
|
||||
|
||||
function artifactName() {
|
||||
const { platform, arch } = process;
|
||||
const id = (() => {
|
||||
if (isRelease) {
|
||||
return getVersion();
|
||||
} else if (isNightly) {
|
||||
return `nightly-${timestamp()}`
|
||||
} else {
|
||||
return getVersion();
|
||||
}
|
||||
})();
|
||||
const name = 'arduino-ide';
|
||||
switch (platform) {
|
||||
case 'win32': {
|
||||
if (arch === 'x64') {
|
||||
return `${name}_${id}_Windows_64bit.\$\{ext}`;
|
||||
}
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
case 'darwin': {
|
||||
return `${name}_${id}_macOS_64bit.\$\{ext}`;
|
||||
}
|
||||
case 'linux': {
|
||||
switch (arch) {
|
||||
case 'arm': {
|
||||
return `${name}_${id}_Linux_ARMv7.\$\{ext}`;
|
||||
}
|
||||
case 'arm64': {
|
||||
return `${name}_${id}_Linux_ARM64.\$\{ext}`;
|
||||
}
|
||||
case 'x64': {
|
||||
return `${name}_${id}_Linux_64bit.\$\{ext}`;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
default: throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
const { platform, arch } = process;
|
||||
const id = (() => {
|
||||
if (isRelease) {
|
||||
return getVersion();
|
||||
} else if (isNightly) {
|
||||
return `nightly-${timestamp()}`;
|
||||
} else {
|
||||
return getVersion();
|
||||
}
|
||||
})();
|
||||
const name = 'arduino-ide';
|
||||
switch (platform) {
|
||||
case 'win32': {
|
||||
if (arch === 'x64') {
|
||||
return `${name}_${id}_Windows_64bit.\$\{ext}`;
|
||||
}
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
case 'darwin': {
|
||||
return `${name}_${id}_macOS_64bit.\$\{ext}`;
|
||||
}
|
||||
case 'linux': {
|
||||
switch (arch) {
|
||||
case 'arm': {
|
||||
return `${name}_${id}_Linux_ARMv7.\$\{ext}`;
|
||||
}
|
||||
case 'arm64': {
|
||||
return `${name}_${id}_Linux_ARM64.\$\{ext}`;
|
||||
}
|
||||
case 'x64': {
|
||||
return `${name}_${id}_Linux_64bit.\$\{ext}`;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
}
|
||||
|
||||
function electronPlatform() {
|
||||
switch (process.platform) {
|
||||
case 'win32': {
|
||||
return 'win';
|
||||
}
|
||||
case 'darwin': {
|
||||
return 'mac';
|
||||
}
|
||||
case 'linux': {
|
||||
return 'linux';
|
||||
}
|
||||
default: throw new Error(`Unsupported platform: ${process.platform}.`);
|
||||
switch (process.platform) {
|
||||
case 'win32': {
|
||||
return 'win';
|
||||
}
|
||||
case 'darwin': {
|
||||
return 'mac';
|
||||
}
|
||||
case 'linux': {
|
||||
return 'linux';
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported platform: ${process.platform}.`);
|
||||
}
|
||||
}
|
||||
|
||||
function getVersion() {
|
||||
const repositoryRootPath = git('rev-parse --show-toplevel');
|
||||
let version = JSON.parse(fs.readFileSync(path.join(repositoryRootPath, 'package.json'), { encoding: 'utf8' })).version;
|
||||
const repositoryRootPath = git('rev-parse --show-toplevel');
|
||||
let version = JSON.parse(
|
||||
fs.readFileSync(path.join(repositoryRootPath, 'package.json'), {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
).version;
|
||||
if (!semver.valid(version)) {
|
||||
throw new Error(
|
||||
`Could not read version from root package.json. Version was: '${version}'.`
|
||||
);
|
||||
}
|
||||
if (!isRelease) {
|
||||
if (isNightly) {
|
||||
version = `${version}-nightly-${timestamp()}`;
|
||||
} else {
|
||||
version = `${version}-snapshot-${currentCommitish()}`;
|
||||
}
|
||||
if (!semver.valid(version)) {
|
||||
throw new Error(`Could not read version from root package.json. Version was: '${version}'.`);
|
||||
throw new Error(`Invalid patched version: '${version}'.`);
|
||||
}
|
||||
if (!isRelease) {
|
||||
if (isNightly) {
|
||||
version = `${version}-nightly.${timestamp()}`;
|
||||
} else {
|
||||
version = `${version}-snapshot.${currentCommitish()}`;
|
||||
}
|
||||
if (!semver.valid(version)) {
|
||||
throw new Error(`Invalid patched version: '${version}'.`);
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
function getChannel() {
|
||||
if (isRelease) {
|
||||
return 'stable';
|
||||
}
|
||||
if (isNightly) {
|
||||
return 'nightly';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function timestamp() {
|
||||
return dateFormat(new Date(), 'yyyymmdd');
|
||||
return dateFormat(new Date(), 'yyyymmdd');
|
||||
}
|
||||
|
||||
function currentCommitish() {
|
||||
return git('rev-parse --short HEAD');
|
||||
return git('rev-parse --short HEAD');
|
||||
}
|
||||
|
||||
// function currentBranch() {
|
||||
@@ -96,28 +115,38 @@ function currentCommitish() {
|
||||
// }
|
||||
|
||||
function generateTemplate(buildDate) {
|
||||
// do `export PUBLISH=true yarn package` if you want to mimic CI build locally.
|
||||
// const electronPublish = release || (isCI && currentBranch() === 'main') || process.env.PUBLISH === 'true';
|
||||
const version = getVersion();
|
||||
const productName = 'Arduino IDE';
|
||||
const name = 'arduino-ide';
|
||||
let customizations = {
|
||||
name,
|
||||
description: productName,
|
||||
version,
|
||||
build: {
|
||||
productName,
|
||||
appId: 'arduino.ProIDE',
|
||||
[electronPlatform()]: {
|
||||
artifactName: artifactName()
|
||||
}
|
||||
}
|
||||
};
|
||||
if (buildDate) {
|
||||
customizations = merge(customizations, { theia: { frontend: { config: { buildDate } } } });
|
||||
}
|
||||
const template = require('../build/template-package.json');
|
||||
return merge(template, customizations);
|
||||
// do `export PUBLISH=true yarn package` if you want to mimic CI build locally.
|
||||
// const electronPublish = release || (isCI && currentBranch() === 'main') || process.env.PUBLISH === 'true';
|
||||
const version = getVersion();
|
||||
const productName = 'Arduino IDE';
|
||||
const name = 'arduino-ide';
|
||||
const updateChannel = getChannel();
|
||||
let customizations = {
|
||||
name,
|
||||
description: productName,
|
||||
version,
|
||||
theia: {
|
||||
frontend: {
|
||||
config: {
|
||||
'arduino.ide.updateChannel': updateChannel,
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
productName,
|
||||
appId: 'cc.arduino.IDE2',
|
||||
[electronPlatform()]: {
|
||||
artifactName: artifactName(),
|
||||
},
|
||||
},
|
||||
};
|
||||
if (buildDate) {
|
||||
customizations = merge(customizations, {
|
||||
theia: { frontend: { config: { buildDate } } },
|
||||
});
|
||||
}
|
||||
const template = require('../build/template-package.json');
|
||||
return merge(template, customizations);
|
||||
}
|
||||
|
||||
module.exports = { generateTemplate };
|
||||
|
@@ -1,339 +1,504 @@
|
||||
//@ts-check
|
||||
|
||||
(async () => {
|
||||
const fs = require('fs');
|
||||
const join = require('path').join;
|
||||
const shell = require('shelljs');
|
||||
const glob = require('glob');
|
||||
const isCI = require('is-ci');
|
||||
shell.env.THEIA_ELECTRON_SKIP_REPLACE_FFMPEG = '1'; // Do not run the ffmpeg validation for the packager.
|
||||
shell.env.NODE_OPTIONS = '--max_old_space_size=4096'; // Increase heap size for the CI
|
||||
shell.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = 'true'; // Skip download and avoid `ERROR: Failed to download Chromium`.
|
||||
const template = require('./config').generateTemplate(
|
||||
new Date().toISOString()
|
||||
);
|
||||
const utils = require('./utils');
|
||||
const merge = require('deepmerge');
|
||||
const { isRelease, isElectronPublish, getChannelFile } = utils;
|
||||
const { version } = template;
|
||||
const { productName } = template.build;
|
||||
|
||||
const fs = require('fs');
|
||||
const join = require('path').join;
|
||||
const shell = require('shelljs');
|
||||
const glob = require('glob');
|
||||
const isCI = require('is-ci');
|
||||
shell.env.THEIA_ELECTRON_SKIP_REPLACE_FFMPEG = '1'; // Do not run the ffmpeg validation for the packager.
|
||||
shell.env.NODE_OPTIONS = '--max_old_space_size=4096'; // Increase heap size for the CI
|
||||
shell.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = 'true'; // Skip download and avoid `ERROR: Failed to download Chromium`.
|
||||
const template = require('./config').generateTemplate(new Date().toISOString());
|
||||
const utils = require('./utils');
|
||||
const merge = require('deepmerge');
|
||||
const { isRelease, isElectronPublish } = utils;
|
||||
const { version } = template;
|
||||
const { productName } = template.build;
|
||||
echo(`📦 Building ${isRelease ? 'release ' : ''}version '${version}'...`);
|
||||
|
||||
echo(`📦 Building ${isRelease ? 'release ' : ''}version '${version}'...`);
|
||||
const workingCopy = 'working-copy';
|
||||
|
||||
const workingCopy = 'working-copy';
|
||||
/**
|
||||
* Relative path from the `__dirname` to the root where the `arduino-ide-extension` and the `electron-app` folders are.
|
||||
* This could come handy when moving the location of the `electron/packager`.
|
||||
*/
|
||||
const rootPath = join('..', '..');
|
||||
|
||||
/**
|
||||
* Relative path from the `__dirname` to the root where the `arduino-ide-extension` and the `electron-app` folders are.
|
||||
* This could come handy when moving the location of the `electron/packager`.
|
||||
*/
|
||||
const rootPath = join('..', '..');
|
||||
// This is a HACK! We rename the root `node_modules` to something else. Otherwise, due to the hoisting,
|
||||
// multiple Theia extensions will be picked up.
|
||||
if (fs.existsSync(path(rootPath, 'node_modules'))) {
|
||||
// We either do this or change the project structure.
|
||||
echo(
|
||||
"🔧 >>> [Hack] Renaming the root 'node_modules' folder to '.node_modules'..."
|
||||
);
|
||||
mv('-f', path(rootPath, 'node_modules'), path(rootPath, '.node_modules'));
|
||||
echo(
|
||||
"👌 <<< [Hack] Renamed the root 'node_modules' folder to '.node_modules'."
|
||||
);
|
||||
}
|
||||
|
||||
// This is a HACK! We rename the root `node_modules` to something else. Otherwise, due to the hoisting,
|
||||
// multiple Theia extensions will be picked up.
|
||||
if (fs.existsSync(path(rootPath, 'node_modules'))) {
|
||||
// We either do this or change the project structure.
|
||||
echo('🔧 >>> [Hack] Renaming the root \'node_modules\' folder to \'.node_modules\'...');
|
||||
mv('-f', path(rootPath, 'node_modules'), path(rootPath, '.node_modules'));
|
||||
echo('👌 <<< [Hack] Renamed the root \'node_modules\' folder to \'.node_modules\'.')
|
||||
}
|
||||
//---------------------------+
|
||||
// Clean the previous state. |
|
||||
//---------------------------+
|
||||
// rm -rf ../working-copy
|
||||
rm('-rf', path('..', workingCopy));
|
||||
// Clean up the `./electron/build` folder.
|
||||
const resourcesToKeep = [
|
||||
'patch',
|
||||
'resources',
|
||||
'scripts',
|
||||
'template-package.json',
|
||||
];
|
||||
fs.readdirSync(path('..', 'build'))
|
||||
.filter((filename) => resourcesToKeep.indexOf(filename) === -1)
|
||||
.forEach((filename) => rm('-rf', path('..', 'build', filename)));
|
||||
|
||||
//---------------------------+
|
||||
// Clean the previous state. |
|
||||
//---------------------------+
|
||||
// rm -rf ../working-copy
|
||||
rm('-rf', path('..', workingCopy));
|
||||
// Clean up the `./electron/build` folder.
|
||||
const resourcesToKeep = ['patch', 'resources', 'scripts', 'template-package.json'];
|
||||
for (const filename of fs.readdirSync(path('..', 'build')).filter(filename => resourcesToKeep.indexOf(filename) === -1)) {
|
||||
rm('-rf', path('..', 'build', filename));
|
||||
}
|
||||
const extensions = require('./extensions.json');
|
||||
echo(
|
||||
`Building the application with the following extensions:\n${extensions
|
||||
.map((ext) => ` - ${ext}`)
|
||||
.join(',\n')}`
|
||||
);
|
||||
const allDependencies = [...extensions, 'electron-app'];
|
||||
|
||||
const extensions = require('./extensions.json');
|
||||
echo(`Building the application with the following extensions:\n${extensions.map(ext => ` - ${ext}`).join(',\n')}`);
|
||||
const allDependencies = [
|
||||
...extensions,
|
||||
'electron-app'
|
||||
]
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
// Copy the following items into the `working-copy` folder. Make sure to reuse the `yarn.lock`. |
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
mkdir('-p', path('..', workingCopy));
|
||||
for (const name of [
|
||||
...allDependencies,
|
||||
'yarn.lock',
|
||||
'package.json',
|
||||
'lerna.json',
|
||||
]) {
|
||||
cp('-rf', path(rootPath, name), path('..', workingCopy));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
// Copy the following items into the `working-copy` folder. Make sure to reuse the `yarn.lock`. |
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
mkdir('-p', path('..', workingCopy));
|
||||
for (const name of [...allDependencies, 'yarn.lock', 'package.json', 'lerna.json']) {
|
||||
cp('-rf', path(rootPath, name), path('..', workingCopy));
|
||||
}
|
||||
|
||||
//----------------------------------------------+
|
||||
// Sanity check: all versions must be the same. |
|
||||
//----------------------------------------------+
|
||||
verifyVersions(allDependencies);
|
||||
//----------------------------------------------------------------------+
|
||||
// Use the nightly patch version if not a release but requires publish. |
|
||||
//----------------------------------------------------------------------+
|
||||
if (!isRelease) {
|
||||
for (const dependency of allDependencies) {
|
||||
const pkg = require(`../working-copy/${dependency}/package.json`);
|
||||
pkg.version = version;
|
||||
for (const dependency in pkg.dependencies) {
|
||||
if (allDependencies.indexOf(dependency) !== -1) {
|
||||
pkg.dependencies[dependency] = version;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(path('..', workingCopy, dependency, 'package.json'), JSON.stringify(pkg, null, 2));
|
||||
//----------------------------------------------+
|
||||
// Sanity check: all versions must be the same. |
|
||||
//----------------------------------------------+
|
||||
verifyVersions(allDependencies);
|
||||
//----------------------------------------------------------------------+
|
||||
// Use the nightly patch version if not a release but requires publish. |
|
||||
//----------------------------------------------------------------------+
|
||||
if (!isRelease) {
|
||||
for (const dependency of allDependencies) {
|
||||
const pkg = require(`../working-copy/${dependency}/package.json`);
|
||||
pkg.version = version;
|
||||
for (const dependency in pkg.dependencies) {
|
||||
if (allDependencies.indexOf(dependency) !== -1) {
|
||||
pkg.dependencies[dependency] = version;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, dependency, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
}
|
||||
verifyVersions(allDependencies);
|
||||
}
|
||||
verifyVersions(allDependencies);
|
||||
|
||||
//-------------------------------------------------------------+
|
||||
// Save some time: no need to build the `browser-app` example. |
|
||||
//-------------------------------------------------------------+
|
||||
//@ts-ignore
|
||||
let pkg = require('../working-copy/package.json');
|
||||
const workspaces = pkg.workspaces;
|
||||
// We cannot remove the `electron-app`. Otherwise, there is not way to collect the unused dependencies.
|
||||
const dependenciesToRemove = ['browser-app'];
|
||||
for (const dependencyToRemove of dependenciesToRemove) {
|
||||
const index = workspaces.indexOf(dependencyToRemove);
|
||||
if (index !== -1) {
|
||||
workspaces.splice(index, 1);
|
||||
}
|
||||
//-------------------------------------------------------------+
|
||||
// Save some time: no need to build the `browser-app` example. |
|
||||
//-------------------------------------------------------------+
|
||||
//@ts-ignore
|
||||
let pkg = require('../working-copy/package.json');
|
||||
const workspaces = pkg.workspaces;
|
||||
// We cannot remove the `electron-app`. Otherwise, there is not way to collect the unused dependencies.
|
||||
const dependenciesToRemove = ['browser-app'];
|
||||
for (const dependencyToRemove of dependenciesToRemove) {
|
||||
const index = workspaces.indexOf(dependencyToRemove);
|
||||
if (index !== -1) {
|
||||
workspaces.splice(index, 1);
|
||||
}
|
||||
pkg.workspaces = workspaces;
|
||||
fs.writeFileSync(path('..', workingCopy, 'package.json'), JSON.stringify(pkg, null, 2));
|
||||
}
|
||||
pkg.workspaces = workspaces;
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
// Rebuild the extension with the copied `yarn.lock`. It is a must to use the same Theia versions. |
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)}`, `Building the ${productName} application`);
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
// Rebuild the extension with the copied `yarn.lock`. It is a must to use the same Theia versions. |
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)}`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
// Test the application. With this approach, we cannot publish test results to GH Actions but save 6-10 minutes per builds |
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)} test`, `Testing the ${productName} application`);
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
// Test the application. With this approach, we cannot publish test results to GH Actions but save 6-10 minutes per builds |
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)} test`,
|
||||
`Testing the ${productName} application`
|
||||
);
|
||||
|
||||
// Collect all unused dependencies by the backend. We have to remove them from the electron app.
|
||||
// The `bundle.js` already contains everything we need for the frontend.
|
||||
// We have to do it before changing the dependencies to `local-path`.
|
||||
const unusedDependencies = await utils.collectUnusedDependencies('../working-copy/electron-app/');
|
||||
// Collect all unused dependencies by the backend. We have to remove them from the electron app.
|
||||
// The `bundle.js` already contains everything we need for the frontend.
|
||||
// We have to do it before changing the dependencies to `local-path`.
|
||||
const unusedDependencies = await utils.collectUnusedDependencies(
|
||||
'../working-copy/electron-app/'
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
// Change the regular NPM dependencies to `local-paths`, so that we can build them without any NPM registries. |
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
for (const extension of extensions) {
|
||||
if (extension !== 'arduino-ide-extension') { // Do not unlink self.
|
||||
// @ts-ignore
|
||||
pkg = require(`../working-copy/${extension}/package.json`);
|
||||
// @ts-ignore
|
||||
pkg.dependencies['arduino-ide-extension'] = 'file:../arduino-ide-extension';
|
||||
fs.writeFileSync(path('..', workingCopy, extension, 'package.json'), JSON.stringify(pkg, null, 2));
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
// Change the regular NPM dependencies to `local-paths`, so that we can build them without any NPM registries. |
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
for (const extension of extensions) {
|
||||
if (extension !== 'arduino-ide-extension') {
|
||||
// Do not unlink self.
|
||||
// @ts-ignore
|
||||
pkg = require(`../working-copy/${extension}/package.json`);
|
||||
// @ts-ignore
|
||||
pkg.dependencies['arduino-ide-extension'] =
|
||||
'file:../arduino-ide-extension';
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, extension, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------+
|
||||
// Merge the `working-copy/package.json` with `electron/build/template-package.json`. |
|
||||
//------------------------------------------------------------------------------------+
|
||||
//------------------------------------------------------------------------------------+
|
||||
// Merge the `working-copy/package.json` with `electron/build/template-package.json`. |
|
||||
//------------------------------------------------------------------------------------+
|
||||
// @ts-ignore
|
||||
pkg = require('../working-copy/electron-app/package.json');
|
||||
template.build.files = [
|
||||
...template.build.files,
|
||||
...unusedDependencies.map((name) => `!node_modules/${name}`),
|
||||
];
|
||||
|
||||
const dependencies = {};
|
||||
for (const extension of extensions) {
|
||||
dependencies[extension] = `file:../working-copy/${extension}`;
|
||||
}
|
||||
// @ts-ignore
|
||||
pkg.dependencies = { ...pkg.dependencies, ...dependencies };
|
||||
pkg.devDependencies = { ...pkg.devDependencies, ...template.devDependencies };
|
||||
// Deep-merging the Theia application configuration. We enable the electron window reload in dev mode but not for the final product. (arduino/arduino-pro-ide#187)
|
||||
// @ts-ignore
|
||||
const theia = merge(pkg.theia || {}, template.theia || {});
|
||||
const content = {
|
||||
...pkg,
|
||||
...template,
|
||||
theia,
|
||||
// @ts-ignore
|
||||
pkg = require('../working-copy/electron-app/package.json');
|
||||
template.build.files = [...template.build.files, ...unusedDependencies.map(name => `!node_modules/${name}`)];
|
||||
dependencies: pkg.dependencies,
|
||||
devDependencies: pkg.devDependencies,
|
||||
};
|
||||
const overwriteMerge = (destinationArray, sourceArray, options) =>
|
||||
sourceArray;
|
||||
fs.writeFileSync(
|
||||
path('..', 'build', 'package.json'),
|
||||
JSON.stringify(
|
||||
merge(content, template, { arrayMerge: overwriteMerge }),
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
|
||||
const dependencies = {};
|
||||
for (const extension of extensions) {
|
||||
dependencies[extension] = `file:../working-copy/${extension}`;
|
||||
}
|
||||
// @ts-ignore
|
||||
pkg.dependencies = { ...pkg.dependencies, ...dependencies };
|
||||
pkg.devDependencies = { ...pkg.devDependencies, ...template.devDependencies };
|
||||
// Deep-merging the Theia application configuration. We enable the electron window reload in dev mode but not for the final product. (arduino/arduino-pro-ide#187)
|
||||
// @ts-ignore
|
||||
const theia = merge((pkg.theia || {}), (template.theia || {}));
|
||||
const content = {
|
||||
...pkg,
|
||||
...template,
|
||||
theia,
|
||||
// @ts-ignore
|
||||
dependencies: pkg.dependencies,
|
||||
devDependencies: pkg.devDependencies
|
||||
};
|
||||
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
|
||||
fs.writeFileSync(path('..', 'build', 'package.json'), JSON.stringify(merge(content, template, { arrayMerge: overwriteMerge }), null, 2));
|
||||
|
||||
echo(`📜 Effective 'package.json' for the ${productName} application is:
|
||||
echo(`📜 Effective 'package.json' for the ${productName} application is:
|
||||
-----------------------
|
||||
${fs.readFileSync(path('..', 'build', 'package.json')).toString()}
|
||||
-----------------------
|
||||
`);
|
||||
|
||||
// Make sure the original `yarn.lock` file is used from the electron application.
|
||||
if (fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} must not exist.`);
|
||||
// Make sure the original `yarn.lock` file is used from the electron application.
|
||||
if (fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} must not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
cp('-rf', path(rootPath, 'yarn.lock'), path('..', 'build'));
|
||||
if (!fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} does not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
// Install all private and public dependencies for the electron application and build Theia. |
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')}`,
|
||||
'Installing dependencies'
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} build${isElectronPublish ? ':publish' : ''
|
||||
}`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} rebuild`,
|
||||
'Rebuild native dependencies'
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------------+
|
||||
// Create a throw away dotenv file which we use to feed the builder with input. |
|
||||
//------------------------------------------------------------------------------+
|
||||
const dotenv = 'electron-builder.env';
|
||||
if (fs.existsSync(path('..', 'build', dotenv))) {
|
||||
rm('-rf', path('..', 'build', dotenv));
|
||||
}
|
||||
// For the releases we use the desired tag as is defined by `$(Release.Tag)` from Azure.
|
||||
// For the preview builds we use the version from the `electron/build/package.json` with the short commit hash.
|
||||
fs.writeFileSync(path('..', 'build', dotenv), `ARDUINO_VERSION=${version}`);
|
||||
|
||||
//-----------------------------------+
|
||||
// Package the electron application. |
|
||||
//-----------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} package`,
|
||||
`Packaging your ${productName} application`
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
// Recalculate artifacts hash and copy to another folder (because they can change after signing them).
|
||||
// Azure does not support wildcard for `PublishBuildArtifacts@1.pathToPublish` |
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
if (isCI) {
|
||||
try {
|
||||
await recalculateArtifactsHash();
|
||||
await copyFilesToBuildArtifacts();
|
||||
} catch (e) {
|
||||
echo(JSON.stringify(e));
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
echo(`🎉 Success. Your application is at: ${path('..', 'build', 'dist')}`);
|
||||
|
||||
restore();
|
||||
|
||||
//--------+
|
||||
// Utils. |
|
||||
//--------+
|
||||
function exec(command, toEcho) {
|
||||
if (toEcho) {
|
||||
echo(`⏱️ >>> ${toEcho}...`);
|
||||
}
|
||||
const { code, stderr, stdout } = shell.exec(command);
|
||||
if (code !== 0) {
|
||||
echo(`🔥 Error when executing ${command} => ${stderr}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
if (toEcho) {
|
||||
echo(`👌 <<< ${toEcho}.`);
|
||||
}
|
||||
return stdout;
|
||||
}
|
||||
|
||||
function cp(options, source, destination) {
|
||||
shell.cp(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function rm(options, ...files) {
|
||||
shell.rm(options, files);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mv(options, source, destination) {
|
||||
shell.mv(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mkdir(options, ...dir) {
|
||||
shell.mkdir(options, dir);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function echo(command) {
|
||||
return shell.echo(command);
|
||||
}
|
||||
|
||||
function assertNoError() {
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
echo(error);
|
||||
restore();
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function restore() {
|
||||
if (fs.existsSync(path(rootPath, '.node_modules'))) {
|
||||
echo(
|
||||
"🔧 >>> [Restore] Renaming the root '.node_modules' folder to 'node_modules'..."
|
||||
);
|
||||
mv('-f', path(rootPath, '.node_modules'), path(rootPath, 'node_modules'));
|
||||
echo(
|
||||
"👌 >>> [Restore] Renamed the root '.node_modules' folder to 'node_modules'."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyFilesToBuildArtifacts() {
|
||||
echo(`🚢 Detected CI, moving build artifacts...`);
|
||||
const { platform } = process;
|
||||
const cwd = path('..', 'build', 'dist');
|
||||
const targetFolder = path('..', 'build', 'dist', 'build-artifacts');
|
||||
mkdir('-p', targetFolder);
|
||||
const filesToCopy = [];
|
||||
const channelFile = getChannelFile(platform);
|
||||
// Channel file might be an empty string if we're not building a
|
||||
// nightly or a full release. This can happen when building a package
|
||||
// locally or a tester build when creating a new PR on GH.
|
||||
if (!!channelFile && fs.existsSync(join(cwd, channelFile))) {
|
||||
const channelFilePath = join(cwd, channelFile);
|
||||
const newChannelFilePath = channelFilePath
|
||||
?.replace('latest', 'stable')
|
||||
?.replace('beta', 'nightly');
|
||||
echo(`🔨 >>> Renaming ${channelFilePath} to ${newChannelFilePath}.`);
|
||||
cp('-f', channelFilePath, newChannelFilePath);
|
||||
filesToCopy.push(newChannelFilePath);
|
||||
}
|
||||
switch (platform) {
|
||||
case 'linux': {
|
||||
filesToCopy.push(
|
||||
...glob
|
||||
.sync('**/arduino-ide*.{zip,AppImage}', { cwd })
|
||||
.map((p) => join(cwd, p))
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'win32': {
|
||||
filesToCopy.push(
|
||||
...glob
|
||||
.sync('**/arduino-ide*.{exe,msi,zip}', { cwd })
|
||||
.map((p) => join(cwd, p))
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'darwin': {
|
||||
filesToCopy.push(
|
||||
...glob
|
||||
.sync('**/arduino-ide*.{dmg,zip}', { cwd })
|
||||
.map((p) => join(cwd, p))
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
echo(`Unsupported platform: ${platform}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
cp('-rf', path(rootPath, 'yarn.lock'), path('..', 'build'));
|
||||
if (!fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} does not exist.`);
|
||||
if (!filesToCopy.length) {
|
||||
echo(`Could not collect any build artifacts from ${cwd}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
for (const fileToCopy of filesToCopy) {
|
||||
echo(`🚢 >>> Copying ${fileToCopy} to ${targetFolder}.`);
|
||||
const isZip = await utils.isZip(fileToCopy);
|
||||
if (isZip && platform === 'linux') {
|
||||
await utils.adjustArchiveStructure(fileToCopy, targetFolder);
|
||||
} else {
|
||||
cp('-rf', fileToCopy, targetFolder);
|
||||
}
|
||||
echo(`👌 >>> Copied ${fileToCopy} to ${targetFolder}.`);
|
||||
}
|
||||
}
|
||||
|
||||
async function recalculateArtifactsHash() {
|
||||
echo(`🚢 Detected CI, recalculating artifacts hash...`);
|
||||
const { platform } = process;
|
||||
const cwd = path('..', 'build', 'dist');
|
||||
const channelFilePath = join(cwd, getChannelFile(platform));
|
||||
const yaml = require('yaml');
|
||||
|
||||
try {
|
||||
let fileContents = fs.readFileSync(channelFilePath, 'utf8');
|
||||
const newChannelFile = yaml.parse(fileContents);
|
||||
const { files, path } = newChannelFile;
|
||||
const newSha512 = await hashFile(join(cwd, path));
|
||||
newChannelFile.sha512 = newSha512;
|
||||
if (!!files) {
|
||||
const newFiles = [];
|
||||
for (let file of files) {
|
||||
const { url } = file;
|
||||
const { size } = fs.statSync(join(cwd, url));
|
||||
const newSha512 = await hashFile(join(cwd, url));
|
||||
|
||||
if (!newFiles.find((f) => f.sha512 === newSha512)) {
|
||||
newFiles.push({ ...file, sha512: newSha512, size });
|
||||
}
|
||||
}
|
||||
newChannelFile.files = newFiles;
|
||||
}
|
||||
|
||||
const newChannelFileRaw = yaml.stringify(newChannelFile);
|
||||
fs.writeFileSync(channelFilePath, newChannelFileRaw);
|
||||
echo(`👌 >>> Channel file updated successfully. New channel file:`);
|
||||
echo(newChannelFileRaw);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function hashFile(
|
||||
file,
|
||||
algorithm = 'sha512',
|
||||
encoding = 'base64',
|
||||
options
|
||||
) {
|
||||
const crypto = require('crypto');
|
||||
return await new Promise((resolve, reject) => {
|
||||
const hash = crypto.createHash(algorithm);
|
||||
hash.on('error', reject).setEncoding(encoding);
|
||||
fs.createReadStream(
|
||||
file,
|
||||
Object.assign({}, options, {
|
||||
highWaterMark: 1024 * 1024,
|
||||
/* better to use more memory but hash faster */
|
||||
})
|
||||
)
|
||||
.on('error', reject)
|
||||
.on('end', () => {
|
||||
hash.end();
|
||||
resolve(hash.read());
|
||||
})
|
||||
.pipe(hash, {
|
||||
end: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins tha path from `__dirname`.
|
||||
*/
|
||||
function path(...paths) {
|
||||
return join(__dirname, ...paths);
|
||||
}
|
||||
|
||||
function verifyVersions(allDependencies, expectedVersion) {
|
||||
const versions = new Set();
|
||||
for (const dependency of allDependencies) {
|
||||
versions.add(
|
||||
require(`../working-copy/${dependency}/package.json`).version
|
||||
);
|
||||
}
|
||||
if (versions.size !== 1) {
|
||||
echo(
|
||||
`Mismatching version configuration. All dependencies must have the same version. Versions were: ${JSON.stringify(
|
||||
Array.from(versions),
|
||||
null,
|
||||
2
|
||||
)}.`
|
||||
);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
if (expectedVersion) {
|
||||
if (!versions.has(expectedVersion)) {
|
||||
echo(
|
||||
`Mismatching version configuration. Expected version was: '${expectedVersion}' actual was: '${Array.from(versions)[0]
|
||||
}'.`
|
||||
);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
// Install all private and public dependencies for the electron application and build Theia. |
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', 'build')}`, 'Installing dependencies');
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} build${isElectronPublish ? ':publish' : ''}`, `Building the ${productName} application`);
|
||||
|
||||
//------------------------------------------------------------------------------+
|
||||
// Create a throw away dotenv file which we use to feed the builder with input. |
|
||||
//------------------------------------------------------------------------------+
|
||||
const dotenv = 'electron-builder.env';
|
||||
if (fs.existsSync(path('..', 'build', dotenv))) {
|
||||
rm('-rf', path('..', 'build', dotenv));
|
||||
}
|
||||
// For the releases we use the desired tag as is defined by `$(Release.Tag)` from Azure.
|
||||
// For the preview builds we use the version from the `electron/build/package.json` with the short commit hash.
|
||||
fs.writeFileSync(path('..', 'build', dotenv), `ARDUINO_VERSION=${version}`);
|
||||
|
||||
//-----------------------------------+
|
||||
// Package the electron application. |
|
||||
//-----------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} package`, `Packaging your ${productName} application`);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
// Copy to another folder. Azure does not support wildcard for `PublishBuildArtifacts@1.pathToPublish` |
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
if (isCI) {
|
||||
try {
|
||||
await copyFilesToBuildArtifacts();
|
||||
} catch (e) {
|
||||
echo(JSON.stringify(e));
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
echo(`🎉 Success. Your application is at: ${path('..', 'build', 'dist')}`);
|
||||
|
||||
restore();
|
||||
|
||||
//--------+
|
||||
// Utils. |
|
||||
//--------+
|
||||
function exec(command, toEcho) {
|
||||
if (toEcho) {
|
||||
echo(`⏱️ >>> ${toEcho}...`);
|
||||
}
|
||||
const { code, stderr, stdout } = shell.exec(command);
|
||||
if (code !== 0) {
|
||||
echo(`🔥 Error when executing ${command} => ${stderr}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
if (toEcho) {
|
||||
echo(`👌 <<< ${toEcho}.`);
|
||||
}
|
||||
return stdout;
|
||||
}
|
||||
|
||||
function cp(options, source, destination) {
|
||||
shell.cp(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function rm(options, ...files) {
|
||||
shell.rm(options, files);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mv(options, source, destination) {
|
||||
shell.mv(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mkdir(options, ...dir) {
|
||||
shell.mkdir(options, dir);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function echo(command) {
|
||||
return shell.echo(command);
|
||||
}
|
||||
|
||||
function assertNoError() {
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
echo(error);
|
||||
restore();
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function restore() {
|
||||
if (fs.existsSync(path(rootPath, '.node_modules'))) {
|
||||
echo('🔧 >>> [Restore] Renaming the root \'.node_modules\' folder to \'node_modules\'...');
|
||||
mv('-f', path(rootPath, '.node_modules'), path(rootPath, 'node_modules'));
|
||||
echo('👌 >>> [Restore] Renamed the root \'.node_modules\' folder to \'node_modules\'.');
|
||||
}
|
||||
}
|
||||
|
||||
async function copyFilesToBuildArtifacts() {
|
||||
echo(`🚢 Detected CI, moving build artifacts...`);
|
||||
const { platform } = process;
|
||||
const cwd = path('..', 'build', 'dist');
|
||||
const targetFolder = path('..', 'build', 'dist', 'build-artifacts');
|
||||
mkdir('-p', targetFolder);
|
||||
const filesToCopy = [];
|
||||
switch (platform) {
|
||||
case 'linux': {
|
||||
filesToCopy.push(...glob.sync('**/arduino-ide*.{zip,AppImage}', { cwd }).map(p => join(cwd, p)));
|
||||
break;
|
||||
}
|
||||
case 'win32': {
|
||||
filesToCopy.push(...glob.sync('**/arduino-ide*.{exe,msi,zip}', { cwd }).map(p => join(cwd, p)));
|
||||
break;
|
||||
}
|
||||
case 'darwin': {
|
||||
filesToCopy.push(...glob.sync('**/arduino-ide*.{dmg,zip}', { cwd }).map(p => join(cwd, p)));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
echo(`Unsupported platform: ${platform}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
if (!filesToCopy.length) {
|
||||
echo(`Could not collect any build artifacts from ${cwd}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
for (const fileToCopy of filesToCopy) {
|
||||
echo(`🚢 >>> Copying ${fileToCopy} to ${targetFolder}.`);
|
||||
const isZip = await utils.isZip(fileToCopy);
|
||||
if (isZip) {
|
||||
await utils.adjustArchiveStructure(fileToCopy, targetFolder);
|
||||
} else {
|
||||
cp('-rf', fileToCopy, targetFolder);
|
||||
}
|
||||
echo(`👌 >>> Copied ${fileToCopy} to ${targetFolder}.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins tha path from `__dirname`.
|
||||
*/
|
||||
function path(...paths) {
|
||||
return join(__dirname, ...paths);
|
||||
}
|
||||
|
||||
function verifyVersions(allDependencies, expectedVersion) {
|
||||
const versions = new Set();
|
||||
for (const dependency of allDependencies) {
|
||||
versions.add(require(`../working-copy/${dependency}/package.json`).version);
|
||||
}
|
||||
if (versions.size !== 1) {
|
||||
echo(`Mismatching version configuration. All dependencies must have the same version. Versions were: ${JSON.stringify(Array.from(versions), null, 2)}.`);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
if (expectedVersion) {
|
||||
if (!versions.has(expectedVersion)) {
|
||||
echo(`Mismatching version configuration. Expected version was: '${expectedVersion}' actual was: '${Array.from(versions)[0]}'.`);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
@@ -13,10 +13,11 @@
|
||||
"author": "Arduino SA",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"7zip-min": "^1.1.1",
|
||||
"@types/file-type": "^10.9.1",
|
||||
"@types/temp": "^0.8.32",
|
||||
"7zip-min": "^1.1.1",
|
||||
"chai": "^4.2.0",
|
||||
"crypto": "^1.0.1",
|
||||
"dateformat": "^3.0.3",
|
||||
"deepmerge": "2.01",
|
||||
"depcheck": "^0.9.2",
|
||||
@@ -25,13 +26,14 @@
|
||||
"is-ci": "^2.0.0",
|
||||
"mocha": "^7.1.1",
|
||||
"semver": "^7.3.2",
|
||||
"sinon": "^9.0.1",
|
||||
"shelljs": "^0.8.3",
|
||||
"sinon": "^9.0.1",
|
||||
"temp": "^0.9.1",
|
||||
"yaml": "^1.10.2",
|
||||
"yargs": "^12.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.14.1 <13"
|
||||
"node": ">=14.0.0 <15"
|
||||
},
|
||||
"mocha": {
|
||||
"reporter": "spec",
|
||||
@@ -39,4 +41,4 @@
|
||||
"watch-extensions": "js",
|
||||
"timeout": 10000
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,112 +8,112 @@ const sinon = require('sinon');
|
||||
|
||||
describe('utils', () => {
|
||||
|
||||
describe('adjustArchiveStructure', () => {
|
||||
describe('adjustArchiveStructure', () => {
|
||||
|
||||
let consoleStub;
|
||||
|
||||
beforeEach(() => {
|
||||
consoleStub = sinon.stub(console, 'log').value(() => { });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
consoleStub.reset();
|
||||
track.cleanupSync();
|
||||
});
|
||||
|
||||
it('should reject when not a zip file', async () => {
|
||||
try {
|
||||
const invalid = path.join(__dirname, 'resources', 'not-a-zip.dmg');
|
||||
await testMe.adjustArchiveStructure(invalid, track.mkdirSync());
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message).to.be.equal('Expected a ZIP file.');
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target directory does not exist', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__dirname, 'some', 'missing', 'path'));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('does not exist.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target is a file', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__filename));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('is not a directory.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should be a NOOP when the zip already has the desired base folder', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
const actual = await testMe.adjustArchiveStructure(zip, track.mkdirSync());
|
||||
expect(actual).to.be.equal(zip);
|
||||
});
|
||||
|
||||
it('should handle whitespace in file path gracefully', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip with whitespace.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip with whitespace.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip with whitespace');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
|
||||
it('should keep the symlinks after ZIP adjustments', async function () {
|
||||
if (process.platform === 'win32') {
|
||||
this.skip();
|
||||
}
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-with-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
expect(fs.lstatSync(path.join(verifyOut, 'zip-with-symlink', 'folder', 'symlinked-sub')).isSymbolicLink()).to.be.true;
|
||||
});
|
||||
|
||||
it('should adjust the archive structure if base folder is not present', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-without-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-without-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip-without-symlink');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
let consoleStub;
|
||||
|
||||
beforeEach(() => {
|
||||
consoleStub = sinon.stub(console, 'log').value(() => { });
|
||||
});
|
||||
|
||||
});
|
||||
afterEach(() => {
|
||||
consoleStub.reset();
|
||||
track.cleanupSync();
|
||||
});
|
||||
|
||||
it('should reject when not a zip file', async () => {
|
||||
try {
|
||||
const invalid = path.join(__dirname, 'resources', 'not-a-zip.dmg');
|
||||
await testMe.adjustArchiveStructure(invalid, track.mkdirSync());
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message).to.be.equal('Expected a ZIP file.');
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target directory does not exist', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__dirname, 'some', 'missing', 'path'));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('does not exist.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target is a file', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__filename));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('is not a directory.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should be a NOOP when the zip already has the desired base folder', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
const actual = await testMe.adjustArchiveStructure(zip, track.mkdirSync());
|
||||
expect(actual).to.be.equal(zip);
|
||||
});
|
||||
|
||||
it('should handle whitespace in file path gracefully', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip with whitespace.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip with whitespace.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip with whitespace');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
|
||||
it('should keep the symlinks after ZIP adjustments', async function () {
|
||||
if (process.platform === 'win32') {
|
||||
this.skip();
|
||||
}
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-with-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
expect(fs.lstatSync(path.join(verifyOut, 'zip-with-symlink', 'folder', 'symlinked-sub')).isSymbolicLink()).to.be.true;
|
||||
});
|
||||
|
||||
it('should adjust the archive structure if base folder is not present', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-without-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-without-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip-without-symlink');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
@@ -12,35 +12,42 @@ const fromFile = require('file-type').fromFile;
|
||||
* Resolves to an array of `npm` package names that are declared in the `package.json` but **not** used by the project.
|
||||
*/
|
||||
function collectUnusedDependencies(pathToProject = process.cwd()) {
|
||||
const p = path.isAbsolute(pathToProject) ? pathToProject : path.resolve(process.cwd(), pathToProject);
|
||||
console.log(`⏱️ >>> Collecting unused backend dependencies for ${p}...`);
|
||||
return new Promise(resolve => {
|
||||
depcheck(p, {
|
||||
ignoreDirs: [
|
||||
'frontend'
|
||||
],
|
||||
parsers: {
|
||||
'*.js': depcheck.parser.es6,
|
||||
'*.jsx': depcheck.parser.jsx
|
||||
},
|
||||
detectors: [
|
||||
depcheck.detector.requireCallExpression,
|
||||
depcheck.detector.importDeclaration
|
||||
],
|
||||
specials: [
|
||||
depcheck.special.eslint,
|
||||
depcheck.special.webpack
|
||||
]
|
||||
}, unused => {
|
||||
const { dependencies } = unused
|
||||
if (dependencies && dependencies.length > 0) {
|
||||
console.log(`👌 <<< The following unused dependencies have been found: ${JSON.stringify(dependencies, null, 2)}`);
|
||||
} else {
|
||||
console.log('👌 <<< No unused dependencies have been found.');
|
||||
}
|
||||
resolve(dependencies);
|
||||
});
|
||||
})
|
||||
const p = path.isAbsolute(pathToProject)
|
||||
? pathToProject
|
||||
: path.resolve(process.cwd(), pathToProject);
|
||||
console.log(`⏱️ >>> Collecting unused backend dependencies for ${p}...`);
|
||||
return new Promise((resolve) => {
|
||||
depcheck(
|
||||
p,
|
||||
{
|
||||
ignoreDirs: ['frontend'],
|
||||
parsers: {
|
||||
'*.js': depcheck.parser.es6,
|
||||
'*.jsx': depcheck.parser.jsx,
|
||||
},
|
||||
detectors: [
|
||||
depcheck.detector.requireCallExpression,
|
||||
depcheck.detector.importDeclaration,
|
||||
],
|
||||
specials: [depcheck.special.eslint, depcheck.special.webpack],
|
||||
},
|
||||
(unused) => {
|
||||
const { dependencies } = unused;
|
||||
if (dependencies && dependencies.length > 0) {
|
||||
console.log(
|
||||
`👌 <<< The following unused dependencies have been found: ${JSON.stringify(
|
||||
dependencies,
|
||||
null,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
} else {
|
||||
console.log('👌 <<< No unused dependencies have been found.');
|
||||
}
|
||||
resolve(dependencies);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,101 +57,111 @@ function collectUnusedDependencies(pathToProject = process.cwd()) {
|
||||
* If `pathToZip` is not a ZIP, rejects. `targetFolderName` is the destination folder not the new archive location.
|
||||
*/
|
||||
function adjustArchiveStructure(pathToZip, targetFolderName, noCleanup) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!await isZip(pathToZip)) {
|
||||
reject(new Error(`Expected a ZIP file.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(targetFolderName)) {
|
||||
reject(new Error(`${targetFolderName} does not exist.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.lstatSync(targetFolderName).isDirectory()) {
|
||||
reject(new Error(`${targetFolderName} is not a directory.`));
|
||||
return;
|
||||
}
|
||||
console.log(`⏱️ >>> Adjusting ZIP structure ${pathToZip}...`);
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!(await isZip(pathToZip))) {
|
||||
reject(new Error(`Expected a ZIP file.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(targetFolderName)) {
|
||||
reject(new Error(`${targetFolderName} does not exist.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.lstatSync(targetFolderName).isDirectory()) {
|
||||
reject(new Error(`${targetFolderName} is not a directory.`));
|
||||
return;
|
||||
}
|
||||
console.log(`⏱️ >>> Adjusting ZIP structure ${pathToZip}...`);
|
||||
|
||||
const root = basename(pathToZip);
|
||||
const resources = await list(pathToZip);
|
||||
const hasBaseFolder = resources.find(name => name === root);
|
||||
if (hasBaseFolder) {
|
||||
if (resources.filter(name => name.indexOf(path.sep) === -1).length > 1) {
|
||||
console.warn(`${pathToZip} ZIP has the desired root folder ${root}, however the ZIP contains other entries too: ${JSON.stringify(resources)}`);
|
||||
}
|
||||
console.log(`👌 <<< The ZIP already has the desired ${root} folder.`);
|
||||
resolve(pathToZip);
|
||||
return;
|
||||
}
|
||||
const root = basename(pathToZip);
|
||||
const resources = await list(pathToZip);
|
||||
const hasBaseFolder = resources.find((name) => name === root);
|
||||
if (hasBaseFolder) {
|
||||
if (
|
||||
resources.filter((name) => name.indexOf(path.sep) === -1).length > 1
|
||||
) {
|
||||
console.warn(
|
||||
`${pathToZip} ZIP has the desired root folder ${root}, however the ZIP contains other entries too: ${JSON.stringify(
|
||||
resources
|
||||
)}`
|
||||
);
|
||||
}
|
||||
console.log(`👌 <<< The ZIP already has the desired ${root} folder.`);
|
||||
resolve(pathToZip);
|
||||
return;
|
||||
}
|
||||
|
||||
const track = temp.track();
|
||||
try {
|
||||
const unzipOut = path.join(track.mkdirSync(), root);
|
||||
fs.mkdirSync(unzipOut);
|
||||
await unpack(pathToZip, unzipOut);
|
||||
const adjustedZip = path.join(targetFolderName, path.basename(pathToZip));
|
||||
await pack(unzipOut, adjustedZip);
|
||||
console.log(`👌 <<< Adjusted the ZIP structure. Moved the modified ${basename(pathToZip)} to the ${targetFolderName} folder.`);
|
||||
resolve(adjustedZip);
|
||||
} finally {
|
||||
if (!noCleanup) {
|
||||
track.cleanupSync();
|
||||
}
|
||||
}
|
||||
});
|
||||
const track = temp.track();
|
||||
try {
|
||||
const unzipOut = path.join(track.mkdirSync(), root);
|
||||
fs.mkdirSync(unzipOut);
|
||||
await unpack(pathToZip, unzipOut);
|
||||
const adjustedZip = path.join(targetFolderName, path.basename(pathToZip));
|
||||
await pack(unzipOut, adjustedZip);
|
||||
console.log(
|
||||
`👌 <<< Adjusted the ZIP structure. Moved the modified ${basename(
|
||||
pathToZip
|
||||
)} to the ${targetFolderName} folder.`
|
||||
);
|
||||
resolve(adjustedZip);
|
||||
} finally {
|
||||
if (!noCleanup) {
|
||||
track.cleanupSync();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `basename` of `pathToFile` without the file extension.
|
||||
*/
|
||||
function basename(pathToFile) {
|
||||
const name = path.basename(pathToFile);
|
||||
const ext = path.extname(pathToFile);
|
||||
return name.substr(0, name.length - ext.length);
|
||||
const name = path.basename(pathToFile);
|
||||
const ext = path.extname(pathToFile);
|
||||
return name.substr(0, name.length - ext.length);
|
||||
}
|
||||
|
||||
function unpack(what, where) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.unpack(what, where, error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.unpack(what, where, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pack(what, where) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.pack(what, where, error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.pack(what, where, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function list(what) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.list(what, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(result.map(({ name }) => name));
|
||||
})
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.list(what, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(result.map(({ name }) => name));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function isZip(pathToFile) {
|
||||
if (!fs.existsSync(pathToFile)) {
|
||||
throw new Error(`${pathToFile} does not exist`);
|
||||
}
|
||||
const type = await fromFile(pathToFile);
|
||||
return type && type.ext === 'zip';
|
||||
if (!fs.existsSync(pathToFile)) {
|
||||
throw new Error(`${pathToFile} does not exist`);
|
||||
}
|
||||
const type = await fromFile(pathToFile);
|
||||
return type && type.ext === 'zip';
|
||||
}
|
||||
|
||||
const isElectronPublish = false; // TODO: support auto-updates
|
||||
@@ -152,20 +169,56 @@ const isNightly = process.env.IS_NIGHTLY === 'true';
|
||||
const isRelease = process.env.IS_RELEASE === 'true';
|
||||
|
||||
function git(command) {
|
||||
try {
|
||||
const gitPath = shell.which('git');
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
const { stderr, stdout } = shell.exec(`"${gitPath}" ${command}`, { silent: true });
|
||||
if (stderr) {
|
||||
throw new Error(stderr.toString().trim());
|
||||
}
|
||||
return stdout.toString().trim();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
try {
|
||||
const gitPath = shell.which('git');
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
const { stderr, stdout } = shell.exec(`"${gitPath}" ${command}`, {
|
||||
silent: true,
|
||||
});
|
||||
if (stderr) {
|
||||
throw new Error(stderr.toString().trim());
|
||||
}
|
||||
return stdout.toString().trim();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { collectUnusedDependencies, adjustArchiveStructure, isZip, unpack, isNightly, isRelease, isElectronPublish, git };
|
||||
// getChannelFile returns the name of the channel file to be released
|
||||
// together with the IDE file.
|
||||
// The channel file depends on the platform and whether we're creating
|
||||
// a nightly build or a full release.
|
||||
// In all other cases, like when building a tester build for a PR,
|
||||
// an empty string is returned since we don't need a channel file.
|
||||
// The channel files are necessary for updates check with electron-updater
|
||||
// to work correctly.
|
||||
// For more information: https://www.electron.build/auto-update
|
||||
function getChannelFile(platform) {
|
||||
let currentChannel = 'beta';
|
||||
if (isRelease) {
|
||||
currentChannel = 'latest';
|
||||
}
|
||||
return (
|
||||
currentChannel +
|
||||
{
|
||||
linux: '-linux.yml',
|
||||
win32: '.yml',
|
||||
darwin: '-mac.yml',
|
||||
}[platform]
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
collectUnusedDependencies,
|
||||
adjustArchiveStructure,
|
||||
isZip,
|
||||
unpack,
|
||||
isNightly,
|
||||
isRelease,
|
||||
isElectronPublish,
|
||||
git,
|
||||
getChannelFile,
|
||||
};
|
||||
|
@@ -437,6 +437,11 @@ cross-spawn@^6.0.0:
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
crypto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037"
|
||||
integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==
|
||||
|
||||
dateformat@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
||||
@@ -1597,6 +1602,11 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
||||
|
||||
yaml@^1.10.2:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||
|
||||
yargs-parser@13.1.2, yargs-parser@^13.1.2:
|
||||
version "13.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
|
||||
|
19
i18n/en.json
19
i18n/en.json
@@ -14,6 +14,22 @@
|
||||
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
|
||||
"loseChanges": "If you don't save, your changes will be lost."
|
||||
},
|
||||
"ide-updater": {
|
||||
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
|
||||
"notNowButton": "Not now",
|
||||
"versionDownloaded": "Arduino IDE {0} has been downloaded.",
|
||||
"closeToInstallNotice": "Close the software and install the update on your machine.",
|
||||
"closeAndInstallButton": "Close and Install",
|
||||
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
|
||||
"updateAvailable": "Update Available",
|
||||
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
|
||||
"skipVersionButton": "Skip Version",
|
||||
"downloadButton": "Download",
|
||||
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
|
||||
"goToDownloadButton": "Go To Download",
|
||||
"ideUpdaterDialog": "Software Update",
|
||||
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE"
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Sketch",
|
||||
"tools": "Tools"
|
||||
@@ -31,7 +47,7 @@
|
||||
"upload.verbose": "True for verbose upload output. False by default.",
|
||||
"window.autoScale": "True if the user interface automatically scales with the font size.",
|
||||
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.",
|
||||
"ide.autoUpdate": "True to enable automatic update checks. The IDE will check for updates automatically and periodically.",
|
||||
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
|
||||
"board.certificates": "List of certificates that can be uploaded to boards",
|
||||
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.",
|
||||
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.",
|
||||
@@ -55,7 +71,6 @@
|
||||
"compile": "compile",
|
||||
"upload": "upload",
|
||||
"verifyAfterUpload": "Verify code after upload",
|
||||
"checkForUpdates": "Check for updates on startup",
|
||||
"editorQuickSuggestions": "Editor Quick Suggestions",
|
||||
"additionalManagerURLs": "Additional Boards Manager URLs",
|
||||
"noProxy": "No proxy",
|
||||
|
14
package.json
14
package.json
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "arduino-ide",
|
||||
"version": "2.0.0-rc3",
|
||||
"version": "2.0.0-rc4",
|
||||
"description": "Arduino IDE",
|
||||
"repository": "https://github.com/arduino/arduino-ide.git",
|
||||
"author": "Arduino SA",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=12.14.1 <13"
|
||||
"node": ">=14.0.0 <15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0",
|
||||
"@theia/cli": "1.22.1",
|
||||
"@types/sinon": "^2.3.5",
|
||||
"@types/jsdom": "^11.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^4.27.0",
|
||||
@@ -33,6 +33,10 @@
|
||||
"typescript": "^3.9.2",
|
||||
"jsdom": "^11.5.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"find-git-exec": "0.0.4",
|
||||
"dugite-extra": "0.1.15"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "cross-env THEIA_ELECTRON_SKIP_REPLACE_FFMPEG=1 lerna run prepare && yarn download:plugins",
|
||||
"cleanup": "npx rimraf ./**/node_modules && rm -rf ./node_modules ./.browser_modules ./arduino-ide-extension/build ./arduino-ide-extension/downloads ./arduino-ide-extension/Examples ./arduino-ide-extension/lib ./browser-app/lib ./browser-app/src-gen ./browser-app/gen-webpack.config.js ./electron-app/lib ./electron-app/src-gen ./electron-app/gen-webpack.config.js",
|
||||
@@ -67,9 +71,9 @@
|
||||
"theiaPluginsDir": "plugins",
|
||||
"theiaPlugins": {
|
||||
"vscode-builtin-cpp": "https://open-vsx.org/api/vscode/cpp/1.52.1/file/vscode.cpp-1.52.1.vsix",
|
||||
"vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.1.vsix",
|
||||
"vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.2.vsix",
|
||||
"vscode-builtin-json": "https://open-vsx.org/api/vscode/json/1.46.1/file/vscode.json-1.46.1.vsix",
|
||||
"vscode-builtin-json-language-features": "https://open-vsx.org/api/vscode/json-language-features/1.46.1/file/vscode.json-language-features-1.46.1.vsix",
|
||||
"cortex-debug": "https://open-vsx.org/api/marus25/cortex-debug/0.3.10/file/marus25.cortex-debug-0.3.10.vsix"
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user