mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-22 09:38:31 +00:00
Compare commits
55 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2be1fac585 | ||
![]() |
b35340caa9 | ||
![]() |
e6b3e2ec23 | ||
![]() |
c07232698c | ||
![]() |
58e992af13 | ||
![]() |
a44b84ffd0 | ||
![]() |
a3640cf812 | ||
![]() |
03a75273e3 | ||
![]() |
6176e50acf | ||
![]() |
46a3466bc5 | ||
![]() |
aba9db6a6b | ||
![]() |
e5b34624ac | ||
![]() |
c430cf0d88 | ||
![]() |
1969e292f0 | ||
![]() |
0db119d7ba | ||
![]() |
c9b498fb08 | ||
![]() |
78004fa4ca | ||
![]() |
4de7737d14 | ||
![]() |
f36df02f5d | ||
![]() |
753872ea2a | ||
![]() |
ca1c24050d | ||
![]() |
61c2b1a007 | ||
![]() |
8cac0872a4 | ||
![]() |
70f1c5f8ec | ||
![]() |
b416e5f9e8 | ||
![]() |
bfe6835cab | ||
![]() |
9e89964df2 | ||
![]() |
04c3d0c1d3 | ||
![]() |
c9996df11c | ||
![]() |
49971ada07 | ||
![]() |
e6b9d4e2aa | ||
![]() |
93a374d0c6 | ||
![]() |
0fc7c78e11 | ||
![]() |
96b5edf427 | ||
![]() |
a5a6a0b611 | ||
![]() |
2a27a14a68 | ||
![]() |
f2d492b5dc | ||
![]() |
5979e5aad2 | ||
![]() |
baa9b5f7ab | ||
![]() |
481497e384 | ||
![]() |
0207778373 | ||
![]() |
d79f32efd7 | ||
![]() |
3ab03dd62f | ||
![]() |
bc3cb0c230 | ||
![]() |
473cb11053 | ||
![]() |
0a87fd00f3 | ||
![]() |
9b1f15def8 | ||
![]() |
77b430675d | ||
![]() |
f660058c75 | ||
![]() |
9ecff86bbe | ||
![]() |
5ab3a747a6 | ||
![]() |
877c1a1559 | ||
![]() |
2f9bf86d75 | ||
![]() |
112153fb96 | ||
![]() |
69ac1f4779 |
72
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
72
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: Bug report
|
||||
description: Report a problem with the code or documentation in this repository.
|
||||
labels:
|
||||
- "type: imperfection"
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduce
|
||||
attributes:
|
||||
label: To reproduce
|
||||
description: Provide the specific set of steps we can follow to reproduce the problem.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: What would you expect to happen after following those instructions?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: project-version
|
||||
attributes:
|
||||
label: Arduino IDE version
|
||||
description: |
|
||||
Which version of the Arduino IDE are you using?
|
||||
See **Help > About Arduino IDE** in the Arduino IDE menus (**Arduino IDE > About Arduino IDE** on macOS).
|
||||
This should be the latest [nightly build](https://github.com/arduino/arduino-ide#nightly-builds).
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
description: Which operating system are you using on your computer?
|
||||
options:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-version
|
||||
attributes:
|
||||
label: Operating system version
|
||||
description: Which version of the operating system are you using on your computer?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any additional information here.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Issue checklist
|
||||
description: Please double-check that you have done each of the following things before submitting the issue.
|
||||
options:
|
||||
- label: I searched for previous reports in [the issue tracker](https://github.com/arduino/arduino-ide/issues?q=)
|
||||
required: true
|
||||
- label: I verified the problem still occurs when using the latest [nightly build](https://github.com/arduino/arduino-ide#nightly-builds)
|
||||
required: true
|
||||
- label: My report contains all necessary details
|
||||
required: true
|
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,32 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'type: imperfection'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. Windows]
|
||||
- Version: [e.g. 2.0.0]
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
13
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
13
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Source:
|
||||
# https://github.com/arduino/tooling-project-assets/blob/main/issue-templates/template-choosers/general/config.yml
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Learn about using this project
|
||||
url: https://github.com/arduino/arduino-ide#readme
|
||||
about: Detailed usage documentation is available here.
|
||||
- name: Support request
|
||||
url: https://forum.arduino.cc/
|
||||
about: We can help you out on the Arduino Forum!
|
||||
- name: Discuss development work on the project
|
||||
url: https://groups.google.com/a/arduino.cc/g/developers
|
||||
about: Arduino Developers Mailing List
|
67
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
67
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: Feature request
|
||||
description: Suggest an enhancement to this project.
|
||||
labels:
|
||||
- "type: enhancement"
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the request
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: current
|
||||
attributes:
|
||||
label: Describe the current behavior
|
||||
description: |
|
||||
What is the current behavior of the Arduino IDE in relation to your request?
|
||||
How can we reproduce that behavior?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: project-version
|
||||
attributes:
|
||||
label: Arduino IDE version
|
||||
description: |
|
||||
Which version of the Arduino IDE are you using?
|
||||
See **Help > About Arduino IDE** in the Arduino IDE menus (**Arduino IDE > About Arduino IDE** on macOS).
|
||||
This should be the latest [nightly build](https://github.com/arduino/arduino-ide#nightly-builds).
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
description: Which operating system are you using on your computer?
|
||||
options:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-version
|
||||
attributes:
|
||||
label: Operating system version
|
||||
description: Which version of the operating system are you using on your computer?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any additional information here.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Issue checklist
|
||||
description: Please double-check that you have done each of the following things before submitting the issue.
|
||||
options:
|
||||
- label: I searched for previous requests in [the issue tracker](https://github.com/arduino/arduino-ide/issues?q=)
|
||||
required: true
|
||||
- label: I verified the feature was still missing when using the latest [nightly build](https://github.com/arduino/arduino-ide#nightly-builds)
|
||||
required: true
|
||||
- label: My request contains all necessary details
|
||||
required: true
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'type: enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
### Motivation
|
||||
<!-- Why this pull request? -->
|
||||
|
||||
### Change description
|
||||
<!-- What does your code do? -->
|
||||
|
||||
### Other information
|
||||
<!-- Any additional information that could help the review process -->
|
||||
|
||||
### Reviewer checklist
|
||||
|
||||
* [ ] PR addresses a single concern.
|
||||
* [ ] The PR has no duplicates (please search among the [Pull Requests](https://github.com/arduino/arduino-ide/pulls) before creating one)
|
||||
* [ ] PR title and description are properly filled.
|
||||
* [ ] Docs have been added / updated (for bug fixes / features)
|
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
|
||||
|
14
.github/workflows/compose-full-changelog.yaml
vendored
14
.github/workflows/compose-full-changelog.yaml
vendored
@@ -2,10 +2,13 @@ name: Compose full changelog
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created, edited]
|
||||
types:
|
||||
- edited
|
||||
|
||||
env:
|
||||
CHANGELOG_ARTIFACTS: changelog
|
||||
# See: https://github.com/actions/setup-node/#readme
|
||||
NODE_VERSION: 14.x
|
||||
|
||||
jobs:
|
||||
create-changelog:
|
||||
@@ -15,6 +18,12 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Get Tag
|
||||
id: tag_name
|
||||
run: |
|
||||
@@ -23,10 +32,11 @@ jobs:
|
||||
- name: Create full changelog
|
||||
id: full-changelog
|
||||
run: |
|
||||
yarn add @octokit/rest --ignore-workspace-root-check
|
||||
mkdir "${{ github.workspace }}/${{ env.CHANGELOG_ARTIFACTS }}"
|
||||
|
||||
# Get the changelog file name to build
|
||||
CHANGELOG_FILE_NAME="${{ steps.tag_name.outputs.TAG_NAME }}-$(date --iso-8601=s).md"
|
||||
CHANGELOG_FILE_NAME="${{ steps.tag_name.outputs.TAG_NAME }}-$(date +%s).md"
|
||||
|
||||
# Create manifest file pointing to latest changelog file name
|
||||
echo "$CHANGELOG_FILE_NAME" >> "${{ github.workspace }}/${{ env.CHANGELOG_ARTIFACTS }}/latest.txt"
|
||||
|
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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
13
BUILDING.md
13
BUILDING.md
@@ -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
|
||||
@@ -67,6 +66,13 @@ Once you have all the tools installed, you can build the editor following these
|
||||
yarn start
|
||||
```
|
||||
|
||||
### Notes for Windows contributors
|
||||
Windows requires the Microsoft Visual C++ (MSVC) compiler toolset to be installed on your development machine.
|
||||
|
||||
In case it's not already present, it can be downloaded from the "**Tools for Visual Studio 20XX**" section of the Visual Studio [downloads page](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022) via the "**Build Tools for Visual Studio 20XX**" (e.g., "**Build Tools for Visual Studio 2022**") download link.
|
||||
|
||||
Select "**Desktop development with C++**" from the "**Workloads**" tab during the installation procedure.
|
||||
|
||||
### CI
|
||||
|
||||
This project is built on [GitHub Actions](https://github.com/arduino/arduino-ide/actions).
|
||||
@@ -83,6 +89,7 @@ This project is built on [GitHub Actions](https://github.com/arduino/arduino-ide
|
||||
git push origin 1.2.3
|
||||
```
|
||||
|
||||
|
||||
## Notes for macOS contributors
|
||||
Beginning in macOS 10.14.5, the software [must be notarized to run](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution). The signing and notarization processes for the Arduino IDE are managed by our Continuous Integration (CI) workflows, implemented with GitHub Actions. On every push and pull request, the Arduino IDE is built and saved to a workflow artifact. These artifacts can be used by contributors and beta testers who don't want to set up a build system locally.
|
||||
For security reasons, signing and notarization are disabled for workflow runs for pull requests from forks of this repository. This means that macOS will block you from running those artifacts.
|
||||
|
@@ -23,13 +23,14 @@ should be considered unstable:
|
||||
|
||||
| Platform | 32 bit | 64 bit |
|
||||
| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------ |
|
||||
| Linux | | [Nightly Linux 64 bit] |
|
||||
| Linux | | [Nightly Linux AppImage 64 bit]<br />[Nightly Linux ZIP file 64 bit] |
|
||||
| Linux ARM | [🚧 Work in progress...] | [🚧 Work in progress...] |
|
||||
| Windows | | [Nightly Windows 64 bit installer]<br />[Nightly Windows 64 bit MSI]<br />[Nightly Windows 64 bit ZIP] |
|
||||
| macOS | | [Nightly macOS 64 bit] |
|
||||
|
||||
[🚧 work in progress...]: https://github.com/arduino/arduino-ide/issues/107
|
||||
[nightly linux 64 bit]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Linux_64bit.zip
|
||||
[nightly linux appimage 64 bit]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Linux_64bit.AppImage
|
||||
[nightly linux zip file 64 bit]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Linux_64bit.zip
|
||||
[nightly windows 64 bit installer]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Windows_64bit.exe
|
||||
[nightly windows 64 bit msi]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Windows_64bit.msi
|
||||
[nightly windows 64 bit zip]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Windows_64bit.zip
|
||||
|
@@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "arduino-ide-extension",
|
||||
"version": "2.0.0-rc3",
|
||||
"version": "2.0.0-rc6",
|
||||
"description": "An extension for Theia building the Arduino IDE",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"scripts": {
|
||||
"prepare": "yarn download-cli && yarn download-fwuploader && yarn download-ls && yarn copy-serial-plotter && yarn clean && yarn download-examples && yarn build && yarn test",
|
||||
"prepare": "yarn download-cli && yarn download-fwuploader && yarn download-ls && yarn copy-serial-plotter && yarn copy-i18n && yarn clean && yarn download-examples && yarn build && yarn test",
|
||||
"clean": "rimraf lib",
|
||||
"compose-changelog": "node ./scripts/compose-changelog.js",
|
||||
"download-cli": "node ./scripts/download-cli.js",
|
||||
"download-fwuploader": "node ./scripts/download-fwuploader.js",
|
||||
"copy-serial-plotter": "npx ncp ../node_modules/arduino-serial-plotter-webapp ./build/arduino-serial-plotter-webapp",
|
||||
"copy-i18n": "npx ncp ../i18n ./build/i18n",
|
||||
"download-ls": "node ./scripts/download-ls.js",
|
||||
"download-examples": "node ./scripts/download-examples.js",
|
||||
"generate-protocol": "node ./scripts/generate-protocol.js",
|
||||
@@ -21,22 +22,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 +66,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 +84,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 +157,7 @@
|
||||
],
|
||||
"arduino": {
|
||||
"cli": {
|
||||
"version": "0.20.2"
|
||||
"version": "0.21.0"
|
||||
},
|
||||
"fwuploader": {
|
||||
"version": "2.0.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,
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
FrontendApplication,
|
||||
FrontendApplicationContribution,
|
||||
LocalStorageService,
|
||||
SaveableWidget,
|
||||
StatusBar,
|
||||
StatusBarAlignment,
|
||||
} from '@theia/core/lib/browser';
|
||||
@@ -38,13 +39,14 @@ import {
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import {
|
||||
EditorCommands,
|
||||
EditorMainMenu,
|
||||
EditorManager,
|
||||
EditorOpenerOptions,
|
||||
} from '@theia/editor/lib/browser';
|
||||
import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution';
|
||||
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
|
||||
import { FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
|
||||
import { FileNavigatorCommands, FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
|
||||
import { OutlineViewContribution } from '@theia/outline-view/lib/browser/outline-view-contribution';
|
||||
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
|
||||
import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution';
|
||||
@@ -68,8 +70,12 @@ 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';
|
||||
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
|
||||
|
||||
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
|
||||
export const SKIP_IDE_VERSION = 'skipIDEVersion';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoFrontendContribution
|
||||
@@ -78,8 +84,7 @@ export class ArduinoFrontendContribution
|
||||
TabBarToolbarContribution,
|
||||
CommandContribution,
|
||||
MenuContribution,
|
||||
ColorContribution
|
||||
{
|
||||
ColorContribution {
|
||||
@inject(ILogger)
|
||||
protected logger: ILogger;
|
||||
|
||||
@@ -157,6 +162,15 @@ export class ArduinoFrontendContribution
|
||||
@inject(LocalStorageService)
|
||||
protected readonly localStorageService: LocalStorageService;
|
||||
|
||||
@inject(FileSystemFrontendContribution)
|
||||
protected readonly fileSystemFrontendContribution: FileSystemFrontendContribution;
|
||||
|
||||
@inject(IDEUpdater)
|
||||
protected readonly updater: IDEUpdater;
|
||||
|
||||
@inject(IDEUpdaterDialog)
|
||||
protected readonly updaterDialog: IDEUpdaterDialog;
|
||||
|
||||
protected invalidConfigPopup:
|
||||
| Promise<void | 'No' | 'Yes' | undefined>
|
||||
| undefined;
|
||||
@@ -251,7 +265,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 +280,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 +315,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,17 +341,19 @@ 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');
|
||||
|
||||
this.fileSystemFrontendContribution.onDidChangeEditorFile(e => {
|
||||
if (e.type === FileChangeType.DELETED) {
|
||||
const editorWidget = e.editor;
|
||||
if (SaveableWidget.is(editorWidget)) {
|
||||
editorWidget.closeWithoutSaving();
|
||||
} else {
|
||||
editorWidget.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
app.shell.leftPanelHandler.removeBottomMenu('settings-menu');
|
||||
}
|
||||
|
||||
onStop(): void {
|
||||
@@ -431,6 +486,18 @@ export class ArduinoFrontendContribution
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
for (const command of [
|
||||
EditorCommands.SPLIT_EDITOR_DOWN,
|
||||
EditorCommands.SPLIT_EDITOR_LEFT,
|
||||
EditorCommands.SPLIT_EDITOR_RIGHT,
|
||||
EditorCommands.SPLIT_EDITOR_UP,
|
||||
EditorCommands.SPLIT_EDITOR_VERTICAL,
|
||||
EditorCommands.SPLIT_EDITOR_HORIZONTAL,
|
||||
FileNavigatorCommands.REVEAL_IN_NAVIGATOR
|
||||
]) {
|
||||
registry.unregisterCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry) {
|
||||
|
@@ -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';
|
||||
@@ -39,10 +39,6 @@ export class AddZipLibrary extends SketchContribution {
|
||||
...ArduinoMenus.SKETCH__UTILS_GROUP,
|
||||
'0_include',
|
||||
];
|
||||
// TODO: do we need it? calling `registerSubmenu` multiple times is noop, so it does not hurt.
|
||||
registry.registerSubmenu(includeLibMenuPath, 'Include Library', {
|
||||
order: '1',
|
||||
});
|
||||
registry.registerMenuAction([...includeLibMenuPath, '1_install'], {
|
||||
commandId: AddZipLibrary.Commands.ADD_ZIP_LIBRARY.id,
|
||||
label: nls.localize('arduino/library/addZip', 'Add .ZIP Library...'),
|
||||
|
@@ -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';
|
||||
|
@@ -43,10 +43,10 @@ export class EditContributions extends Contribution {
|
||||
execute: () => this.run('actions.find'),
|
||||
});
|
||||
registry.registerCommand(EditContributions.Commands.FIND_NEXT, {
|
||||
execute: () => this.run('actions.findWithSelection'),
|
||||
execute: () => this.run('editor.action.nextMatchFindAction'),
|
||||
});
|
||||
registry.registerCommand(EditContributions.Commands.FIND_PREVIOUS, {
|
||||
execute: () => this.run('editor.action.nextMatchFindAction'),
|
||||
execute: () => this.run('editor.action.previousMatchFindAction'),
|
||||
});
|
||||
registry.registerCommand(EditContributions.Commands.USE_FOR_FIND, {
|
||||
execute: () => this.run('editor.action.previousSelectionMatchFindAction'),
|
||||
|
@@ -13,6 +13,8 @@ import {
|
||||
KeybindingRegistry,
|
||||
} from './contribution';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { IDEUpdaterCommands } from '../ide-updater/ide-updater-commands';
|
||||
import { ElectronCommands } from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
||||
|
||||
@injectable()
|
||||
export class Help extends Contribution {
|
||||
@@ -83,9 +85,17 @@ export class Help extends Contribution {
|
||||
Help.Commands.VISIT_ARDUINO,
|
||||
createOpenHandler('https://www.arduino.cc/')
|
||||
);
|
||||
registry.registerCommand(
|
||||
Help.Commands.PRIVACY_POLICY,
|
||||
createOpenHandler('https://www.arduino.cc/en/privacy-policy')
|
||||
);
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
registry.unregisterMenuAction({
|
||||
commandId: ElectronCommands.TOGGLE_DEVELOPER_TOOLS.id,
|
||||
});
|
||||
|
||||
registry.registerMenuAction(ArduinoMenus.HELP__MAIN_GROUP, {
|
||||
commandId: Help.Commands.GETTING_STARTED.id,
|
||||
order: '0',
|
||||
@@ -115,6 +125,14 @@ export class Help extends Contribution {
|
||||
commandId: Help.Commands.VISIT_ARDUINO.id,
|
||||
order: '6',
|
||||
});
|
||||
registry.registerMenuAction(ArduinoMenus.HELP__FIND_GROUP, {
|
||||
commandId: Help.Commands.PRIVACY_POLICY.id,
|
||||
order: '7',
|
||||
});
|
||||
registry.registerMenuAction(ArduinoMenus.HELP__FIND_GROUP, {
|
||||
commandId: IDEUpdaterCommands.CHECK_FOR_UPDATES.id,
|
||||
order: '8',
|
||||
});
|
||||
}
|
||||
|
||||
registerKeybindings(registry: KeybindingRegistry): void {
|
||||
@@ -162,5 +180,10 @@ export namespace Help {
|
||||
label: nls.localize('arduino/help/visit', 'Visit Arduino.cc'),
|
||||
category: 'Arduino',
|
||||
};
|
||||
export const PRIVACY_POLICY: Command = {
|
||||
id: 'arduino-privacy-policy',
|
||||
label: nls.localize('arduino/help/privacyPolicy', 'Privacy Policy'),
|
||||
category: 'Arduino',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -100,14 +100,29 @@ export class CreateApi {
|
||||
return result;
|
||||
}
|
||||
|
||||
async sketches(): Promise<Create.Sketch[]> {
|
||||
async sketches(limit = 50): Promise<Create.Sketch[]> {
|
||||
const url = new URL(`${this.domain()}/sketches`);
|
||||
url.searchParams.set('user_id', 'me');
|
||||
url.searchParams.set('limit', limit.toString());
|
||||
const headers = await this.headers();
|
||||
const result = await this.run<{ sketches: Create.Sketch[] }>(url, {
|
||||
method: 'GET',
|
||||
headers,
|
||||
});
|
||||
const result: { sketches: Create.Sketch[] } = { sketches: [] };
|
||||
|
||||
let partialSketches: Create.Sketch[] = [];
|
||||
let currentOffset = 0;
|
||||
do {
|
||||
url.searchParams.set('offset', currentOffset.toString());
|
||||
partialSketches = (
|
||||
await this.run<{ sketches: Create.Sketch[] }>(url, {
|
||||
method: 'GET',
|
||||
headers,
|
||||
})
|
||||
).sketches;
|
||||
if (partialSketches.length != 0) {
|
||||
result.sketches = result.sketches.concat(partialSketches);
|
||||
}
|
||||
currentOffset = currentOffset + limit;
|
||||
} while (partialSketches.length != 0);
|
||||
|
||||
result.sketches.forEach((sketch) => this.sketchCache.addSketch(sketch));
|
||||
return result.sketches;
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -9,6 +9,7 @@ import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
import { FileDialogService } from '@theia/filesystem/lib/browser/file-dialog/file-dialog-service';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import {
|
||||
AdditionalUrls,
|
||||
CompilerWarningLiterals,
|
||||
Network,
|
||||
ProxySettings,
|
||||
@@ -35,21 +36,32 @@ export class SettingsComponent extends React.Component<
|
||||
if (
|
||||
this.state &&
|
||||
prevState &&
|
||||
JSON.stringify(this.state) !== JSON.stringify(prevState)
|
||||
JSON.stringify(SettingsComponent.State.toSettings(this.state)) !==
|
||||
JSON.stringify(SettingsComponent.State.toSettings(prevState))
|
||||
) {
|
||||
this.props.settingsService.update(this.state, true);
|
||||
this.props.settingsService.update(
|
||||
SettingsComponent.State.toSettings(this.state),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.props.settingsService
|
||||
.settings()
|
||||
.then((settings) => this.setState(settings));
|
||||
this.toDispose.push(
|
||||
.then((settings) =>
|
||||
this.setState(SettingsComponent.State.fromSettings(settings))
|
||||
);
|
||||
this.toDispose.pushAll([
|
||||
this.props.settingsService.onDidChange((settings) =>
|
||||
this.setState(settings)
|
||||
)
|
||||
);
|
||||
this.setState((prevState) => ({
|
||||
...SettingsComponent.State.merge(prevState, settings),
|
||||
}))
|
||||
),
|
||||
this.props.settingsService.onDidReset((settings) =>
|
||||
this.setState(SettingsComponent.State.fromSettings(settings))
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
@@ -260,18 +272,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"
|
||||
@@ -302,8 +302,8 @@ export class SettingsComponent extends React.Component<
|
||||
<input
|
||||
className="theia-input stretch with-margin"
|
||||
type="text"
|
||||
value={this.state.additionalUrls.join(',')}
|
||||
onChange={this.additionalUrlsDidChange}
|
||||
value={this.state.rawAdditionalUrlsValue}
|
||||
onChange={this.rawAdditionalUrlsValueDidChange}
|
||||
/>
|
||||
<i
|
||||
className="fa fa-window-restore theia-button shrink"
|
||||
@@ -444,7 +444,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 +456,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected numbersOnlyKeyDown = (
|
||||
event: React.KeyboardEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.isControlKey(event)) {
|
||||
return;
|
||||
}
|
||||
@@ -466,7 +468,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,42 +485,44 @@ export class SettingsComponent extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
protected editAdditionalUrlDidClick = async () => {
|
||||
protected editAdditionalUrlDidClick = async (): Promise<void> => {
|
||||
const additionalUrls = await new AdditionalUrlsDialog(
|
||||
this.state.additionalUrls,
|
||||
AdditionalUrls.parse(this.state.rawAdditionalUrlsValue, ','),
|
||||
this.props.windowService
|
||||
).open();
|
||||
if (additionalUrls) {
|
||||
this.setState({ additionalUrls });
|
||||
this.setState({
|
||||
rawAdditionalUrlsValue: AdditionalUrls.stringify(additionalUrls),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
protected editorFontSizeDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
const { value } = event.target;
|
||||
if (value) {
|
||||
this.setState({ editorFontSize: parseInt(value, 10) });
|
||||
}
|
||||
};
|
||||
|
||||
protected additionalUrlsDidChange = (
|
||||
protected rawAdditionalUrlsValueDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({
|
||||
additionalUrls: event.target.value.split(',').map((url) => url.trim()),
|
||||
rawAdditionalUrlsValue: event.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
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 +536,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 +568,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 +580,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 +597,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 +628,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 +638,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 +648,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 +658,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 +666,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 +678,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 +688,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;
|
||||
@@ -709,5 +713,48 @@ export namespace SettingsComponent {
|
||||
readonly windowService: WindowService;
|
||||
readonly localizationProvider: AsyncLocalizationProvider;
|
||||
}
|
||||
export type State = Settings & { languages: string[] };
|
||||
export type State = Settings & {
|
||||
rawAdditionalUrlsValue: string;
|
||||
};
|
||||
export namespace State {
|
||||
export function fromSettings(settings: Settings): State {
|
||||
return {
|
||||
...settings,
|
||||
rawAdditionalUrlsValue: AdditionalUrls.stringify(
|
||||
settings.additionalUrls
|
||||
),
|
||||
};
|
||||
}
|
||||
export function toSettings(state: State): Settings {
|
||||
const parsedAdditionalUrls = AdditionalUrls.parse(
|
||||
state.rawAdditionalUrlsValue,
|
||||
','
|
||||
);
|
||||
return {
|
||||
...state,
|
||||
additionalUrls: AdditionalUrls.sameAs(
|
||||
state.additionalUrls,
|
||||
parsedAdditionalUrls
|
||||
)
|
||||
? state.additionalUrls
|
||||
: parsedAdditionalUrls,
|
||||
};
|
||||
}
|
||||
export function merge(prevState: State, settings: Settings): State {
|
||||
const prevAdditionalUrls = AdditionalUrls.parse(
|
||||
prevState.rawAdditionalUrlsValue,
|
||||
','
|
||||
);
|
||||
return {
|
||||
...settings,
|
||||
rawAdditionalUrlsValue: prevState.rawAdditionalUrlsValue,
|
||||
additionalUrls: AdditionalUrls.sameAs(
|
||||
prevAdditionalUrls,
|
||||
settings.additionalUrls
|
||||
)
|
||||
? prevAdditionalUrls
|
||||
: settings.additionalUrls,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ import { FileDialogService } from '@theia/filesystem/lib/browser/file-dialog/fil
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { SettingsComponent } from './settings-component';
|
||||
import { AsyncLocalizationProvider } from '@theia/core/lib/common/i18n/localization';
|
||||
import { AdditionalUrls } from '../../../common/protocol';
|
||||
|
||||
@injectable()
|
||||
export class SettingsWidget extends ReactWidget {
|
||||
@@ -96,7 +97,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
||||
this.update();
|
||||
}
|
||||
|
||||
protected onUpdateRequest(msg: Message) {
|
||||
protected onUpdateRequest(msg: Message): void {
|
||||
super.onUpdateRequest(msg);
|
||||
this.widget.update();
|
||||
}
|
||||
@@ -105,7 +106,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
||||
super.onActivateRequest(msg);
|
||||
|
||||
// calling settingsService.reset() in order to reload the settings from the preferenceService
|
||||
// and update the UI including changes triggerd from the command palette
|
||||
// and update the UI including changes triggered from the command palette
|
||||
this.settingsService.reset();
|
||||
|
||||
this.widget.activate();
|
||||
@@ -168,10 +169,7 @@ export class AdditionalUrlsDialog extends AbstractDialog<string[]> {
|
||||
}
|
||||
|
||||
get value(): string[] {
|
||||
return this.textArea.value
|
||||
.split('\n')
|
||||
.map((url) => url.trim())
|
||||
.filter((url) => !!url);
|
||||
return AdditionalUrls.parse(this.textArea.value, 'newline');
|
||||
}
|
||||
|
||||
protected onAfterAttach(message: Message): void {
|
||||
|
@@ -1,43 +1,42 @@
|
||||
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';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import { PreferenceService, PreferenceScope } from '@theia/core/lib/browser';
|
||||
import { Index } from '../../../common/types';
|
||||
import {
|
||||
AdditionalUrls,
|
||||
CompilerWarnings,
|
||||
ConfigService,
|
||||
FileSystemExt,
|
||||
Network,
|
||||
} from '../../../common/protocol';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { CommandService, nls } from '@theia/core/lib/common';
|
||||
import { AsyncLocalizationProvider } from '@theia/core/lib/common/i18n/localization';
|
||||
import { ElectronCommands } from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
||||
|
||||
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 {
|
||||
export interface Settings {
|
||||
editorFontSize: number; // `editor.fontSize`
|
||||
themeId: string; // `workbench.colorTheme`
|
||||
autoSave: 'on' | 'off'; // `editor.autoSave`
|
||||
@@ -48,7 +47,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`
|
||||
@@ -56,7 +54,7 @@ export interface Settings extends Index {
|
||||
sketchbookShowAllFiles: boolean; // `arduino.sketchbook.showAllFiles`
|
||||
|
||||
sketchbookPath: string; // CLI
|
||||
additionalUrls: string[]; // CLI
|
||||
additionalUrls: AdditionalUrls; // CLI
|
||||
network: Network; // CLI
|
||||
}
|
||||
export namespace Settings {
|
||||
@@ -85,15 +83,19 @@ export class SettingsService {
|
||||
@inject(AsyncLocalizationProvider)
|
||||
protected readonly localizationProvider: AsyncLocalizationProvider;
|
||||
|
||||
@inject(CommandService)
|
||||
protected commandService: CommandService;
|
||||
|
||||
protected readonly onDidChangeEmitter = new Emitter<Readonly<Settings>>();
|
||||
readonly onDidChange = this.onDidChangeEmitter.event;
|
||||
protected readonly onDidResetEmitter = new Emitter<Readonly<Settings>>();
|
||||
readonly onDidReset = this.onDidResetEmitter.event;
|
||||
|
||||
protected ready = new Deferred<void>();
|
||||
protected _settings: Settings;
|
||||
|
||||
@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 +112,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -135,7 +136,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 +154,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -174,7 +173,10 @@ export class SettingsService {
|
||||
async update(settings: Settings, fireDidChange = false): Promise<void> {
|
||||
await this.ready.promise;
|
||||
for (const key of Object.keys(settings)) {
|
||||
this._settings[key] = settings[key];
|
||||
if (key in this._settings) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(this._settings as any)[key] = (settings as any)[key];
|
||||
}
|
||||
}
|
||||
if (fireDidChange) {
|
||||
this.onDidChangeEmitter.fire(this._settings);
|
||||
@@ -183,7 +185,8 @@ export class SettingsService {
|
||||
|
||||
async reset(): Promise<void> {
|
||||
const settings = await this.loadSettings();
|
||||
return this.update(settings, true);
|
||||
await this.update(settings, false);
|
||||
this.onDidResetEmitter.fire(this._settings);
|
||||
}
|
||||
|
||||
async validate(
|
||||
@@ -224,6 +227,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 +242,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -253,71 +260,33 @@ 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);
|
||||
window.location.reload();
|
||||
// Only reload if the language differs from the current locale. `nls.locale === undefined` signals english as well
|
||||
if (
|
||||
currentLanguage !== (await this.localizationProvider.getCurrentLanguage())
|
||||
) {
|
||||
await this.localizationProvider.setCurrentLanguage(currentLanguage);
|
||||
if (currentLanguage === 'en') {
|
||||
window.localStorage.removeItem(nls.localeId);
|
||||
} else {
|
||||
window.localStorage.setItem(nls.localeId, currentLanguage);
|
||||
}
|
||||
this.commandService.executeCommand(ElectronCommands.RELOAD.id);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -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',
|
||||
};
|
||||
}
|
@@ -115,8 +115,10 @@ const _Row = ({
|
||||
return (
|
||||
(data.lines[index].lineLen && (
|
||||
<div style={style}>
|
||||
{timestamp}
|
||||
{data.lines[index].message}
|
||||
<pre>
|
||||
{timestamp}
|
||||
{data.lines[index].message}
|
||||
</pre>
|
||||
</div>
|
||||
)) ||
|
||||
null
|
||||
|
@@ -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;
|
||||
}
|
@@ -57,3 +57,7 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.p-Widget.dialogOverlay .dialogBlock .dialogContent.additional-urls-dialog {
|
||||
display: block;
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import {
|
||||
} from '@theia/core/lib/browser/connection-status-service';
|
||||
import {
|
||||
ApplicationShell as TheiaApplicationShell,
|
||||
DockPanel,
|
||||
Panel,
|
||||
Widget,
|
||||
} from '@theia/core/lib/browser';
|
||||
@@ -16,6 +17,7 @@ import { Sketch } from '../../../common/protocol';
|
||||
import { SaveAsSketch } from '../../contributions/save-as-sketch';
|
||||
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
|
||||
@injectable()
|
||||
export class ApplicationShell extends TheiaApplicationShell {
|
||||
@@ -40,6 +42,9 @@ export class ApplicationShell extends TheiaApplicationShell {
|
||||
// Make the editor un-closeable asynchronously.
|
||||
this.sketchesServiceClient.currentSketch().then((sketch) => {
|
||||
if (sketch) {
|
||||
if (!this.isSketchFile(widget.editor.uri, sketch.uri)) {
|
||||
return;
|
||||
}
|
||||
if (Sketch.isInSketch(widget.editor.uri, sketch)) {
|
||||
widget.title.closable = false;
|
||||
}
|
||||
@@ -48,6 +53,14 @@ export class ApplicationShell extends TheiaApplicationShell {
|
||||
}
|
||||
}
|
||||
|
||||
private isSketchFile(uri: URI, sketchUriString: string): boolean {
|
||||
const sketchUri = new URI(sketchUriString);
|
||||
if (uri.parent.isEqual(sketchUri)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async addWidget(
|
||||
widget: Widget,
|
||||
options: Readonly<TheiaApplicationShell.WidgetOptions> = {}
|
||||
@@ -74,6 +87,11 @@ export class ApplicationShell extends TheiaApplicationShell {
|
||||
return super.addWidget(widget, { ...options, ref });
|
||||
}
|
||||
|
||||
handleEvent(): boolean {
|
||||
// NOOP, dragging has been disabled
|
||||
return false
|
||||
}
|
||||
|
||||
// Avoid hiding top panel as we use it for arduino toolbar
|
||||
protected createTopPanel(): Panel {
|
||||
const topPanel = super.createTopPanel();
|
||||
@@ -101,3 +119,16 @@ export class ApplicationShell extends TheiaApplicationShell {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const originalHandleEvent = DockPanel.prototype.handleEvent;
|
||||
|
||||
DockPanel.prototype.handleEvent = function (event) {
|
||||
switch (event.type) {
|
||||
case 'p-dragenter':
|
||||
case 'p-dragleave':
|
||||
case 'p-dragover':
|
||||
case 'p-drop':
|
||||
return;
|
||||
}
|
||||
originalHandleEvent(event);
|
||||
};
|
||||
|
@@ -11,7 +11,15 @@ export class CommonFrontendContribution extends TheiaCommonFrontendContribution
|
||||
registerCommands(commandRegistry: CommandRegistry): void {
|
||||
super.registerCommands(commandRegistry);
|
||||
|
||||
for (const command of [CommonCommands.CONFIGURE_DISPLAY_LANGUAGE]) {
|
||||
for (const command of [
|
||||
CommonCommands.CONFIGURE_DISPLAY_LANGUAGE,
|
||||
CommonCommands.CLOSE_TAB,
|
||||
CommonCommands.CLOSE_SAVED_TABS,
|
||||
CommonCommands.CLOSE_OTHER_TABS,
|
||||
CommonCommands.CLOSE_ALL_TABS,
|
||||
CommonCommands.COLLAPSE_PANEL,
|
||||
CommonCommands.TOGGLE_MAXIMIZED,
|
||||
]) {
|
||||
commandRegistry.unregisterCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -32,10 +40,6 @@ export class CommonFrontendContribution extends TheiaCommonFrontendContribution
|
||||
CommonCommands.SELECT_ICON_THEME,
|
||||
CommonCommands.SELECT_COLOR_THEME,
|
||||
CommonCommands.ABOUT_COMMAND,
|
||||
CommonCommands.CLOSE_TAB,
|
||||
CommonCommands.CLOSE_OTHER_TABS,
|
||||
CommonCommands.CLOSE_ALL_TABS,
|
||||
CommonCommands.COLLAPSE_PANEL,
|
||||
CommonCommands.SAVE_WITHOUT_FORMATTING, // Patched for https://github.com/eclipse-theia/theia/pull/8877
|
||||
]) {
|
||||
registry.unregisterMenuAction(command);
|
||||
|
@@ -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 {
|
||||
|
2
arduino-ide-extension/src/browser/utils/constants.ts
Normal file
2
arduino-ide-extension/src/browser/utils/constants.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const REMOTE_SKETCHBOOK_FOLDER = 'RemoteSketchbook';
|
||||
export const ARDUINO_CLOUD_FOLDER = 'ArduinoCloud';
|
@@ -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()
|
||||
);
|
||||
|
||||
|
@@ -116,7 +116,7 @@ export interface Config {
|
||||
readonly sketchDirUri: string;
|
||||
readonly dataDirUri: string;
|
||||
readonly downloadsDirUri: string;
|
||||
readonly additionalUrls: string[];
|
||||
readonly additionalUrls: AdditionalUrls;
|
||||
readonly network: Network;
|
||||
readonly daemon: Daemon;
|
||||
}
|
||||
@@ -141,3 +141,32 @@ export namespace Config {
|
||||
);
|
||||
}
|
||||
}
|
||||
export type AdditionalUrls = string[];
|
||||
export namespace AdditionalUrls {
|
||||
export function parse(value: string, delimiter: ',' | 'newline'): string[] {
|
||||
return value
|
||||
.trim()
|
||||
.split(delimiter === ',' ? delimiter : /\r?\n/)
|
||||
.map((url) => url.trim())
|
||||
.filter((url) => !!url);
|
||||
}
|
||||
export function stringify(additionalUrls: AdditionalUrls): string {
|
||||
return additionalUrls.join(',');
|
||||
}
|
||||
export function sameAs(left: AdditionalUrls, right: AdditionalUrls): boolean {
|
||||
if (left.length !== right.length) {
|
||||
return false;
|
||||
}
|
||||
const localeCompare = (left: string, right: string) =>
|
||||
left.localeCompare(right);
|
||||
const normalize = (url: string) => url.toLowerCase();
|
||||
const normalizedLeft = left.map(normalize).sort(localeCompare);
|
||||
const normalizedRight = right.map(normalize).sort(localeCompare);
|
||||
for (let i = 0; i < normalizedLeft.length; i++) {
|
||||
if (normalizedLeft[i] !== normalizedRight[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
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;
|
||||
}
|
@@ -11,12 +11,13 @@ import { FrontendApplicationContribution } from '@theia/core/lib/browser/fronten
|
||||
import { Sketch, SketchesService } from '../../common/protocol';
|
||||
import { ConfigService } from './config-service';
|
||||
import { SketchContainer } from './sketches-service';
|
||||
import {
|
||||
ARDUINO_CLOUD_FOLDER,
|
||||
REMOTE_SKETCHBOOK_FOLDER,
|
||||
} from '../../browser/utils/constants';
|
||||
|
||||
const READ_ONLY_FILES = [
|
||||
'thingProperties.h',
|
||||
'thingsProperties.h',
|
||||
'sketch.json',
|
||||
];
|
||||
const READ_ONLY_FILES = ['sketch.json'];
|
||||
const READ_ONLY_FILES_REMOTE = ['thingProperties.h', 'thingsProperties.h'];
|
||||
|
||||
@injectable()
|
||||
export class SketchesServiceClientImpl
|
||||
@@ -178,7 +179,17 @@ export class SketchesServiceClientImpl
|
||||
if (toCheck.scheme === 'user-storage') {
|
||||
return false;
|
||||
}
|
||||
if (READ_ONLY_FILES.includes(toCheck?.path?.base)) {
|
||||
|
||||
const isCloudSketch = toCheck
|
||||
.toString()
|
||||
.includes(`${REMOTE_SKETCHBOOK_FOLDER}/${ARDUINO_CLOUD_FOLDER}`);
|
||||
|
||||
const filesToCheck = [
|
||||
...READ_ONLY_FILES,
|
||||
...(isCloudSketch ? READ_ONLY_FILES_REMOTE : []),
|
||||
];
|
||||
|
||||
if (filesToCheck.includes(toCheck?.path?.base)) {
|
||||
return true;
|
||||
}
|
||||
const readOnly = !this.workspaceService
|
||||
|
@@ -1,7 +1,3 @@
|
||||
export type RecursiveRequired<T> = {
|
||||
[P in keyof T]-?: RecursiveRequired<T[P]>;
|
||||
};
|
||||
|
||||
export interface Index {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
@@ -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,129 @@
|
||||
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;
|
||||
const currentVersionHeader = `\n\n---\n\n## ${this.updater.currentVersion}\n\n`;
|
||||
// We only want to see the release notes of newer versions
|
||||
const currentVersionIndex = changelog?.indexOf(currentVersionHeader);
|
||||
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,45 @@
|
||||
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';
|
||||
import { RELOAD_REQUESTED_SIGNAL, Restart } from '@theia/core/lib/electron-common/messaging/electron-messages';
|
||||
|
||||
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 +49,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';
|
||||
}
|
||||
@@ -45,11 +158,21 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
app.on('second-instance', this.onSecondInstance.bind(this));
|
||||
app.on('window-all-closed', this.onWindowAllClosed.bind(this));
|
||||
|
||||
ipcMain.on('restart', ({ sender }) => {
|
||||
ipcMain.on(RELOAD_REQUESTED_SIGNAL, event => this.handleReload(event));
|
||||
|
||||
ipcMain.on(Restart, ({ sender }) => {
|
||||
this.restart(sender.id);
|
||||
});
|
||||
}
|
||||
|
||||
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 +271,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 +343,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,7 +12,6 @@ import { Event, Emitter } from '@theia/core/lib/common/event';
|
||||
import { environment } from '@theia/application-package/lib/environment';
|
||||
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
||||
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
|
||||
import { LocalizationProvider } from '@theia/core/lib/node/i18n/localization-provider';
|
||||
import { ArduinoDaemon, NotificationServiceServer } from '../common/protocol';
|
||||
import { DaemonLog } from './daemon-log';
|
||||
import { CLI_CONFIG } from './cli-config';
|
||||
@@ -32,9 +31,6 @@ export class ArduinoDaemonImpl
|
||||
@inject(NotificationServiceServer)
|
||||
protected readonly notificationService: NotificationServiceServer;
|
||||
|
||||
@inject(LocalizationProvider)
|
||||
protected readonly localizationProvider: LocalizationProvider;
|
||||
|
||||
protected readonly toDispose = new DisposableCollection();
|
||||
protected readonly onDaemonStartedEmitter = new Emitter<void>();
|
||||
protected readonly onDaemonStoppedEmitter = new Emitter<void>();
|
||||
|
@@ -92,6 +92,8 @@ import { ArduinoFirmwareUploaderImpl } from './arduino-firmware-uploader-impl';
|
||||
import { PlotterBackendContribution } from './plotter/plotter-backend-contribution';
|
||||
import WebSocketServiceImpl from './web-socket/web-socket-service-impl';
|
||||
import { WebSocketService } from './web-socket/web-socket-service';
|
||||
import { ArduinoLocalizationContribution } from './arduino-localization-contribution';
|
||||
import { LocalizationContribution } from '@theia/core/lib/node/i18n/localization-contribution';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(BackendApplication).toSelf().inSingletonScope();
|
||||
@@ -340,4 +342,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
|
||||
bind(PlotterBackendContribution).toSelf().inSingletonScope();
|
||||
bind(BackendApplicationContribution).toService(PlotterBackendContribution);
|
||||
bind(ArduinoLocalizationContribution).toSelf().inSingletonScope();
|
||||
bind(LocalizationContribution).toService(ArduinoLocalizationContribution);
|
||||
});
|
||||
|
@@ -0,0 +1,152 @@
|
||||
import {
|
||||
LocalizationContribution,
|
||||
LocalizationRegistry,
|
||||
} from '@theia/core/lib/node/i18n/localization-contribution';
|
||||
import { injectable } from 'inversify';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoLocalizationContribution
|
||||
implements LocalizationContribution
|
||||
{
|
||||
async registerLocalizations(registry: LocalizationRegistry): Promise<void> {
|
||||
registry.registerLocalizationFromRequire(
|
||||
'af',
|
||||
require('../../build/i18n/af.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'en',
|
||||
require('../../build/i18n/en.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'fr',
|
||||
require('../../build/i18n/fr.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'ko',
|
||||
require('../../build/i18n/ko.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'pt',
|
||||
require('../../build/i18n/pt.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'uk_UA',
|
||||
require('../../build/i18n/uk_UA.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'ar',
|
||||
require('../../build/i18n/ar.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'es',
|
||||
require('../../build/i18n/es.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'he',
|
||||
require('../../build/i18n/he.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'my_MM',
|
||||
require('../../build/i18n/my_MM.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'ro',
|
||||
require('../../build/i18n/ro.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'zh-cn',
|
||||
require('../../build/i18n/zh.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'bg',
|
||||
require('../../build/i18n/bg.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'eu',
|
||||
require('../../build/i18n/eu.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'hu',
|
||||
require('../../build/i18n/hu.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'ne',
|
||||
require('../../build/i18n/ne.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'ru',
|
||||
require('../../build/i18n/ru.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'zh_TW',
|
||||
require('../../build/i18n/zh_TW.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'de',
|
||||
require('../../build/i18n/de.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'fa',
|
||||
require('../../build/i18n/fa.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'it',
|
||||
require('../../build/i18n/it.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'nl',
|
||||
require('../../build/i18n/nl.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'sv_SE',
|
||||
require('../../build/i18n/sv_SE.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'el',
|
||||
require('../../build/i18n/el.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'fil',
|
||||
require('../../build/i18n/fil.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'ja',
|
||||
require('../../build/i18n/ja.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'pl',
|
||||
require('../../build/i18n/pl.json')
|
||||
);
|
||||
|
||||
registry.registerLocalizationFromRequire(
|
||||
'tr',
|
||||
require('../../build/i18n/tr.json')
|
||||
);
|
||||
}
|
||||
}
|
@@ -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}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -30,10 +30,11 @@ const WIN32_DRIVE_REGEXP = /^[a-zA-Z]:\\/;
|
||||
const prefix = '.arduinoIDE-unsaved';
|
||||
|
||||
@injectable()
|
||||
export class SketchesServiceImpl
|
||||
extends CoreClientAware
|
||||
implements SketchesService
|
||||
{
|
||||
export class SketchesServiceImpl extends CoreClientAware
|
||||
implements SketchesService {
|
||||
private sketchSuffixIndex = 1;
|
||||
private lastSketchBaseName: string;
|
||||
|
||||
@inject(ConfigService)
|
||||
protected readonly configService: ConfigService;
|
||||
|
||||
@@ -303,22 +304,31 @@ export class SketchesServiceImpl
|
||||
monthNames[today.getMonth()]
|
||||
}${today.getDate()}`;
|
||||
const config = await this.configService.getConfiguration();
|
||||
const user = FileUri.fsPath(config.sketchDirUri);
|
||||
const sketchbookPath = FileUri.fsPath(config.sketchDirUri);
|
||||
let sketchName: string | undefined;
|
||||
for (let i = 97; i < 97 + 26; i++) {
|
||||
const sketchNameCandidate = `${sketchBaseName}${String.fromCharCode(i)}`;
|
||||
// Note: we check the future destination folder (`directories.user`) for name collision and not the temp folder!
|
||||
if (await promisify(fs.exists)(path.join(user, sketchNameCandidate))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sketchName = sketchNameCandidate;
|
||||
break;
|
||||
// If it's another day, reset the count of sketches created today
|
||||
if (this.lastSketchBaseName !== sketchBaseName) this.sketchSuffixIndex = 1;
|
||||
|
||||
let nameFound = false;
|
||||
while (!nameFound) {
|
||||
const sketchNameCandidate = `${sketchBaseName}${sketchIndexToLetters(
|
||||
this.sketchSuffixIndex++
|
||||
)}`;
|
||||
// Note: we check the future destination folder (`directories.user`) for name collision and not the temp folder!
|
||||
const sketchExists = await promisify(fs.exists)(
|
||||
path.join(sketchbookPath, sketchNameCandidate)
|
||||
);
|
||||
if (!sketchExists) {
|
||||
nameFound = true;
|
||||
sketchName = sketchNameCandidate;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sketchName) {
|
||||
throw new Error('Cannot create a unique sketch name');
|
||||
}
|
||||
this.lastSketchBaseName = sketchBaseName;
|
||||
|
||||
const sketchDir = path.join(parentPath, sketchName);
|
||||
const sketchFile = path.join(sketchDir, `${sketchName}.ino`);
|
||||
@@ -507,3 +517,23 @@ interface SketchContainerWithDetails extends SketchContainer {
|
||||
readonly children: SketchContainerWithDetails[];
|
||||
readonly sketches: SketchWithDetails[];
|
||||
}
|
||||
|
||||
/*
|
||||
* When a new sketch is created, add a suffix to distinguish it
|
||||
* from other new sketches I created today.
|
||||
* If 'sketch_jul8a' is already used, go with 'sketch_jul8b'.
|
||||
* If 'sketch_jul8b' already used, go with 'sketch_jul8c'.
|
||||
* When it reacheas 'sketch_jul8z', go with 'sketch_jul8aa',
|
||||
* and so on.
|
||||
*/
|
||||
function sketchIndexToLetters(num: number): string {
|
||||
let out = '';
|
||||
let pow;
|
||||
do {
|
||||
pow = Math.floor(num / 26);
|
||||
const mod = num % 26;
|
||||
out = (mod ? String.fromCharCode(96 + mod) : (--pow, 'z')) + out;
|
||||
num = pow;
|
||||
} while (pow > 0);
|
||||
return out;
|
||||
}
|
||||
|
35
arduino-ide-extension/src/test/common/config-service.test.ts
Normal file
35
arduino-ide-extension/src/test/common/config-service.test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { expect } from 'chai';
|
||||
import { AdditionalUrls } from '../../common/protocol';
|
||||
|
||||
describe('config-service', () => {
|
||||
describe('additionalUrls', () => {
|
||||
it('should consider additional URLs same as if they differ in case', () => {
|
||||
expect(AdditionalUrls.sameAs(['aaaa'], ['AAAA'])).to.be.true;
|
||||
});
|
||||
it('should consider additional URLs same as if they have a different order', () => {
|
||||
expect(AdditionalUrls.sameAs(['bbbb', 'aaaa'], ['aaaa', 'bbbb'])).to.be
|
||||
.true;
|
||||
});
|
||||
it('should parse an empty string as an empty array', () => {
|
||||
expect(AdditionalUrls.parse('', ',')).to.be.empty;
|
||||
});
|
||||
it('should parse a blank string as an empty array', () => {
|
||||
expect(AdditionalUrls.parse(' ', ',')).to.be.empty;
|
||||
});
|
||||
it('should parse urls with commas', () => {
|
||||
expect(AdditionalUrls.parse(' ,a , b , c, ', ',')).to.be.deep.equal([
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
]);
|
||||
});
|
||||
it("should parse urls with both '\\n' and '\\r\\n' line endings", () => {
|
||||
expect(
|
||||
AdditionalUrls.parse(
|
||||
'a ' + '\r\n' + ' b ' + '\n' + ' c ' + '\r\n' + ' ' + '\n' + '',
|
||||
'newline'
|
||||
)
|
||||
).to.be.deep.equal(['a', 'b', 'c']);
|
||||
});
|
||||
});
|
||||
});
|
@@ -1,29 +1,29 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "browser-app",
|
||||
"version": "2.0.0-rc3",
|
||||
"version": "2.0.0-rc6",
|
||||
"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-rc6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0"
|
||||
"@theia/cli": "1.22.1"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "theia build --mode development",
|
||||
|
@@ -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-rc6",
|
||||
"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-rc6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0"
|
||||
"@theia/cli": "1.22.1",
|
||||
"electron": "^15.3.5"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "theia build --mode development",
|
||||
|
@@ -1,5 +1,3 @@
|
||||
Terms of Service
|
||||
|
||||
By downloading the software from this page, you agree to the specified terms.
|
||||
|
||||
The Arduino software is provided to you "as is" and we make no express or implied warranties whatsoever with respect to its functionality, operability, or use, including, without limitation, any implied warranties of merchantability, fitness for a particular purpose, or infringement. We expressly disclaim any liability whatsoever for any direct, indirect, consequential, incidental or special damages, including, without limitation, lost revenues, lost profits, losses resulting from business interruption or loss of data, regardless of the form of action or legal theory under which the liability may be asserted, even if advised of the possibility or likelihood of such damages.
|
||||
|
@@ -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,30 +3,32 @@
|
||||
"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"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn download:plugins && theia build --mode development && yarn patch",
|
||||
"build:publish": "yarn download:plugins && theia build --mode production && yarn patch",
|
||||
"build": "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 +53,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 +76,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,20 +96,19 @@
|
||||
"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"
|
||||
},
|
||||
"msi": {
|
||||
"runAfterFinish": false
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": false,
|
||||
"installerHeaderIcon": "resources/icon.ico",
|
||||
@@ -139,9 +148,15 @@
|
||||
"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"
|
||||
"cortex-debug": "https://open-vsx.org/api/marus25/cortex-debug/0.3.10/file/marus25.cortex-debug-0.3.10.vsix",
|
||||
"vscode-language-pack-nl": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-nl/1.48.3/file/MS-CEINTL.vscode-language-pack-nl-1.48.3.vsix",
|
||||
"vscode-language-pack-fr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-fr/1.53.2/file/MS-CEINTL.vscode-language-pack-fr-1.53.2.vsix",
|
||||
"vscode-language-pack-zh-hans": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-zh-hans/1.53.2/file/MS-CEINTL.vscode-language-pack-zh-hans-1.53.2.vsix",
|
||||
"vscode-language-pack-de": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-de/1.53.2/file/MS-CEINTL.vscode-language-pack-de-1.53.2.vsix",
|
||||
"vscode-language-pack-ja":"https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-ja/1.53.2/file/MS-CEINTL.vscode-language-pack-ja-1.53.2.vsix",
|
||||
"vscode-language-pack-tr": "https://open-vsx.org/api/MS-CEINTL/vscode-language-pack-tr/1.53.2/file/MS-CEINTL.vscode-language-pack-tr-1.53.2.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,502 @@
|
||||
//@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',
|
||||
'i18n'
|
||||
]) {
|
||||
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`,
|
||||
`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);
|
||||
}
|
||||
if (expectedVersion) {
|
||||
if (!versions.has(expectedVersion)) {
|
||||
echo(
|
||||
`Mismatching version configuration. Expected version was: '${expectedVersion}' actual was: '${Array.from(versions)[0]
|
||||
}'.`
|
||||
);
|
||||
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`);
|
||||
|
||||
//------------------------------------------------------------------------------+
|
||||
// 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"
|
||||
|
350
i18n/af.json
Normal file
350
i18n/af.json
Normal file
@@ -0,0 +1,350 @@
|
||||
{
|
||||
"arduino": {
|
||||
"common": {
|
||||
"offlineIndicator": "Dit lyk of jy van af lyn is. Sonder 'n internetverbinding kan die Arduino CLI moontlik nie die nodige hulpbronne aflaai nie en kan dit wanfunksionering veroorsaak. Koppel asseblief aan die internet en herbegin die toepassing.",
|
||||
"noBoardSelected": "Geen bord geselekteer",
|
||||
"selectedOn": "aan {0}",
|
||||
"notConnected": "[nie gekoppel]",
|
||||
"serialMonitor": "Seriaal Monitor",
|
||||
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
|
||||
"later": "Later",
|
||||
"selectBoard": "Kies Bord",
|
||||
"unknown": "Onbekend",
|
||||
"processing": "Verwerking",
|
||||
"saveChangesToSketch": "Wil jy veranderinge aan hierdie skets stoor voordat jy toemaak?",
|
||||
"loseChanges": "As jy nie stoor nie, sal jou veranderinge verlore gaan."
|
||||
},
|
||||
"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": "Skets",
|
||||
"tools": "Gereedskap"
|
||||
},
|
||||
"debug": {
|
||||
"optimizeForDebugging": "Geoptimaliseerd vir ontfouting",
|
||||
"debugWithMessage": "Ontfouting {0}",
|
||||
"noPlatformInstalledFor": "Platform is nie geïnstalleer vir ' {0} '",
|
||||
"debuggingNotSupported": "Debugging is not supported by '{0}'"
|
||||
},
|
||||
"preferences": {
|
||||
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.",
|
||||
"compile.verbose": "True for verbose compile output. False by default",
|
||||
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default",
|
||||
"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.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.",
|
||||
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.",
|
||||
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.",
|
||||
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.",
|
||||
"cloud.sketchSyncEnpoint": "The endpoint used to push and pull sketches from a backend. By default it points to Arduino Cloud API.",
|
||||
"auth.clientID": "The OAuth2 client ID.",
|
||||
"auth.domain": "Die OAuth2 domein.",
|
||||
"auth.audience": "Die OAuth2 gehoor.",
|
||||
"auth.registerUri": "Die URI wat gebruik word vir nuwe registrasies.",
|
||||
"network": "Netwerk",
|
||||
"sketchbook.location": "Sketsboek ligging",
|
||||
"browse": "Snuffel",
|
||||
"files.inside.sketches": "Toon lêers binne in Sketse aan",
|
||||
"editorFontSize": "Editor lettertipe grootte",
|
||||
"interfaceScale": "Koppelvlak skaal",
|
||||
"showVerbose": "Wys ontfoutings uitset tydens",
|
||||
"compilerWarnings": "Compiler warnings",
|
||||
"automatic": "Automaties",
|
||||
"compile": "saamstel",
|
||||
"upload": "oplaai",
|
||||
"verifyAfterUpload": "Verifieer kode na oplaai ",
|
||||
"editorQuickSuggestions": "Editor Quick Suggestions",
|
||||
"additionalManagerURLs": "Additional Boards Manager URLs",
|
||||
"noProxy": "No proxy",
|
||||
"manualProxy": "Manual proxy configuration",
|
||||
"newSketchbookLocation": "Select new sketchbook location",
|
||||
"choose": "Kies",
|
||||
"enterAdditionalURLs": "Enter additional URLs, one for each row",
|
||||
"unofficialBoardSupport": "Click for a list of unofficial board support URLs",
|
||||
"invalid.sketchbook.location": "Invalid sketchbook location: {0}",
|
||||
"invalid.editorFontSize": "Invalid editor font size. It must be a positive integer.",
|
||||
"invalid.theme": "Invalid theme."
|
||||
},
|
||||
"cloud": {
|
||||
"signIn": "TEKEN AAN",
|
||||
"signOut": "Teken Uit",
|
||||
"chooseSketchVisibility": "Choose visibility of your Sketch:",
|
||||
"privateVisibility": "Private. Only you can view the Sketch.",
|
||||
"publicVisibility": "Public. Anyone with the link can view the Sketch.",
|
||||
"link": "Skakel:",
|
||||
"embed": "Embed:",
|
||||
"cloudSketchbook": "Wolk Skets",
|
||||
"shareSketch": "Share Sketch",
|
||||
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook",
|
||||
"pullSketch": "Pull Sketch",
|
||||
"openInCloudEditor": "Open in Cloud Editor",
|
||||
"options": "Opsies...",
|
||||
"share": "Deel...",
|
||||
"remote": "Remote",
|
||||
"emptySketchbook": "Jou Sketsboek is leeg",
|
||||
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.",
|
||||
"signInToCloud": "Sign in to Arduino Cloud",
|
||||
"syncEditSketches": "Sync and edit your Arduino Cloud Sketches",
|
||||
"learnMore": "Learn more",
|
||||
"continue": "Continue",
|
||||
"pushSketch": "Push Sketch",
|
||||
"pushSketchMsg": "This is a Public Sketch. Before pushing, make sure any sensitive information is defined in arduino_secrets.h files. You can make a Sketch private from the Share panel.",
|
||||
"pull": "Pull",
|
||||
"pullSketchMsg": "Pulling this Sketch from the Cloud will overwrite its local version. Are you sure you want to continue?",
|
||||
"donePulling": "Done pulling ‘{0}’.",
|
||||
"notYetPulled": "Cannot push to Cloud. It is not yet pulled.",
|
||||
"push": "Push",
|
||||
"pullFirst": "You have to pull first to be able to push to the Cloud.",
|
||||
"donePushing": "Done pushing ‘{0}’.",
|
||||
"connected": "Connected",
|
||||
"offline": "Aflyn",
|
||||
"profilePicture": "Profiel foto"
|
||||
},
|
||||
"board": {
|
||||
"installManually": "Install Manually",
|
||||
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
|
||||
"configDialogTitle": "Select Other Board & Port",
|
||||
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
|
||||
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
|
||||
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
|
||||
"showAllAvailablePorts": "Shows all available ports when enabled",
|
||||
"programmer": "Programeerder",
|
||||
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}",
|
||||
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}",
|
||||
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
|
||||
"reselectLater": "Herselekteer later",
|
||||
"noneSelected": "No boards selected.",
|
||||
"noPortsSelected": "No ports selected for board: '{0}'.",
|
||||
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
|
||||
"openBoardsConfig": "Kies ander bord en poort...",
|
||||
"boardListItem": "{0} by {1}",
|
||||
"selectBoardForInfo": "Please select a board to obtain board info.",
|
||||
"platformMissing": "The platform for the selected '{0}' board is not installed.",
|
||||
"selectPortForInfo": "Please select a port to obtain board info.",
|
||||
"boardInfo": "Board Info",
|
||||
"board": "Board{0}",
|
||||
"port": "Port{0}",
|
||||
"getBoardInfo": "Get Board Info",
|
||||
"inSketchbook": " (in Sketchbook)"
|
||||
},
|
||||
"boardsManager": "Boards Manager",
|
||||
"about": {
|
||||
"label": "About {0}",
|
||||
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
|
||||
},
|
||||
"contributions": {
|
||||
"addFile": "Add File",
|
||||
"replaceTitle": "Vervang",
|
||||
"fileAdded": "Een lêer by skets gevoeg"
|
||||
},
|
||||
"replaceMsg": "Replace the existing version of {0}?",
|
||||
"library": {
|
||||
"addZip": "Add .ZIP Library...",
|
||||
"zipLibrary": "Library",
|
||||
"overwriteExistingLibrary": "Do you want to overwrite the existing library?",
|
||||
"successfullyInstalledZipLibrary": "Successfully installed library from {0} archive",
|
||||
"namedLibraryAlreadyExists": "A library folder named {0} already exists. Do you want to overwrite it?",
|
||||
"libraryAlreadyExists": "A library already exists. Do you want to overwrite it?",
|
||||
"include": "Include Library",
|
||||
"manageLibraries": "Manage Libraries...",
|
||||
"arduinoLibraries": "Arduino libraries",
|
||||
"contributedLibraries": "Contributed libraries",
|
||||
"title": "Library Manager",
|
||||
"needsOneDependency": "The library <b>{0}:{1}</b> needs another dependency currently not installed:",
|
||||
"needsMultipleDependencies": "The library <b>{0}:{1}</b> needs some other dependencies currently not installed:",
|
||||
"installOneMissingDependency": "Would you like to install the missing dependency?",
|
||||
"installMissingDependencies": "Would you like to install all the missing dependencies?",
|
||||
"dependenciesForLibrary": "Dependencies for library {0}:{1}",
|
||||
"installAll": "Install all",
|
||||
"installOnly": "Install {0} only",
|
||||
"installedSuccessfully": "Successfully installed library {0}:{1}",
|
||||
"uninstalledSuccessfully": "Successfully uninstalled library {0}:{1}"
|
||||
},
|
||||
"selectZip": "Select a zip file containing the library you'd like to add",
|
||||
"sketch": {
|
||||
"archiveSketch": "Archive Sketch",
|
||||
"saveSketchAs": "Save sketch folder as...",
|
||||
"createdArchive": "Created archive '{0}'.",
|
||||
"new": "New",
|
||||
"openRecent": "Open Recent",
|
||||
"showFolder": "Show Sketch Folder",
|
||||
"sketch": "Skets",
|
||||
"moving": "Moving",
|
||||
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
|
||||
"cantOpen": "A folder named \"{0}\" already exists. Can't open sketch.",
|
||||
"saveFolderAs": "Save sketch folder as...",
|
||||
"sketchbook": "Sketchbook",
|
||||
"upload": "Upload",
|
||||
"uploadUsingProgrammer": "Upload Using Programmer",
|
||||
"userFieldsNotFoundError": "Can't find user fields for connected board",
|
||||
"doneUploading": "Done uploading.",
|
||||
"configureAndUpload": "Configure And Upload",
|
||||
"verifyOrCompile": "Verify/Compile",
|
||||
"exportBinary": "Export Compiled Binary",
|
||||
"verify": "Verify",
|
||||
"doneCompiling": "Done compiling.",
|
||||
"couldNotConnectToSerial": "Could not reconnect to serial port. {0}",
|
||||
"openSketchInNewWindow": "Open Sketch in New Window",
|
||||
"openFolder": "Open Folder",
|
||||
"titleLocalSketchbook": "Local Sketchbook",
|
||||
"titleSketchbook": "Sketchbook",
|
||||
"close": "Are you sure you want to close the sketch?"
|
||||
},
|
||||
"bootloader": {
|
||||
"burnBootloader": "Burn Bootloader",
|
||||
"doneBurningBootloader": "Done burning bootloader."
|
||||
},
|
||||
"editor": {
|
||||
"copyForForum": "Copy for Forum (Markdown)",
|
||||
"commentUncomment": "Comment/Uncomment",
|
||||
"increaseIndent": "Increase Indent",
|
||||
"decreaseIndent": "Decrease Indent",
|
||||
"increaseFontSize": "Increase Font Size",
|
||||
"decreaseFontSize": "Decrease Font Size",
|
||||
"autoFormat": "Auto Format"
|
||||
},
|
||||
"examples": {
|
||||
"menu": "Examples",
|
||||
"couldNotInitializeExamples": "Could not initialize built-in examples.",
|
||||
"builtInExamples": "Built-in examples",
|
||||
"customLibrary": "Examples from Custom Libraries",
|
||||
"for": "Examples for {0}",
|
||||
"forAny": "Examples for any board"
|
||||
},
|
||||
"help": {
|
||||
"search": "Search on Arduino.cc",
|
||||
"keyword": "Type a keyword",
|
||||
"gettingStarted": "Getting Started",
|
||||
"environment": "Environment",
|
||||
"troubleshooting": "Troubleshooting",
|
||||
"reference": "Reference",
|
||||
"findInReference": "Find in Reference",
|
||||
"faq": "Frequently Asked Questions",
|
||||
"visit": "Visit Arduino.cc",
|
||||
"privacyPolicy": "Privacy Policy"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "Upload SSL Root Certificates",
|
||||
"openContext": "Open context",
|
||||
"remove": "Remove",
|
||||
"upload": "Upload",
|
||||
"addURL": "Add URL to fetch SSL certificate",
|
||||
"enterURL": "Enter URL",
|
||||
"selectCertificateToUpload": "1. Select certificate to upload",
|
||||
"addNew": "Add New",
|
||||
"selectDestinationBoardToUpload": "2. Select destination board and upload certificate",
|
||||
"uploadingCertificates": "Uploading certificates.",
|
||||
"certificatesUploaded": "Certificates uploaded.",
|
||||
"uploadFailed": "Upload failed. Please try again.",
|
||||
"selectBoard": "Select a board...",
|
||||
"boardAtPort": "{0} by {1}",
|
||||
"noSupportedBoardConnected": "No supported board connected"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Updater",
|
||||
"selectBoard": "Kies Bord",
|
||||
"checkUpdates": "Check Updates",
|
||||
"selectVersion": "Select firmware version",
|
||||
"install": "Install",
|
||||
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
|
||||
"installingFirmware": "Installing firmware.",
|
||||
"successfullyInstalled": "Firmware successfully installed.",
|
||||
"failedInstall": "Installation failed. Please try again."
|
||||
},
|
||||
"dialog": {
|
||||
"dontAskAgain": "Don't ask again"
|
||||
},
|
||||
"userFields": {
|
||||
"cancel": "Cancel",
|
||||
"upload": "Upload"
|
||||
},
|
||||
"serial": {
|
||||
"toggleTimestamp": "Toggle Timestamp",
|
||||
"autoscroll": "Autoscroll",
|
||||
"timestamp": "Tydstempel",
|
||||
"noLineEndings": "No Line Ending",
|
||||
"newLine": "Nuwe lyn",
|
||||
"carriageReturn": "Wagterugkeer",
|
||||
"newLineCarriageReturn": "Beide NL & CR",
|
||||
"notConnected": "Not connected. Select a board and a port to connect automatically.",
|
||||
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
|
||||
"connectionBusy": "Konneksie het gevaal. Seriaal poort is besig: {0}",
|
||||
"disconnected": "Disconnected {0} from {1}.",
|
||||
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.",
|
||||
"failedReconnect": "Failed to reconnect {0} to serial port after 10 consecutive attempts. The {1} serial port is busy.",
|
||||
"reconnect": "Reconnecting {0} to {1} in {2} seconds..."
|
||||
},
|
||||
"component": {
|
||||
"uninstall": "Uninstall",
|
||||
"uninstallMsg": "Do you want to uninstall {0}?",
|
||||
"by": "by",
|
||||
"version": "Weergawe {0}",
|
||||
"moreInfo": "Meer inligting",
|
||||
"install": "INSTALLEER",
|
||||
"filterSearch": "Filter your search..."
|
||||
},
|
||||
"electron": {
|
||||
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
|
||||
"unsavedChanges": "Enige ongestoorde veranderinge sal nie gestoor word nie."
|
||||
},
|
||||
"compile": {
|
||||
"error": "Compilation error: {0}"
|
||||
},
|
||||
"upload": {
|
||||
"error": "{0} error: {1}"
|
||||
},
|
||||
"burnBootloader": {
|
||||
"error": "Error while burning the bootloader: {0}"
|
||||
}
|
||||
},
|
||||
"theia": {
|
||||
"core": {
|
||||
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
|
||||
"offline": "Aflyn",
|
||||
"daemonOffline": "CLI Daemon Offline",
|
||||
"cannotConnectBackend": "Cannot connect to the backend.",
|
||||
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
|
||||
},
|
||||
"debug": {
|
||||
"start": "Begin...",
|
||||
"typeNotSupported": "The debug session type \"{0}\" is not supported.",
|
||||
"startError": "There was an error starting the debug session, check the logs for more details."
|
||||
},
|
||||
"editor": {
|
||||
"unsavedTitle": "Unsaved – {0}"
|
||||
},
|
||||
"messages": {
|
||||
"expand": "Expand",
|
||||
"collapse": "Collapse"
|
||||
},
|
||||
"workspace": {
|
||||
"fileNewName": "Naam vir nuwe lêer",
|
||||
"invalidFilename": "Ongeldige lêernaam",
|
||||
"invalidExtension": ".{0} is not a valid extension",
|
||||
"newFileName": "Nuwe naam vir lêer",
|
||||
"deleteCurrentSketch": "Wil jy die huidige skets uitvee?",
|
||||
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
|
||||
}
|
||||
},
|
||||
"cloud": {
|
||||
"GoToCloud": "GAAN NA WOLK"
|
||||
}
|
||||
}
|
32
i18n/ar.json
32
i18n/ar.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": "ادوات"
|
||||
@@ -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": "افحص التحديثات عند التشغيل",
|
||||
"editorQuickSuggestions": "Editor Quick Suggestions",
|
||||
"additionalManagerURLs": "تدبير عناوين اللوحات الإضافية",
|
||||
"noProxy": "No proxy",
|
||||
@@ -108,7 +123,7 @@
|
||||
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
|
||||
"configDialogTitle": "Select Other Board & Port",
|
||||
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
|
||||
"configDialog2": "If you only select a Board you will be able just to compile, but not to upload your sketch.",
|
||||
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
|
||||
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
|
||||
"showAllAvailablePorts": "Shows all available ports when enabled",
|
||||
"programmer": "Programmer",
|
||||
@@ -173,7 +188,7 @@
|
||||
"showFolder": "Show Sketch Folder",
|
||||
"sketch": "Sketch",
|
||||
"moving": "Moving",
|
||||
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named as \"{1}\".\nCreate this folder, move the file, and continue?",
|
||||
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
|
||||
"cantOpen": "المجلد المسمى \"{0}\" موجود مسبقا. لا يمكن فتح الشيفرة البرمجية",
|
||||
"saveFolderAs": "Save sketch folder as...",
|
||||
"sketchbook": "Sketchbook",
|
||||
@@ -223,7 +238,8 @@
|
||||
"reference": "Reference",
|
||||
"findInReference": "Find in Reference",
|
||||
"faq": "Frequently Asked Questions",
|
||||
"visit": "Visit Arduino.cc"
|
||||
"visit": "Visit Arduino.cc",
|
||||
"privacyPolicy": "Privacy Policy"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "Upload SSL Root Certificates",
|
||||
@@ -243,14 +259,14 @@
|
||||
"noSupportedBoardConnected": "No supported board connected"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Updater",
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Updater",
|
||||
"selectBoard": "Select Board",
|
||||
"checkUpdates": "Check Updates",
|
||||
"selectVersion": "Select firmware version",
|
||||
"install": "تنصيب",
|
||||
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
|
||||
"installingFirmware": "Installing firmware.",
|
||||
"successfullyInstalled": "Firmware succesfully installed.",
|
||||
"successfullyInstalled": "Firmware successfully installed.",
|
||||
"failedInstall": "Installation failed. Please try again."
|
||||
},
|
||||
"dialog": {
|
||||
@@ -269,7 +285,7 @@
|
||||
"carriageReturn": "اعادة الحمل",
|
||||
"newLineCarriageReturn": "كلاهما NL & CR",
|
||||
"notConnected": "Not connected. Select a board and a port to connect automatically.",
|
||||
"message": "Message ({0} + Enter to send message to '{1}' on '{2}'",
|
||||
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
|
||||
"connectionBusy": "Connection failed. Serial port is busy: {0}",
|
||||
"disconnected": "Disconnected {0} from {1}.",
|
||||
"unexpectedError": "Unexpected error. Reconnecting {0} on port {1}.",
|
||||
|
32
i18n/bg.json
32
i18n/bg.json
@@ -14,6 +14,22 @@
|
||||
"saveChangesToSketch": "Искате ли да запазите промените в тази скица, преди да затворите?",
|
||||
"loseChanges": "Ако не запазите, промените ви ще бъдат загубени."
|
||||
},
|
||||
"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": "Скица",
|
||||
"tools": "Инструменти"
|
||||
@@ -31,7 +47,7 @@
|
||||
"upload.verbose": "True за подробен изход за качване. False по подразбиране.",
|
||||
"window.autoScale": "True , ако потребителският интерфейс автоматично се мащабира с размера на шрифта.",
|
||||
"window.zoomLevel": "Регулирайте нивото на увеличение на прозореца. Оригиналният размер е 0 и всяко увеличение над (напр. 1) или под (напр. -1) представлява увеличение с 20% по-голямо или по-малко. Можете също да въведете десетични знаци, за да регулирате нивото на увеличение по-финно.",
|
||||
"ide.autoUpdate": "True, за да активирате автоматичните проверки за актуализация. IDE ще проверява за актуализации автоматично и периодично.",
|
||||
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
|
||||
"board.certificates": "Списък със сертификати, които могат да бъдат качени на платката",
|
||||
"sketchbook.showAllFiles": "True , за да се покажат всички файлове вътре в скицата. По подразбиране е false.",
|
||||
"cloud.enabled": "True , ако функциите за синхронизиране на скицата са активирани. По подразбиране е true.",
|
||||
@@ -55,7 +71,6 @@
|
||||
"compile": "компилиране",
|
||||
"upload": "качване",
|
||||
"verifyAfterUpload": "Потвърдете кода след качване",
|
||||
"checkForUpdates": "Проверете за актуализации при стартиране",
|
||||
"editorQuickSuggestions": "Бързи предложения на редактора",
|
||||
"additionalManagerURLs": "Допълнителни URL адреси на мениджър на платки",
|
||||
"noProxy": "Без прокси",
|
||||
@@ -108,7 +123,7 @@
|
||||
"installNow": "Ядрото „{0} {1}“ трябва да бъде инсталирано за текущо избраната платка „{2}“. Искате ли да го инсталирате сега?",
|
||||
"configDialogTitle": "Изберете друга платка и порт",
|
||||
"configDialog1": "Изберете както платка, така и порт, ако искате да качите скица.",
|
||||
"configDialog2": "Ако изберете само платка, ще можете само да компилирате, но не и да качвате скицата си.",
|
||||
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
|
||||
"pleasePickBoard": "Моля, изберете платка, свързана към порта, който сте избрали.",
|
||||
"showAllAvailablePorts": "Показва всички налични портове, когато е активиран",
|
||||
"programmer": "Програматор",
|
||||
@@ -173,7 +188,7 @@
|
||||
"showFolder": "Показване на папка за скици",
|
||||
"sketch": "Скица",
|
||||
"moving": "Преместване",
|
||||
"movingMsg": "Файлът „{0}“ трябва да бъде в папка на скица, наречена „{1}“.\nСъздай тази папка, премести файла и продължи?",
|
||||
"movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
|
||||
"cantOpen": "Папка с име „{0}“ вече съществува. Не може да се отвори скица.",
|
||||
"saveFolderAs": "Запазете папката със скица като...",
|
||||
"sketchbook": "Скицник",
|
||||
@@ -223,7 +238,8 @@
|
||||
"reference": "Референция",
|
||||
"findInReference": "Намерете в Референцията",
|
||||
"faq": "Често задавани въпроси",
|
||||
"visit": "Посетете Arduino.cc"
|
||||
"visit": "Посетете Arduino.cc",
|
||||
"privacyPolicy": "Privacy Policy"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "Качете SSL коренни сертификати",
|
||||
@@ -243,14 +259,14 @@
|
||||
"noSupportedBoardConnected": "Няма свързана поддържана платка"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Обновяване на фърмуера",
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Updater",
|
||||
"selectBoard": "Изберете платка",
|
||||
"checkUpdates": "Проверете актуализации",
|
||||
"selectVersion": "Изберете версия на фърмуера",
|
||||
"install": "Инсталирай",
|
||||
"overwriteSketch": "Инсталацията ще презапише скицата на платката.",
|
||||
"installingFirmware": "Инсталиране на фърмуер.",
|
||||
"successfullyInstalled": "Фърмуерът е инсталиран успешно.",
|
||||
"successfullyInstalled": "Firmware successfully installed.",
|
||||
"failedInstall": "Неуспешно инсталиране. Моля, опитайте отново."
|
||||
},
|
||||
"dialog": {
|
||||
@@ -269,7 +285,7 @@
|
||||
"carriageReturn": "Carriage Return",
|
||||
"newLineCarriageReturn": "Както NL, така и CR",
|
||||
"notConnected": "Няма връзка. Изберете платка и порт за автоматично свързване.",
|
||||
"message": "Съобщение ({0} + Enter, за да изпратите съобщение до „{1}“ на „{2}“",
|
||||
"message": "Message ({0} + Enter to send message to '{1}' on '{2}')",
|
||||
"connectionBusy": "Свързването е неуспешно. Серийният порт е зает: {0}",
|
||||
"disconnected": "Прекъснато е връзката на {0} с {1}.",
|
||||
"unexpectedError": "Неочаквана грешка. Повторно свързване на {0} на порт {1}.",
|
||||
|
350
i18n/cs.json
Normal file
350
i18n/cs.json
Normal file
@@ -0,0 +1,350 @@
|
||||
{
|
||||
"arduino": {
|
||||
"common": {
|
||||
"offlineIndicator": "Nejspíše nejste online. Bez Internetového připojení nebude Arduino CLI schopno stáhnout potřebné zdroje a toto může způsobit chybu. Prosím připojte se k Internetu a restartujte aplikaci.",
|
||||
"noBoardSelected": "Nebyla zvolena deska",
|
||||
"selectedOn": "zapnuto{0}",
|
||||
"notConnected": "[nepřipojen]",
|
||||
"serialMonitor": "Seriový monitor",
|
||||
"oldFormat": "{0}používá stále starý formát `.pde`. Chcete ho převést na soubor s příponou `.ino`?",
|
||||
"later": "Později",
|
||||
"selectBoard": "Zvolte desku",
|
||||
"unknown": "Neznámý",
|
||||
"processing": "Zpracovávám",
|
||||
"saveChangesToSketch": "Chcete uložit změny před ukončením programu?",
|
||||
"loseChanges": "Pokud projekt neuložíte, změny budou ztraceny. "
|
||||
},
|
||||
"ide-updater": {
|
||||
"errorCheckingForUpdates": "Nastala chyba při kontrole aktualizací Arduino IDE{0}",
|
||||
"notNowButton": "Nyní ne",
|
||||
"versionDownloaded": "Arduino IDE {0}bylo staženo.",
|
||||
"closeToInstallNotice": "Vypněte program a nainstalujte update na Váš stroj. ",
|
||||
"closeAndInstallButton": "Zavřít a nainstalovat",
|
||||
"downloadingNotice": "Stahuji poslední verzi Arduino IDE.",
|
||||
"updateAvailable": "Je dostupná aktualizace",
|
||||
"newVersionAvailable": "Je k dispozici nová verze Arduino IDE ({0}).",
|
||||
"skipVersionButton": "přeskočit verzi",
|
||||
"downloadButton": "Stáhnout",
|
||||
"goToDownloadPage": "Je dostupná aktualizace pro Arduino IDE, ale nepodařilo se jej stáhnout a nainstalovat automaticky. Prosím navštivte stránku pro stažení a stáhněte prosím jeho poslední verzi ručně. ",
|
||||
"goToDownloadButton": "přejit do stažených",
|
||||
"ideUpdaterDialog": "Softwarová aktualizace",
|
||||
"noUpdatesAvailable": "Nejsou k dispozici žádné aktualizace pro Arduino ID"
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Sketch",
|
||||
"tools": "Nástroje"
|
||||
},
|
||||
"debug": {
|
||||
"optimizeForDebugging": "optimalizovat pro Debugging",
|
||||
"debugWithMessage": "Debug - {0}",
|
||||
"noPlatformInstalledFor": "Platforma není nainstalována pro '{0}'",
|
||||
"debuggingNotSupported": "Debugging není podporován s '{0}'"
|
||||
},
|
||||
"preferences": {
|
||||
"language.log": "True if the Arduino Language Server should generate log files into the sketch folder. Otherwise, false. It's false by default.",
|
||||
"compile.verbose": "True for verbose compile output. False by default",
|
||||
"compile.warnings": "Tells gcc which warning level to use. It's 'None' by default",
|
||||
"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.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
|
||||
"board.certificates": "Seznam certifikátů, které mohou být nahrány na desky",
|
||||
"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.",
|
||||
"cloud.pull.warn": "True if users should be warned before pulling a cloud sketch. Defaults to true.",
|
||||
"cloud.push.warn": "True if users should be warned before pushing a cloud sketch. Defaults to true.",
|
||||
"cloud.pushpublic.warn": "True if users should be warned before pushing a public sketch to the cloud. Defaults to true.",
|
||||
"cloud.sketchSyncEnpoint": "Endpoint použitý pro stahování a odesílání sketchí z backendu. Ve výchozím stavu je toto směrováno na Arduino Cloud API.",
|
||||
"auth.clientID": "OAuth2 klient ID",
|
||||
"auth.domain": "Doména OAuth2 ",
|
||||
"auth.audience": "OAuth2 audience",
|
||||
"auth.registerUri": "URL použita při registraci nového uživatele. ",
|
||||
"network": "Síť",
|
||||
"sketchbook.location": "Umístění sketche",
|
||||
"browse": "Procházet",
|
||||
"files.inside.sketches": "Zobrazit soubory uvnitř sketche",
|
||||
"editorFontSize": "Editor velikosti fontu",
|
||||
"interfaceScale": "Měřítko prostředí",
|
||||
"showVerbose": "Zobrazit podrobný výstup během",
|
||||
"compilerWarnings": "Varování kompileru",
|
||||
"automatic": "Automaticky",
|
||||
"compile": "kompilovat",
|
||||
"upload": "nahrát",
|
||||
"verifyAfterUpload": "Kontrolovat kód po nahrání",
|
||||
"editorQuickSuggestions": "Rychlá nápověda v editoru",
|
||||
"additionalManagerURLs": "Další URL pro manager desek",
|
||||
"noProxy": "Bez proxy",
|
||||
"manualProxy": "Ruční nastavení proxy",
|
||||
"newSketchbookLocation": "Zvolit nové umístění projektů",
|
||||
"choose": "Zvolit",
|
||||
"enterAdditionalURLs": "Vložte další URL, jednu pro každý řádek",
|
||||
"unofficialBoardSupport": "Zde klikněte pro seznam adres neoficiálně podporovaných desek",
|
||||
"invalid.sketchbook.location": "Neplatné umístění projektů:{0}",
|
||||
"invalid.editorFontSize": "Neplatná velikost editoru písem: Toto číslo musí být kladné.",
|
||||
"invalid.theme": "Neplatné téma."
|
||||
},
|
||||
"cloud": {
|
||||
"signIn": "Přihlásit se",
|
||||
"signOut": "Odhlásit se",
|
||||
"chooseSketchVisibility": "Zvolte viditelnost sketche:",
|
||||
"privateVisibility": "Soukromá. Pouze vy můžete vidět tuto sketch.",
|
||||
"publicVisibility": "Veřejná. Kdokoli s odkazem může vidět tuto sketch.",
|
||||
"link": "Adresa: ",
|
||||
"embed": "Vložit: ",
|
||||
"cloudSketchbook": "Cloudové umístění projektů",
|
||||
"shareSketch": "Sdílet sketch",
|
||||
"showHideRemoveSketchbook": "Zobrazit/skrýt vzdálenou sketch",
|
||||
"pullSketch": "Stáhnout sketch",
|
||||
"openInCloudEditor": "Otevřít v cloudovém editoru",
|
||||
"options": "Možnosti...",
|
||||
"share": "Sdílet...",
|
||||
"remote": "Vzdálený",
|
||||
"emptySketchbook": "Umístění projektů je prázdné",
|
||||
"visitArduinoCloud": "Navštivte Arduino Cloud pro vytvoření cloudové sketche",
|
||||
"signInToCloud": "Přihlásit se do Arduino Cloud",
|
||||
"syncEditSketches": "Synchronizovat a editovat sketche v Arduino Cloud",
|
||||
"learnMore": "Zjistit více",
|
||||
"continue": "Pokračovat",
|
||||
"pushSketch": "Odeslat sketch",
|
||||
"pushSketchMsg": "Toto je veřejná sketch. Před odesláním se prosím ujistěte že jsou smazané citlivé informace ze souboru arduino_secrets.h . Tuto sketch můžete změnit na soukromou v panelu pro sdílení. ",
|
||||
"pull": "Stáhnout",
|
||||
"pullSketchMsg": "Stažením této sketche z cloudu přepíšete její lokální verzi. Chcete opravdu pokračovat?",
|
||||
"donePulling": "Stahování dokončeno ’{0}’.",
|
||||
"notYetPulled": "Nemohu odeslat do cloudu jelikož z něj ještě nebylo staženo.",
|
||||
"push": "Odeslat",
|
||||
"pullFirst": "Nejprve musíte stáhnout z cloudu, aby bylo možno do něj odeslat.",
|
||||
"donePushing": "Odesílání dokončeno ‘{0}’.",
|
||||
"connected": "Připojen",
|
||||
"offline": "Nepřipojen",
|
||||
"profilePicture": "Profilový obrázek"
|
||||
},
|
||||
"board": {
|
||||
"installManually": "Instalovat ručně",
|
||||
"installNow": "\"{0}{1}\" jádro musí být instalováno pro aktuálně zvolenou \"{2}\" desku. Chcete ho nyní nainstalovat?",
|
||||
"configDialogTitle": "Zvolte desku a port",
|
||||
"configDialog1": "Pokud chcete nahrát sketch, musíte zvolit jak desku tak i port.",
|
||||
"configDialog2": "Pokud zvolíte jen desku, budete schopni kompilovat sketch, ale nebudete ji moci nahrát do desky.",
|
||||
"pleasePickBoard": "Vyberte prosím desku která je připojená k zvolenému portu. ",
|
||||
"showAllAvailablePorts": "Zobrazit všechny dostupné porty (pokud je zaškrtnuto)",
|
||||
"programmer": "Programátor",
|
||||
"succesfullyInstalledPlatform": "Platforma {0}:{1} byla úspěšně nainstalována.",
|
||||
"succesfullyUninstalledPlatform": "Platforma {0}:{1} byla úspěšně odinstalována.",
|
||||
"couldNotFindPreviouslySelected": "Dříve zvolená deska '{0}' v instalované platformě '{1}' nebyla nalezena. Zvolte prosím manuálně desku kterou chcete použít. Chcete tuto desku zvolit nyní? ",
|
||||
"reselectLater": "Zvolit později",
|
||||
"noneSelected": "Nebyla zvolena deska.",
|
||||
"noPortsSelected": "Nebyl zvolen port pro desku '{0}'.",
|
||||
"noFQBN": "FQBN není dostupné pro zvolenou desku \"{0}\". Máte nainstalované příslušné jádro? ",
|
||||
"openBoardsConfig": "Zvolte jinou desku a port...",
|
||||
"boardListItem": "{0}v{1}",
|
||||
"selectBoardForInfo": "Prosím zvolte desku pro získání informací o desce.",
|
||||
"platformMissing": "Platforma pro zvolenou desku '{0}' není nainstalována.",
|
||||
"selectPortForInfo": "Prosím zvolte port pro získání informací o desce.",
|
||||
"boardInfo": "Info o desce",
|
||||
"board": "Deska {0}",
|
||||
"port": "Port {0}",
|
||||
"getBoardInfo": "Získat info o desce.",
|
||||
"inSketchbook": "(v projektech)"
|
||||
},
|
||||
"boardsManager": "Manažér desek",
|
||||
"about": {
|
||||
"label": "O {0}",
|
||||
"detail": "Verze: {0}\nDatum: {1}[2]\nVerze CLI: {3}{4} [{5}]\n\n{6}"
|
||||
},
|
||||
"contributions": {
|
||||
"addFile": "Přidat soubor",
|
||||
"replaceTitle": "Vyměnit",
|
||||
"fileAdded": "Soubor byl přidán do sketche."
|
||||
},
|
||||
"replaceMsg": "Vyměnit existující verzi {0}?",
|
||||
"library": {
|
||||
"addZip": "Přidat .ZIP knihovnu...",
|
||||
"zipLibrary": "Knihovna",
|
||||
"overwriteExistingLibrary": "Chcete přepsat existující knihovnu? ",
|
||||
"successfullyInstalledZipLibrary": "Knihovna byla úspěšně nainstalována z archívu {0}",
|
||||
"namedLibraryAlreadyExists": "Knihovna s názvem {0}již existuje. Chcete jí přepsat? ",
|
||||
"libraryAlreadyExists": "Knihovna již existuje. Chcete jí přepsat?",
|
||||
"include": "Zahrnout knihovnu",
|
||||
"manageLibraries": "Spravovat knihovny...",
|
||||
"arduinoLibraries": "Arduino knihovny",
|
||||
"contributedLibraries": "Přispěné knihovny",
|
||||
"title": "Manažér knihoven",
|
||||
"needsOneDependency": "Knihovna <b>{0}:{1}</b>vyžaduje další závislost která není nainstalovaná:",
|
||||
"needsMultipleDependencies": "Knihovna <b>{0}:{1}</b>vyžaduje další jinou závislost která není nainstalovaná:",
|
||||
"installOneMissingDependency": "Chcete nainstalovat chybějící závislost? ",
|
||||
"installMissingDependencies": "Chcete nainstalovat všechny chybějící závislosti? ",
|
||||
"dependenciesForLibrary": "Závislosti pro knihovny {0}:{1}",
|
||||
"installAll": "Instalovat vše",
|
||||
"installOnly": "Instalovat pouze {0}",
|
||||
"installedSuccessfully": "Knihovna {0}:{1}byla úspěšně nainstalována",
|
||||
"uninstalledSuccessfully": "Knihovna {0}:{1}byla úspěšně odinstalována"
|
||||
},
|
||||
"selectZip": "Zvolte ZIP soubor s knihovnou kterou chcete přidat",
|
||||
"sketch": {
|
||||
"archiveSketch": "Archivovat sketch",
|
||||
"saveSketchAs": "Uložit složku sketche jako...",
|
||||
"createdArchive": "Vytvořen archív '{0}'.",
|
||||
"new": "Nový",
|
||||
"openRecent": "Otevřít nedávné",
|
||||
"showFolder": "Zobrazit složku sketche",
|
||||
"sketch": "Sketch",
|
||||
"moving": "Přesouvám",
|
||||
"movingMsg": "Soubor \"{0}\" musí být uvnitř složky která je shodná názvem \"{1}\".\nVytvořit složku, přesunout tam- soubor a pokračovat? ",
|
||||
"cantOpen": "Složka s názvem \"{0}\" již existuje, proto nemohu otevřít sketch. ",
|
||||
"saveFolderAs": "Uložit složku sketche jako...",
|
||||
"sketchbook": "Projekty",
|
||||
"upload": "Nahrát",
|
||||
"uploadUsingProgrammer": "Nahrát pomocí programátoru",
|
||||
"userFieldsNotFoundError": "Nemohu nalézt uživatelská pole pro připojenou desku",
|
||||
"doneUploading": "Nahrávání dokončeno. ",
|
||||
"configureAndUpload": "Nastavit a nahrát",
|
||||
"verifyOrCompile": "Ověřit/Kompilovat",
|
||||
"exportBinary": "Exportovat kompilované soubory",
|
||||
"verify": "Ověřit",
|
||||
"doneCompiling": "Ověřování dokončeno.",
|
||||
"couldNotConnectToSerial": "Nebylo možné se opět připojit k seriovému portu. {0}",
|
||||
"openSketchInNewWindow": "Otevřít sketch v novém okně",
|
||||
"openFolder": "Otevřít složku",
|
||||
"titleLocalSketchbook": "Složka lokálních projektů",
|
||||
"titleSketchbook": "Projekty",
|
||||
"close": "Opravdu chcete zavřít tuto sketch? "
|
||||
},
|
||||
"bootloader": {
|
||||
"burnBootloader": "Nahrát zavaděč",
|
||||
"doneBurningBootloader": "Nahrání zavaděče bylo dokončeno. "
|
||||
},
|
||||
"editor": {
|
||||
"copyForForum": "Kopírovat pro forum (Markdown)",
|
||||
"commentUncomment": "Komentovat/Odkomentovat",
|
||||
"increaseIndent": "Zvětšit odrážku",
|
||||
"decreaseIndent": "Zmenšit odrážku",
|
||||
"increaseFontSize": "Zvýšit velikost písma",
|
||||
"decreaseFontSize": "Zmenšit velikost písma",
|
||||
"autoFormat": "Automatické formátování"
|
||||
},
|
||||
"examples": {
|
||||
"menu": "Příklady",
|
||||
"couldNotInitializeExamples": "Nebylo možné inicializovat vestavěné příklady.",
|
||||
"builtInExamples": "Vestavěné příklady.",
|
||||
"customLibrary": "Příklady pro vlastní knihovny",
|
||||
"for": "Příklady pro {0}",
|
||||
"forAny": "Příklady pro všechny desky"
|
||||
},
|
||||
"help": {
|
||||
"search": "Hledat na Arduino.cc",
|
||||
"keyword": "Napište klíčové slovo",
|
||||
"gettingStarted": "Začínáme",
|
||||
"environment": "Prostředí",
|
||||
"troubleshooting": "Řešení problémů",
|
||||
"reference": "Reference",
|
||||
"findInReference": "Hledat v referencích",
|
||||
"faq": "Často kladené otázky",
|
||||
"visit": "Navštívit Arduino.cc",
|
||||
"privacyPolicy": "Zásady ochrany osobních údajů"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "Nahrát certifikát SSL",
|
||||
"openContext": "Otevřít kontext",
|
||||
"remove": "Odstranit",
|
||||
"upload": "Nahrát",
|
||||
"addURL": "Přidat URL pro získání SSL certifikátu",
|
||||
"enterURL": "Vložit URL",
|
||||
"selectCertificateToUpload": "1. Zvolit certifikát pro nahrání",
|
||||
"addNew": "Přidat nový",
|
||||
"selectDestinationBoardToUpload": "2. Zvolit cílovou desku a nahrát certifikát",
|
||||
"uploadingCertificates": "Nahrávám certifikát.",
|
||||
"certificatesUploaded": "Certifikáty nahrány. ",
|
||||
"uploadFailed": "Nahrání se nezdařilo. Prosím zkuste to později. ",
|
||||
"selectBoard": "Zvolte desku...",
|
||||
"boardAtPort": "{0}v{1}",
|
||||
"noSupportedBoardConnected": "Není připojena žádná podporovaná deska"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Updater",
|
||||
"selectBoard": "Zvolit desku",
|
||||
"checkUpdates": "Zkontrolovat aktualizace",
|
||||
"selectVersion": "Zvolit verzi firmwaru",
|
||||
"install": "Instalovat",
|
||||
"overwriteSketch": "Instalace přepíše sketch na desce.",
|
||||
"installingFirmware": "Instaluji firmware.",
|
||||
"successfullyInstalled": "Firmware byl úspěšně nainstalován. ",
|
||||
"failedInstall": "Instalace se nezdařila. Prosím zkuste to později. "
|
||||
},
|
||||
"dialog": {
|
||||
"dontAskAgain": "Znovu se neptat"
|
||||
},
|
||||
"userFields": {
|
||||
"cancel": "Zrušit",
|
||||
"upload": "Nahrát"
|
||||
},
|
||||
"serial": {
|
||||
"toggleTimestamp": "Přepnout časovou značku",
|
||||
"autoscroll": "Autoscroll",
|
||||
"timestamp": "Časová značka",
|
||||
"noLineEndings": "Bez konce řádku",
|
||||
"newLine": "Nový řádek (NL)",
|
||||
"carriageReturn": "Enter (CR)",
|
||||
"newLineCarriageReturn": "Oba NL & CR",
|
||||
"notConnected": "Nepřipojen. Zvolte desku a port pro automatické připojení.",
|
||||
"message": "Zpráva ({0}+ Enter pro odeslání zprávy do '{1}' na '{2}')",
|
||||
"connectionBusy": "Připojení se nezdařilo, sériový port je zaneprázdněn: {0}",
|
||||
"disconnected": "Odpojen {0}od {1}.",
|
||||
"unexpectedError": "Nastala neočekávaná chyba. Opět připojuji {0} na portu {1}.",
|
||||
"failedReconnect": "Nepodařilo se připojit {0}k sériovému portu po 10 pokusech po sobě. Sériový port {1} je zaneprázdněn. ",
|
||||
"reconnect": "Opětovné připojení {0} k {1}za [2] vteřin..."
|
||||
},
|
||||
"component": {
|
||||
"uninstall": "Odinstalovat",
|
||||
"uninstallMsg": "Chcete odinstalovat {0}?",
|
||||
"by": "od",
|
||||
"version": "Verze {0}",
|
||||
"moreInfo": "Více informací",
|
||||
"install": "Instalovat",
|
||||
"filterSearch": "Filtrovat vyhledávání... "
|
||||
},
|
||||
"electron": {
|
||||
"couldNotSave": "Nebylo možné uložit sketch. Zkopírujte prosím neuloženou práci do Vašeho oblíbeného textového editoru a restartujte IDE. ",
|
||||
"unsavedChanges": "Jakékoli změny nebudou uloženy. "
|
||||
},
|
||||
"compile": {
|
||||
"error": "Chyba kompilace: {0}"
|
||||
},
|
||||
"upload": {
|
||||
"error": "{0}chyba: {1}"
|
||||
},
|
||||
"burnBootloader": {
|
||||
"error": "Chyba během nahrávání zavaděče: {0}"
|
||||
}
|
||||
},
|
||||
"theia": {
|
||||
"core": {
|
||||
"couldNotSave": "Nebylo možné uložit sketch. Zkopírujte prosím neuloženou práci do Vašeho oblíbeného textového editoru a restartujte IDE. ",
|
||||
"offline": "Nepřipojen",
|
||||
"daemonOffline": "CLI Daemon nepřipojen",
|
||||
"cannotConnectBackend": "Nebylo možné se připojit k backendu. ",
|
||||
"cannotConnectDaemon": "Nebylo možné se připojit k CLI Daemon."
|
||||
},
|
||||
"debug": {
|
||||
"start": "Start...",
|
||||
"typeNotSupported": "Typ \"{0}\" debugovacího spojení není podporován, ",
|
||||
"startError": "Vyskytla se chyba při spouštění debugovacího spojení, zkontrolujte prosím log pro více informací. "
|
||||
},
|
||||
"editor": {
|
||||
"unsavedTitle": "Neuloženo – {0}"
|
||||
},
|
||||
"messages": {
|
||||
"expand": "Rozšířit",
|
||||
"collapse": "Složit"
|
||||
},
|
||||
"workspace": {
|
||||
"fileNewName": "Název pro nový soubor",
|
||||
"invalidFilename": "Neplatný název souboru.",
|
||||
"invalidExtension": ".{0}je neplatná přípona",
|
||||
"newFileName": "Nový název souboru",
|
||||
"deleteCurrentSketch": "Opravdu chcete vymazat aktuální sketch? ",
|
||||
"sketchDirectoryError": "Vyskytla se chyba při vytváření složky pro sketch. Více informací naleznete v logu. Aplikace nebude pravděpodobně pracovat správně. "
|
||||
}
|
||||
},
|
||||
"cloud": {
|
||||
"GoToCloud": "Přejdi do Cloudu"
|
||||
}
|
||||
}
|
34
i18n/de.json
34
i18n/de.json
@@ -3,7 +3,7 @@
|
||||
"common": {
|
||||
"offlineIndicator": "Anscheinend bist du offline. Ohne eine aktive Internetverbindung kann das Arduino CLI nicht die nötigen Ressourcen herunterladen, was zu Problemen führen kann. Bitte überprüfe deine Internetverbindung und starte das Programm neu. ",
|
||||
"noBoardSelected": "Kein Board ausgewählt",
|
||||
"selectedOn": "bei {0}",
|
||||
"selectedOn": "an {0}",
|
||||
"notConnected": "[keine Verbindung]",
|
||||
"serialMonitor": "Serieller Monitor",
|
||||
"oldFormat": "Der Sketch '{0}' verwendet noch das alte '.pde' Format. Möchtest du auf die neuere '.ino' Endung wechseln?",
|
||||
@@ -12,7 +12,23 @@
|
||||
"unknown": "unbekannt",
|
||||
"processing": "Verarbeiten",
|
||||
"saveChangesToSketch": "Änderungen zu diesem Sketch vor dem Schließen sichern?",
|
||||
"loseChanges": "Wenn du nicht sicherst, werden deine Änderungen gelöscht."
|
||||
"loseChanges": "Wenn du nicht speicherst, werden deine Änderungen gelöscht."
|
||||
},
|
||||
"ide-updater": {
|
||||
"errorCheckingForUpdates": "Fehler bei der Suche nach IDE Updates{0}",
|
||||
"notNowButton": "Später",
|
||||
"versionDownloaded": "Arduino IDE {0} wurde heruntergeladen",
|
||||
"closeToInstallNotice": "Schließe die Software und installiere das Update auf deinem Computer",
|
||||
"closeAndInstallButton": "Schließen und Installieren",
|
||||
"downloadingNotice": "Die neueste Version der Arduino IDE wird heruntergeladen",
|
||||
"updateAvailable": "Update Verfügbar",
|
||||
"newVersionAvailable": "Eine neue Version der Arduino IDE ({0}) ist zum Download verfügbar",
|
||||
"skipVersionButton": "Version Überspringen",
|
||||
"downloadButton": "Download",
|
||||
"goToDownloadPage": "Eine Update für die Arduino IDE ist verfügbar, konnte aber nicht automatisch heruntergeladen und installiert werden. Bitte gehen sie zur Download-Seite und laden sie dort die neueste Version herunter",
|
||||
"goToDownloadButton": "Zum Download Wechseln",
|
||||
"ideUpdaterDialog": "Software Update",
|
||||
"noUpdatesAvailable": "Es gibt keine neuen Updates für die Arduino IDE"
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Sketch",
|
||||
@@ -31,7 +47,7 @@
|
||||
"upload.verbose": "Wahr für ausführliche Ausgaben während dem Hochladen. Standardmäßig Falsch.",
|
||||
"window.autoScale": "Ist wahr, wenn die Benutzeroberfläche automatisch mit der Schriftgröße skaliert wird.",
|
||||
"window.zoomLevel": "Stelle die Zoomstufe des Fensters ein. Der Standardwert ist 0, jede Vergrößerung (z.B.: 1) oder Verringerung (z.B.: -1) um eins steht für 20% Vergrößerung bzw. Verkleinerung des Fensters. Du kannst auch Kommazahlen eingeben, um die Zoomstufe feiner einzustellen.\n ",
|
||||
"ide.autoUpdate": "Wahr, um automatisch auf Updates zu überprüfen. Die IDE wird automatisch regelmäßig auf Updates prüfen.",
|
||||
"ide.updateChannel": "Von welchem Kannal die Updates kommen sollen. 'stabil' ist die stabile Version, 'nächtlich' ist die neueste Entwicklerversion",
|
||||
"board.certificates": "Liste der Zertifikate, welche zu den Boards hochgeladen werden können.",
|
||||
"sketchbook.showAllFiles": "Wahr, um alle Dateien im Sketch anzuzeigen. Standardmäßig Falsch.",
|
||||
"cloud.enabled": "Wahr, wenn die Sketch-Syncfunctionen aktiv sind. Standardeinstellung ist wahr.",
|
||||
@@ -55,7 +71,6 @@
|
||||
"compile": "Kompilieren",
|
||||
"upload": "Hochladen",
|
||||
"verifyAfterUpload": "Code nach Hochladen überprüfen ",
|
||||
"checkForUpdates": "Beim Start nach Updates suchen",
|
||||
"editorQuickSuggestions": "Schnelle Editor Vorschläge",
|
||||
"additionalManagerURLs": "Zusätzliche Boardverwalter-URLs",
|
||||
"noProxy": "Kein Proxy",
|
||||
@@ -85,7 +100,7 @@
|
||||
"share": "Teilen....",
|
||||
"remote": "Remote",
|
||||
"emptySketchbook": "Dein Sketchbook ist leer",
|
||||
"visitArduinoCloud": "Besuche Arduino Cloud um Cloud Sketche zu erstellen.",
|
||||
"visitArduinoCloud": "Besuche Arduino Cloud um Cloud Sketche zu erstellen.",
|
||||
"signInToCloud": "Anmelden zur Arduino Cloud",
|
||||
"syncEditSketches": "Synchronisiere und editiere deine Arduino Cloud Sketches.",
|
||||
"learnMore": "Mehr erfahren",
|
||||
@@ -173,7 +188,7 @@
|
||||
"showFolder": "Zeige Sketch Ordner",
|
||||
"sketch": "Sketch",
|
||||
"moving": "Übertragen...",
|
||||
"movingMsg": "Die Datei \"{0}\" muss sich in einem Sketch Ordner \"{1}\" befinden.\nDiesen Ordner erstellen, Datei verschieben und fortfahren?",
|
||||
"movingMsg": "Die Datei \"{0}\" muss sich in einen Sketch Ordner \"{1}\" befinden.\nOrdner erstellen, Datei verschieben und fortfahren?",
|
||||
"cantOpen": "Ein Ordner mit dem Namen \"{0}\" ist bereits vorhanden. Der Sketch kann nicht geöffnet werden.",
|
||||
"saveFolderAs": "Sketch Ordner speichern als...",
|
||||
"sketchbook": "Sketchbook",
|
||||
@@ -223,7 +238,8 @@
|
||||
"reference": "Referenz",
|
||||
"findInReference": "Referenzsuche",
|
||||
"faq": "Häufig gestellte Fragen",
|
||||
"visit": "Besuche Arduino.cc"
|
||||
"visit": "Besuche Arduino.cc",
|
||||
"privacyPolicy": "Datenschutzbestimmungen"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "SSL Root Zertifikat hochladen",
|
||||
@@ -243,7 +259,7 @@
|
||||
"noSupportedBoardConnected": "Kein unterstütztes Board angeschlossen"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Aktualisierer",
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Aktualisierer",
|
||||
"selectBoard": "Board auswählen",
|
||||
"checkUpdates": "Nach Updates Suchen",
|
||||
"selectVersion": "Firmware Version wählen",
|
||||
@@ -269,7 +285,7 @@
|
||||
"carriageReturn": "Zeilenumbruch",
|
||||
"newLineCarriageReturn": "Sowohl NL als auch CR",
|
||||
"notConnected": "Nicht verbunden. Wählen Sie ein Board und einen Port, um automatisch zu verbinden.",
|
||||
"message": "Nachricht ({0} + Enter, um Nachricht an '{1}' auf '{2}' zu senden",
|
||||
"message": "Nachricht ({0} + Enter, um Nachricht an '{1}' auf '{2}') zu senden",
|
||||
"connectionBusy": "Verbindung fehlgeschlagen. Serieller port ist belegt: {0}",
|
||||
"disconnected": "{0} von {1} getrennt.",
|
||||
"unexpectedError": "100%match\nUnerwarteter Fehler. {0} wird am Port {1} erneut verbunden.",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user