mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-16 14:58:32 +00:00
Compare commits
51 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
96b5edf427 | ||
![]() |
a5a6a0b611 | ||
![]() |
2a27a14a68 | ||
![]() |
f2d492b5dc | ||
![]() |
5979e5aad2 | ||
![]() |
baa9b5f7ab | ||
![]() |
481497e384 | ||
![]() |
0207778373 | ||
![]() |
d79f32efd7 | ||
![]() |
3ab03dd62f | ||
![]() |
bc3cb0c230 | ||
![]() |
473cb11053 | ||
![]() |
0a87fd00f3 | ||
![]() |
9b1f15def8 | ||
![]() |
77b430675d | ||
![]() |
f660058c75 | ||
![]() |
9ecff86bbe | ||
![]() |
5ab3a747a6 | ||
![]() |
877c1a1559 | ||
![]() |
2f9bf86d75 | ||
![]() |
112153fb96 | ||
![]() |
69ac1f4779 | ||
![]() |
a20899ff43 | ||
![]() |
ef2be1c086 | ||
![]() |
af33dce0f6 | ||
![]() |
b3b22795f8 | ||
![]() |
8a0454db51 | ||
![]() |
f1a5d87ab2 | ||
![]() |
cf0a2161af | ||
![]() |
dcebd863cc | ||
![]() |
e8477b14f3 | ||
![]() |
0230071b5f | ||
![]() |
1d88263c85 | ||
![]() |
a71ac4c44d | ||
![]() |
66fc27e58c | ||
![]() |
bc365f4a8d | ||
![]() |
a5891f9884 | ||
![]() |
fcdf16a937 | ||
![]() |
e0b6dbbf2a | ||
![]() |
9529e78647 | ||
![]() |
51da3c0668 | ||
![]() |
c00d3d33dd | ||
![]() |
cfa9b8aea6 | ||
![]() |
6106e9ff1a | ||
![]() |
b1d9f65a0d | ||
![]() |
f4008100e1 | ||
![]() |
11a6959a24 | ||
![]() |
3c6e11832b | ||
![]() |
c064673ce1 | ||
![]() |
cc5764e536 | ||
![]() |
9131f2d09e |
115
.github/workflows/build.yml
vendored
115
.github/workflows/build.yml
vendored
@@ -15,15 +15,15 @@ on:
|
||||
|
||||
env:
|
||||
JOB_TRANSFER_ARTIFACT: build-artifacts
|
||||
CHANGELOG_ARTIFACTS: changelog
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
if: github.repository == 'arduino/arduino-ide'
|
||||
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,35 +50,36 @@ 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') }}
|
||||
IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
IS_FORK: ${{ github.event.pull_request.head.repo.fork == true }}
|
||||
run: |
|
||||
# See: https://www.electron.build/code-signing
|
||||
if [ $IS_FORK = true ]; then
|
||||
echo "Skipping the app signing: building from a fork."
|
||||
else
|
||||
if [ "${{ runner.OS }}" = "macOS" ]; then
|
||||
export CSC_LINK="${{ runner.temp }}/signing_certificate.p12"
|
||||
# APPLE_SIGNING_CERTIFICATE_P12 secret was produced by following the procedure from:
|
||||
# https://www.kencochrane.com/2020/08/01/build-and-sign-golang-binaries-for-macos-with-github-actions/#exporting-the-developer-certificate
|
||||
echo "${{ secrets.APPLE_SIGNING_CERTIFICATE_P12 }}" | base64 --decode > "$CSC_LINK"
|
||||
# See: https://www.electron.build/code-signing
|
||||
if [ $IS_FORK = true ]; then
|
||||
echo "Skipping the app signing: building from a fork."
|
||||
else
|
||||
if [ "${{ runner.OS }}" = "macOS" ]; then
|
||||
export CSC_LINK="${{ runner.temp }}/signing_certificate.p12"
|
||||
# APPLE_SIGNING_CERTIFICATE_P12 secret was produced by following the procedure from:
|
||||
# https://www.kencochrane.com/2020/08/01/build-and-sign-golang-binaries-for-macos-with-github-actions/#exporting-the-developer-certificate
|
||||
echo "${{ secrets.APPLE_SIGNING_CERTIFICATE_P12 }}" | base64 --decode > "$CSC_LINK"
|
||||
|
||||
export CSC_KEY_PASSWORD="${{ secrets.KEYCHAIN_PASSWORD }}"
|
||||
export CSC_KEY_PASSWORD="${{ secrets.KEYCHAIN_PASSWORD }}"
|
||||
|
||||
elif [ "${{ runner.OS }}" = "Windows" ]; then
|
||||
export CSC_LINK="${{ runner.temp }}/signing_certificate.pfx"
|
||||
npm config set msvs_version 2017 --global
|
||||
echo "${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PFX }}" | base64 --decode > "$CSC_LINK"
|
||||
elif [ "${{ runner.OS }}" = "Windows" ]; then
|
||||
export CSC_LINK="${{ runner.temp }}/signing_certificate.pfx"
|
||||
npm config set msvs_version 2017 --global
|
||||
echo "${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PFX }}" | base64 --decode > "$CSC_LINK"
|
||||
|
||||
export CSC_KEY_PASSWORD="${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PASSWORD }}"
|
||||
fi
|
||||
export CSC_KEY_PASSWORD="${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PASSWORD }}"
|
||||
fi
|
||||
fi
|
||||
|
||||
yarn --cwd ./electron/packager/
|
||||
yarn --cwd ./electron/packager/ package
|
||||
yarn --cwd ./electron/packager/
|
||||
yarn --cwd ./electron/packager/ package
|
||||
|
||||
- name: Upload [GitHub Actions]
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -95,15 +96,19 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
artifact:
|
||||
- path: "*Linux_64bit.zip"
|
||||
name: Linux_X86-64
|
||||
- path: "*macOS_64bit.dmg"
|
||||
name: macOS
|
||||
- path: "*Windows_64bit.exe"
|
||||
- path: '*Linux_64bit.zip'
|
||||
name: Linux_X86-64_zip
|
||||
- path: '*Linux_64bit.AppImage'
|
||||
name: Linux_X86-64_app_image
|
||||
- path: '*macOS_64bit.dmg'
|
||||
name: macOS_dmg
|
||||
- path: '*macOS_64bit.zip'
|
||||
name: macOS_zip
|
||||
- path: '*Windows_64bit.exe'
|
||||
name: Windows_X86-64_interactive_installer
|
||||
- path: "*Windows_64bit.msi"
|
||||
- path: '*Windows_64bit.msi'
|
||||
name: Windows_X86-64_MSI
|
||||
- path: "*Windows_64bit.zip"
|
||||
- path: '*Windows_64bit.zip'
|
||||
name: Windows_X86-64_zip
|
||||
|
||||
steps:
|
||||
@@ -112,7 +117,7 @@ jobs:
|
||||
with:
|
||||
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
|
||||
path: ${{ env.JOB_TRANSFER_ARTIFACT }}
|
||||
|
||||
|
||||
- name: Upload tester build artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
@@ -135,24 +140,24 @@ jobs:
|
||||
env:
|
||||
IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
run: |
|
||||
export LATEST_TAG=$(git describe --abbrev=0)
|
||||
export GIT_LOG=$(git log --pretty=" - %s [%h]" $LATEST_TAG..HEAD | sed 's/ *$//g')
|
||||
if [ "$IS_RELEASE" = true ]; then
|
||||
export BODY=$(echo -e "$GIT_LOG")
|
||||
else
|
||||
export LATEST_TAG_WITH_LINK=$(echo "[$LATEST_TAG](https://github.com/arduino/arduino-ide/releases/tag/$LATEST_TAG)")
|
||||
if [ -z "$GIT_LOG" ]; then
|
||||
export BODY="There were no changes since version $LATEST_TAG_WITH_LINK."
|
||||
else
|
||||
export BODY=$(echo -e "Changes since version $LATEST_TAG_WITH_LINK:\n$GIT_LOG")
|
||||
fi
|
||||
export LATEST_TAG=$(git describe --abbrev=0)
|
||||
export GIT_LOG=$(git log --pretty=" - %s [%h]" $LATEST_TAG..HEAD | sed 's/ *$//g')
|
||||
if [ "$IS_RELEASE" = true ]; then
|
||||
export BODY=$(echo -e "$GIT_LOG")
|
||||
else
|
||||
export LATEST_TAG_WITH_LINK=$(echo "[$LATEST_TAG](https://github.com/arduino/arduino-ide/releases/tag/$LATEST_TAG)")
|
||||
if [ -z "$GIT_LOG" ]; then
|
||||
export BODY="There were no changes since version $LATEST_TAG_WITH_LINK."
|
||||
else
|
||||
export BODY=$(echo -e "Changes since version $LATEST_TAG_WITH_LINK:\n$GIT_LOG")
|
||||
fi
|
||||
echo -e "$BODY"
|
||||
OUTPUT_SAFE_BODY="${BODY//'%'/'%25'}"
|
||||
OUTPUT_SAFE_BODY="${OUTPUT_SAFE_BODY//$'\n'/'%0A'}"
|
||||
OUTPUT_SAFE_BODY="${OUTPUT_SAFE_BODY//$'\r'/'%0D'}"
|
||||
echo "::set-output name=BODY::$OUTPUT_SAFE_BODY"
|
||||
echo "$BODY" > CHANGELOG.txt
|
||||
fi
|
||||
echo -e "$BODY"
|
||||
OUTPUT_SAFE_BODY="${BODY//'%'/'%25'}"
|
||||
OUTPUT_SAFE_BODY="${OUTPUT_SAFE_BODY//$'\n'/'%0A'}"
|
||||
OUTPUT_SAFE_BODY="${OUTPUT_SAFE_BODY//$'\r'/'%0D'}"
|
||||
echo "::set-output name=BODY::$OUTPUT_SAFE_BODY"
|
||||
echo "$BODY" > CHANGELOG.txt
|
||||
|
||||
- name: Upload Changelog [GitHub Actions]
|
||||
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')
|
||||
@@ -175,9 +180,9 @@ jobs:
|
||||
- name: Publish Nightly [S3]
|
||||
uses: docker://plugins/s3
|
||||
env:
|
||||
PLUGIN_SOURCE: "${{ env.JOB_TRANSFER_ARTIFACT }}/*"
|
||||
PLUGIN_STRIP_PREFIX: "${{ env.JOB_TRANSFER_ARTIFACT }}/"
|
||||
PLUGIN_TARGET: "/arduino-ide/nightly"
|
||||
PLUGIN_SOURCE: '${{ env.JOB_TRANSFER_ARTIFACT }}/*'
|
||||
PLUGIN_STRIP_PREFIX: '${{ env.JOB_TRANSFER_ARTIFACT }}/'
|
||||
PLUGIN_TARGET: '/arduino-ide/nightly'
|
||||
PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -211,9 +216,9 @@ jobs:
|
||||
- name: Publish Release [S3]
|
||||
uses: docker://plugins/s3
|
||||
env:
|
||||
PLUGIN_SOURCE: "${{ env.JOB_TRANSFER_ARTIFACT }}/*"
|
||||
PLUGIN_STRIP_PREFIX: "${{ env.JOB_TRANSFER_ARTIFACT }}/"
|
||||
PLUGIN_TARGET: "/arduino-ide"
|
||||
PLUGIN_SOURCE: '${{ env.JOB_TRANSFER_ARTIFACT }}/*'
|
||||
PLUGIN_STRIP_PREFIX: '${{ env.JOB_TRANSFER_ARTIFACT }}/'
|
||||
PLUGIN_TARGET: '/arduino-ide'
|
||||
PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
|
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
|
||||
|
45
.github/workflows/compose-full-changelog.yaml
vendored
Normal file
45
.github/workflows/compose-full-changelog.yaml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: Compose full changelog
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created, edited]
|
||||
|
||||
env:
|
||||
CHANGELOG_ARTIFACTS: changelog
|
||||
|
||||
jobs:
|
||||
create-changelog:
|
||||
if: github.repository == 'arduino/arduino-ide'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get Tag
|
||||
id: tag_name
|
||||
run: |
|
||||
echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/}
|
||||
|
||||
- name: Create full changelog
|
||||
id: full-changelog
|
||||
run: |
|
||||
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"
|
||||
|
||||
# Create manifest file pointing to latest changelog file name
|
||||
echo "$CHANGELOG_FILE_NAME" >> "${{ github.workspace }}/${{ env.CHANGELOG_ARTIFACTS }}/latest.txt"
|
||||
|
||||
# Compose changelog
|
||||
yarn run compose-changelog "${{ github.workspace }}/${{ env.CHANGELOG_ARTIFACTS }}/$CHANGELOG_FILE_NAME"
|
||||
|
||||
- name: Publish Changelog [S3]
|
||||
uses: docker://plugins/s3
|
||||
env:
|
||||
PLUGIN_SOURCE: '${{ env.CHANGELOG_ARTIFACTS }}/*'
|
||||
PLUGIN_STRIP_PREFIX: '${{ env.CHANGELOG_ARTIFACTS }}/'
|
||||
PLUGIN_TARGET: '/arduino-ide/changelog'
|
||||
PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
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
|
||||
|
4
.github/workflows/sync-labels.yml
vendored
4
.github/workflows/sync-labels.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
|
||||
- name: Download JSON schema for labels configuration file
|
||||
id: download-schema
|
||||
uses: carlosperate/download-file-action@v1.0.3
|
||||
uses: carlosperate/download-file-action@v1
|
||||
with:
|
||||
file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/arduino-tooling-gh-label-configuration-schema.json
|
||||
location: ${{ runner.temp }}/label-configuration-schema
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Download
|
||||
uses: carlosperate/download-file-action@v1.0.3
|
||||
uses: carlosperate/download-file-action@v1
|
||||
with:
|
||||
file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/${{ matrix.filename }}
|
||||
|
||||
|
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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
37
BUILDING.md
37
BUILDING.md
@@ -40,22 +40,31 @@ The _frontend_ is running as an Electron renderer process and can invoke service
|
||||
## Build from source
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
### Build
|
||||
```sh
|
||||
yarn
|
||||
```
|
||||
Once you have all the tools installed, you can build the editor following these steps
|
||||
|
||||
### Rebuild the native dependencies
|
||||
```sh
|
||||
yarn rebuild:electron
|
||||
```
|
||||
1. Install the dependencies and build
|
||||
```sh
|
||||
yarn
|
||||
```
|
||||
|
||||
### Start
|
||||
```sh
|
||||
yarn start
|
||||
```
|
||||
2. Rebuild the dependencies
|
||||
```sh
|
||||
yarn rebuild:browser
|
||||
```
|
||||
|
||||
3. Rebuild the electron dependencies
|
||||
```sh
|
||||
yarn rebuild:electron
|
||||
```
|
||||
|
||||
4. Start the application
|
||||
```sh
|
||||
yarn start
|
||||
```
|
||||
|
||||
### CI
|
||||
|
||||
@@ -117,7 +126,7 @@ git add . \
|
||||
git tag -a 0.2.0 -m "0.2.0" \
|
||||
&& git push origin 0.2.0
|
||||
```
|
||||
- The release build starts automatically and uploads the artifacts with the changelog to the [release page](https://github.com/arduino/arduino-ide/releases).
|
||||
- The release build starts automatically and uploads the artifacts with the changelog to the [release page](https://github.com/arduino/arduino-ide/releases).
|
||||
- If you do not want to release the `EXE` and `MSI` installers, wipe them manually.
|
||||
- If you do not like the generated changelog, modify it and update the GH release.
|
||||
|
||||
|
42
README.md
42
README.md
@@ -15,29 +15,30 @@ The Arduino IDE 2.x is a major rewrite, sharing no code with the IDE 1.x. It is
|
||||
## Download
|
||||
|
||||
You can download the latest version from the [software download page on the Arduino website](https://www.arduino.cc/en/software#experimental-software).
|
||||
|
||||
### Nightly builds
|
||||
|
||||
These builds are generated every day at 03:00 GMT from the `main` branch and
|
||||
should be considered unstable:
|
||||
|
||||
Platform | 32 bit | 64 bit |
|
||||
--------- | ------------------------ | ------------------------------------------------------------------------------------------------------ |
|
||||
Linux | | [Nightly Linux 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] |
|
||||
| Platform | 32 bit | 64 bit |
|
||||
| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------ |
|
||||
| Linux | | [Nightly Linux 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 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
|
||||
[Nightly macOS 64 bit]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_macOS_64bit.dmg
|
||||
[🚧 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 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
|
||||
[nightly macos 64 bit]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_macOS_64bit.dmg
|
||||
|
||||
> These links return an HTTP `302: Found` response, redirecting to latest
|
||||
generated builds by replacing `latest` with the latest available build
|
||||
date, using the format YYYYMMDD (i.e for 2019/Aug/06 `latest` is
|
||||
replaced with `20190806`)
|
||||
> generated builds by replacing `latest` with the latest available build
|
||||
> date, using the format YYYYMMDD (i.e for 2019/Aug/06 `latest` is
|
||||
> replaced with `20190806`)
|
||||
|
||||
## Support
|
||||
|
||||
@@ -47,8 +48,8 @@ If you need assistance, see the [Help Center](https://support.arduino.cc/hc/en-u
|
||||
|
||||
If you want to report an issue, you can submit it to the [issue tracker](https://github.com/arduino/arduino-ide/issues) of this repository. A few rules apply:
|
||||
|
||||
* Before posting, please check if the same problem has been already reported by someone else to avoid duplicates.
|
||||
* Remember to include as much detail as you can about your hardware set-up, code and steps for reproducing the issue. Make sure you're using an original Arduino board.
|
||||
- Before posting, please check if the same problem has been already reported by someone else to avoid duplicates.
|
||||
- Remember to include as much detail as you can about your hardware set-up, code and steps for reproducing the issue. Make sure you're using an original Arduino board.
|
||||
|
||||
### Security
|
||||
|
||||
@@ -64,10 +65,13 @@ Contributions are very welcome! You can browse the list of open issues to see wh
|
||||
|
||||
This repository contains the main code, but two more repositories are included during the build process:
|
||||
|
||||
* [vscode-arduino-tools](https://github.com/arduino/vscode-arduino-tools): provides support for the language server and the debugger
|
||||
* [arduino-language-server](https://github.com/arduino/arduino-language-server): provides the language server that parses Arduino code
|
||||
- [vscode-arduino-tools](https://github.com/arduino/vscode-arduino-tools): provides support for the language server and the debugger
|
||||
- [arduino-language-server](https://github.com/arduino/arduino-language-server): provides the language server that parses Arduino code
|
||||
|
||||
See the [BUILDING.md](BUILDING.md) for a technical overview of the application and instructions for building the code.
|
||||
|
||||
You can help with the translation of the Arduino IDE to your language here: [Arduino IDE on Transifex](https://www.transifex.com/arduino-1/ide2/dashboard/).
|
||||
|
||||
## Donations
|
||||
|
||||
This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [donating](https://www.arduino.cc/en/donate/) or [sponsoring](https://github.com/sponsors/arduino) to support our work, as well as [buying original Arduino boards](https://store.arduino.cc/) which is the best way to make sure our effort can continue in the long term.
|
||||
|
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"name": "arduino-ide-extension",
|
||||
"version": "2.0.0-rc2",
|
||||
"version": "2.0.0-rc4",
|
||||
"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",
|
||||
"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",
|
||||
@@ -20,22 +21,23 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.3.7",
|
||||
"@theia/application-package": "1.19.0",
|
||||
"@theia/core": "1.19.0",
|
||||
"@theia/editor": "1.19.0",
|
||||
"@theia/editor-preview": "1.19.0",
|
||||
"@theia/filesystem": "1.19.0",
|
||||
"@theia/git": "1.19.0",
|
||||
"@theia/keymaps": "1.19.0",
|
||||
"@theia/markers": "1.19.0",
|
||||
"@theia/monaco": "1.19.0",
|
||||
"@theia/navigator": "1.19.0",
|
||||
"@theia/outline-view": "1.19.0",
|
||||
"@theia/output": "1.19.0",
|
||||
"@theia/preferences": "1.19.0",
|
||||
"@theia/search-in-workspace": "1.19.0",
|
||||
"@theia/terminal": "1.19.0",
|
||||
"@theia/workspace": "1.19.0",
|
||||
"@theia/application-package": "1.22.1",
|
||||
"@theia/core": "1.22.1",
|
||||
"@theia/editor": "1.22.1",
|
||||
"@theia/editor-preview": "1.22.1",
|
||||
"@theia/electron": "1.22.1",
|
||||
"@theia/filesystem": "1.22.1",
|
||||
"@theia/git": "1.22.1",
|
||||
"@theia/keymaps": "1.22.1",
|
||||
"@theia/markers": "1.22.1",
|
||||
"@theia/monaco": "1.22.1",
|
||||
"@theia/navigator": "1.22.1",
|
||||
"@theia/outline-view": "1.22.1",
|
||||
"@theia/output": "1.22.1",
|
||||
"@theia/preferences": "1.22.1",
|
||||
"@theia/search-in-workspace": "1.22.1",
|
||||
"@theia/terminal": "1.22.1",
|
||||
"@theia/workspace": "1.22.1",
|
||||
"@tippyjs/react": "^4.2.5",
|
||||
"@types/atob": "^2.1.2",
|
||||
"@types/auth0-js": "^9.14.0",
|
||||
@@ -55,7 +57,7 @@
|
||||
"@types/temp": "^0.8.34",
|
||||
"@types/which": "^1.3.1",
|
||||
"ajv": "^6.5.3",
|
||||
"arduino-serial-plotter-webapp": "0.0.15",
|
||||
"arduino-serial-plotter-webapp": "0.0.17",
|
||||
"async-mutex": "^0.3.0",
|
||||
"atob": "^2.1.2",
|
||||
"auth0-js": "^9.14.0",
|
||||
@@ -63,6 +65,7 @@
|
||||
"css-element-queries": "^1.2.0",
|
||||
"dateformat": "^3.0.3",
|
||||
"deepmerge": "2.0.1",
|
||||
"electron-updater": "^4.6.5",
|
||||
"fuzzy": "^0.1.3",
|
||||
"glob": "^7.1.6",
|
||||
"google-protobuf": "^3.11.4",
|
||||
@@ -80,6 +83,7 @@
|
||||
"ps-tree": "^1.2.0",
|
||||
"query-string": "^7.0.1",
|
||||
"react-disable": "^0.1.0",
|
||||
"react-markdown": "^8.0.0",
|
||||
"react-select": "^3.0.4",
|
||||
"react-tabs": "^3.1.2",
|
||||
"react-window": "^1.8.6",
|
||||
@@ -92,6 +96,7 @@
|
||||
"which": "^1.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"@types/chai": "^4.2.7",
|
||||
"@types/chai-string": "^1.4.2",
|
||||
"@types/mocha": "^5.2.7",
|
||||
@@ -151,10 +156,16 @@
|
||||
],
|
||||
"arduino": {
|
||||
"cli": {
|
||||
"version": "0.20.2"
|
||||
"version": "0.21.0"
|
||||
},
|
||||
"fwuploader": {
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"clangd": {
|
||||
"version": "13.0.0"
|
||||
},
|
||||
"languageServer": {
|
||||
"version": "0.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
116
arduino-ide-extension/scripts/compose-changelog.js
Executable file
116
arduino-ide-extension/scripts/compose-changelog.js
Executable file
@@ -0,0 +1,116 @@
|
||||
// @ts-check
|
||||
|
||||
(async () => {
|
||||
const { Octokit } = require('@octokit/rest');
|
||||
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 releases = response.data;
|
||||
|
||||
let fullChangelog = releases.reduce((acc, item, index) => {
|
||||
// Process each line separately
|
||||
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}${
|
||||
index !== releases.length - 1 ? '\n\n---\n\n' : '\n'
|
||||
}`
|
||||
);
|
||||
}, '');
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length == 0) {
|
||||
console.error('Missing argument to destination file');
|
||||
process.exit(1);
|
||||
}
|
||||
const changelogFile = path.resolve(args[0]);
|
||||
|
||||
await fs.writeFile(
|
||||
changelogFile,
|
||||
fullChangelog,
|
||||
{
|
||||
flag: 'w+',
|
||||
},
|
||||
(err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
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.
|
||||
const processLine = (line) => {
|
||||
// Check if a link with one of the following format exists:
|
||||
// * [#123](https://github.com/arduino/arduino-ide/pull/123)
|
||||
// * [#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/)
|
||||
// If it does return the line as is.
|
||||
let r =
|
||||
/(\(|\[)#\d+(\)|\])(\(|\[)https:\/\/github\.com\/arduino\/arduino-ide\/(pull|issues)\/(\d+)\/?(\)|\])/gm;
|
||||
if (r.test(line)) {
|
||||
return line;
|
||||
}
|
||||
|
||||
// Check if a issue or PR link with the following format exists:
|
||||
// * #123
|
||||
// If it does it's changed to:
|
||||
// * [#123](https://github.com/arduino/arduino-ide/pull/123)
|
||||
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)`
|
||||
);
|
||||
}
|
||||
|
||||
// Check if a link with one of the following format exists:
|
||||
// * https://github.com/arduino/arduino-ide/pull/123
|
||||
// * https://github.com/arduino/arduino-ide/issues/123
|
||||
// * https://github.com/arduino/arduino-ide/pull/123/
|
||||
// * https://github.com/arduino/arduino-ide/issues/123/
|
||||
// If it does it's changed respectively to:
|
||||
// * [#123](https://github.com/arduino/arduino-ide/pull/123)
|
||||
// * [#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;
|
||||
if (r.test(line)) {
|
||||
return line.replace(r, `[#$3]($1)`);
|
||||
}
|
||||
|
||||
// Check if a link with the following format exists:
|
||||
// * https://github.com/arduino/arduino-ide/compare/2.0.0-rc2...2.0.0-rc3
|
||||
// * 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;
|
||||
if (r.test(line)) {
|
||||
return line.replace(r, '[`$2`]($1)');
|
||||
}
|
||||
|
||||
// If nothing matches just return the line as is
|
||||
return line;
|
||||
};
|
@@ -4,13 +4,38 @@
|
||||
// - https://downloads.arduino.cc/arduino-language-server/clangd/clangd_${VERSION}_${SUFFIX}
|
||||
|
||||
(() => {
|
||||
const DEFAULT_ALS_VERSION = '0.5.0';
|
||||
const DEFAULT_CLANGD_VERSION = 'snapshot_20210124';
|
||||
|
||||
const path = require('path');
|
||||
const shell = require('shelljs');
|
||||
const downloader = require('./downloader');
|
||||
|
||||
const [DEFAULT_ALS_VERSION, DEFAULT_CLANGD_VERSION] = (() => {
|
||||
const pkg = require(path.join(__dirname, '..', 'package.json'));
|
||||
if (!pkg) return undefined;
|
||||
|
||||
const { arduino } = pkg;
|
||||
if (!arduino) return undefined;
|
||||
|
||||
const { languageServer, clangd } = arduino;
|
||||
if (!languageServer) return undefined;
|
||||
if (!clangd) return undefined;
|
||||
|
||||
return [languageServer.version, clangd.version];
|
||||
})();
|
||||
|
||||
if (!DEFAULT_ALS_VERSION) {
|
||||
shell.echo(
|
||||
`Could not retrieve Arduino Language Server version info from the 'package.json'.`
|
||||
);
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
if (!DEFAULT_CLANGD_VERSION) {
|
||||
shell.echo(
|
||||
`Could not retrieve clangd version info from the 'package.json'.`
|
||||
);
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
const yargs = require('yargs')
|
||||
.option('ls-version', {
|
||||
alias: 'lv',
|
||||
@@ -20,7 +45,7 @@
|
||||
.option('clangd-version', {
|
||||
alias: 'cv',
|
||||
default: DEFAULT_CLANGD_VERSION,
|
||||
choices: ['snapshot_20210124'],
|
||||
choices: [DEFAULT_CLANGD_VERSION, 'snapshot_20210124'],
|
||||
describe: `The version of 'clangd' to download. Defaults to ${DEFAULT_CLANGD_VERSION}.`,
|
||||
})
|
||||
.option('force-download', {
|
||||
@@ -35,32 +60,32 @@
|
||||
const clangdVersion = yargs['clangd-version'];
|
||||
const force = yargs['force-download'];
|
||||
const { platform, arch } = process;
|
||||
|
||||
const platformArch = platform + '-' + arch;
|
||||
const build = path.join(__dirname, '..', 'build');
|
||||
const lsExecutablePath = path.join(
|
||||
build,
|
||||
`arduino-language-server${platform === 'win32' ? '.exe' : ''}`
|
||||
);
|
||||
let clangdExecutablePath, lsSuffix, clangdSuffix;
|
||||
|
||||
let clangdExecutablePath, lsSuffix, clangdPrefix;
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
clangdExecutablePath = path.join(build, 'bin', 'clangd');
|
||||
switch (platformArch) {
|
||||
case 'darwin-x64':
|
||||
clangdExecutablePath = path.join(build, 'clangd');
|
||||
lsSuffix = 'macOS_64bit.tar.gz';
|
||||
clangdPrefix = 'mac';
|
||||
clangdSuffix = 'macOS_64bit';
|
||||
break;
|
||||
case 'linux':
|
||||
clangdExecutablePath = path.join(build, 'bin', 'clangd');
|
||||
case 'linux-x64':
|
||||
clangdExecutablePath = path.join(build, 'clangd');
|
||||
lsSuffix = 'Linux_64bit.tar.gz';
|
||||
clangdPrefix = 'linux';
|
||||
clangdSuffix = 'Linux_64bit';
|
||||
break;
|
||||
case 'win32':
|
||||
clangdExecutablePath = path.join(build, 'bin', 'clangd.exe');
|
||||
case 'win32-x64':
|
||||
clangdExecutablePath = path.join(build, 'clangd.exe');
|
||||
lsSuffix = 'Windows_64bit.zip';
|
||||
clangdPrefix = 'windows';
|
||||
clangdSuffix = 'Windows_64bit';
|
||||
break;
|
||||
}
|
||||
if (!lsSuffix) {
|
||||
if (!lsSuffix || !clangdSuffix) {
|
||||
shell.echo(
|
||||
`The arduino-language-server is not available for ${platform} ${arch}.`
|
||||
);
|
||||
@@ -74,7 +99,7 @@
|
||||
}_${lsSuffix}`;
|
||||
downloader.downloadUnzipAll(alsUrl, build, lsExecutablePath, force);
|
||||
|
||||
const clangdUrl = `https://downloads.arduino.cc/arduino-language-server/clangd/clangd-${clangdPrefix}-${clangdVersion}.zip`;
|
||||
const clangdUrl = `https://downloads.arduino.cc/tools/clangd_${clangdVersion}_${clangdSuffix}.tar.bz2`;
|
||||
downloader.downloadUnzipAll(clangdUrl, build, clangdExecutablePath, force, {
|
||||
strip: 1,
|
||||
}); // `strip`: the new clangd (12.x) is zipped into a folder, so we have to strip the outmost folder.
|
||||
|
@@ -5,16 +5,17 @@ const download = require('download');
|
||||
const decompress = require('decompress');
|
||||
const unzip = require('decompress-unzip');
|
||||
const untargz = require('decompress-targz');
|
||||
const untarbz2 = require('decompress-tarbz2');
|
||||
|
||||
process.on('unhandledRejection', (reason, _) => {
|
||||
shell.echo(String(reason));
|
||||
shell.exit(1);
|
||||
throw reason;
|
||||
shell.echo(String(reason));
|
||||
shell.exit(1);
|
||||
throw reason;
|
||||
});
|
||||
process.on('uncaughtException', error => {
|
||||
shell.echo(String(error));
|
||||
shell.exit(1);
|
||||
throw error;
|
||||
process.on('uncaughtException', (error) => {
|
||||
shell.echo(String(error));
|
||||
shell.exit(1);
|
||||
throw error;
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -23,55 +24,62 @@ process.on('uncaughtException', error => {
|
||||
* @param filePrefix {string} Prefix of the file name found in the archive
|
||||
* @param force {boolean} Whether to download even if the target file exists. `false` by default.
|
||||
*/
|
||||
exports.downloadUnzipFile = async (url, targetFile, filePrefix, force = false) => {
|
||||
if (fs.existsSync(targetFile) && !force) {
|
||||
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(path.dirname(targetFile))) {
|
||||
if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) {
|
||||
shell.echo('Could not create new directory.');
|
||||
shell.exit(1);
|
||||
}
|
||||
exports.downloadUnzipFile = async (
|
||||
url,
|
||||
targetFile,
|
||||
filePrefix,
|
||||
force = false
|
||||
) => {
|
||||
if (fs.existsSync(targetFile) && !force) {
|
||||
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(path.dirname(targetFile))) {
|
||||
if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) {
|
||||
shell.echo('Could not create new directory.');
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const downloads = path.join(__dirname, '..', 'downloads');
|
||||
if (shell.rm('-rf', targetFile, downloads).code !== 0) {
|
||||
shell.exit(1);
|
||||
}
|
||||
const downloads = path.join(__dirname, '..', 'downloads');
|
||||
if (shell.rm('-rf', targetFile, downloads).code !== 0) {
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
shell.echo(`>>> Downloading from '${url}'...`);
|
||||
const data = await download(url);
|
||||
shell.echo(`<<< Download succeeded.`);
|
||||
shell.echo(`>>> Downloading from '${url}'...`);
|
||||
const data = await download(url);
|
||||
shell.echo(`<<< Download succeeded.`);
|
||||
|
||||
shell.echo('>>> Decompressing...');
|
||||
const files = await decompress(data, downloads, {
|
||||
plugins: [
|
||||
unzip(),
|
||||
untargz()
|
||||
]
|
||||
});
|
||||
if (files.length === 0) {
|
||||
shell.echo('Error ocurred while decompressing the archive.');
|
||||
shell.exit(1);
|
||||
}
|
||||
const fileIndex = files.findIndex(f => f.path.startsWith(filePrefix));
|
||||
if (fileIndex === -1) {
|
||||
shell.echo(`The downloaded artifact does not contain any file with prefix ${filePrefix}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo('<<< Decompressing succeeded.');
|
||||
shell.echo('>>> Decompressing...');
|
||||
const files = await decompress(data, downloads, {
|
||||
plugins: [unzip(), untargz(), untarbz2()],
|
||||
});
|
||||
if (files.length === 0) {
|
||||
shell.echo('Error ocurred while decompressing the archive.');
|
||||
shell.exit(1);
|
||||
}
|
||||
const fileIndex = files.findIndex((f) => f.path.startsWith(filePrefix));
|
||||
if (fileIndex === -1) {
|
||||
shell.echo(
|
||||
`The downloaded artifact does not contain any file with prefix ${filePrefix}.`
|
||||
);
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo('<<< Decompressing succeeded.');
|
||||
|
||||
if (shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile).code !== 0) {
|
||||
shell.echo(`Could not move file to target path: ${targetFile}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
if (!fs.existsSync(targetFile)) {
|
||||
shell.echo(`Could not find file: ${targetFile}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo(`Done: ${targetFile}`);
|
||||
}
|
||||
if (
|
||||
shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile)
|
||||
.code !== 0
|
||||
) {
|
||||
shell.echo(`Could not move file to target path: ${targetFile}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
if (!fs.existsSync(targetFile)) {
|
||||
shell.echo(`Could not find file: ${targetFile}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo(`Done: ${targetFile}`);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param url {string} Download URL
|
||||
@@ -79,42 +87,45 @@ exports.downloadUnzipFile = async (url, targetFile, filePrefix, force = false) =
|
||||
* @param targetFile {string} Path to the main file expected after decompressing
|
||||
* @param force {boolean} Whether to download even if the target file exists
|
||||
*/
|
||||
exports.downloadUnzipAll = async (url, targetDir, targetFile, force, decompressOptions = undefined) => {
|
||||
if (fs.existsSync(targetFile) && !force) {
|
||||
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(targetDir)) {
|
||||
if (shell.mkdir('-p', targetDir).code !== 0) {
|
||||
shell.echo('Could not create new directory.');
|
||||
shell.exit(1);
|
||||
}
|
||||
exports.downloadUnzipAll = async (
|
||||
url,
|
||||
targetDir,
|
||||
targetFile,
|
||||
force,
|
||||
decompressOptions = undefined
|
||||
) => {
|
||||
if (fs.existsSync(targetFile) && !force) {
|
||||
shell.echo(`Skipping download because file already exists: ${targetFile}`);
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(targetDir)) {
|
||||
if (shell.mkdir('-p', targetDir).code !== 0) {
|
||||
shell.echo('Could not create new directory.');
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
shell.echo(`>>> Downloading from '${url}'...`);
|
||||
const data = await download(url);
|
||||
shell.echo(`<<< Download succeeded.`);
|
||||
shell.echo(`>>> Downloading from '${url}'...`);
|
||||
const data = await download(url);
|
||||
shell.echo(`<<< Download succeeded.`);
|
||||
|
||||
shell.echo('>>> Decompressing...');
|
||||
let options = {
|
||||
plugins: [
|
||||
unzip(),
|
||||
untargz()
|
||||
]
|
||||
};
|
||||
if (decompressOptions) {
|
||||
options = Object.assign(options, decompressOptions)
|
||||
}
|
||||
const files = await decompress(data, targetDir, options);
|
||||
if (files.length === 0) {
|
||||
shell.echo('Error ocurred while decompressing the archive.');
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo('<<< Decompressing succeeded.');
|
||||
shell.echo('>>> Decompressing...');
|
||||
let options = {
|
||||
plugins: [unzip(), untargz(), untarbz2()],
|
||||
};
|
||||
if (decompressOptions) {
|
||||
options = Object.assign(options, decompressOptions);
|
||||
}
|
||||
const files = await decompress(data, targetDir, options);
|
||||
if (files.length === 0) {
|
||||
shell.echo('Error ocurred while decompressing the archive.');
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo('<<< Decompressing succeeded.');
|
||||
|
||||
if (!fs.existsSync(targetFile)) {
|
||||
shell.echo(`Could not find file: ${targetFile}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo(`Done: ${targetFile}`);
|
||||
}
|
||||
if (!fs.existsSync(targetFile)) {
|
||||
shell.echo(`Could not find file: ${targetFile}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
shell.echo(`Done: ${targetFile}`);
|
||||
};
|
||||
|
@@ -1,9 +1,8 @@
|
||||
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,
|
||||
Port,
|
||||
SketchesService,
|
||||
ExecutableService,
|
||||
Sketch,
|
||||
@@ -69,8 +68,11 @@ import { ArduinoPreferences } from './arduino-preferences';
|
||||
import { SketchesServiceClientImpl } from '../common/protocol/sketches-service-client-impl';
|
||||
import { SaveAsSketch } from './contributions/save-as-sketch';
|
||||
import { SketchbookWidgetContribution } from './widgets/sketchbook/sketchbook-widget-contribution';
|
||||
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
|
||||
import { IDEUpdater } from '../common/protocol/ide-updater';
|
||||
|
||||
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
|
||||
export const SKIP_IDE_VERSION = 'skipIDEVersion';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoFrontendContribution
|
||||
@@ -79,8 +81,7 @@ export class ArduinoFrontendContribution
|
||||
TabBarToolbarContribution,
|
||||
CommandContribution,
|
||||
MenuContribution,
|
||||
ColorContribution
|
||||
{
|
||||
ColorContribution {
|
||||
@inject(ILogger)
|
||||
protected logger: ILogger;
|
||||
|
||||
@@ -158,6 +159,12 @@ export class ArduinoFrontendContribution
|
||||
@inject(LocalStorageService)
|
||||
protected readonly localStorageService: LocalStorageService;
|
||||
|
||||
@inject(IDEUpdater)
|
||||
protected readonly updater: IDEUpdater;
|
||||
|
||||
@inject(IDEUpdaterDialog)
|
||||
protected readonly updaterDialog: IDEUpdaterDialog;
|
||||
|
||||
protected invalidConfigPopup:
|
||||
| Promise<void | 'No' | 'Yes' | undefined>
|
||||
| undefined;
|
||||
@@ -216,7 +223,7 @@ export class ArduinoFrontendContribution
|
||||
? nls.localize(
|
||||
'arduino/common/selectedOn',
|
||||
'on {0}',
|
||||
Port.toString(selectedPort)
|
||||
selectedPort.address
|
||||
)
|
||||
: nls.localize('arduino/common/notConnected', '[not connected]'),
|
||||
className: 'arduino-selected-port',
|
||||
@@ -252,7 +259,7 @@ export class ArduinoFrontendContribution
|
||||
});
|
||||
}
|
||||
|
||||
onStart(app: FrontendApplication): void {
|
||||
async onStart(app: FrontendApplication): Promise<void> {
|
||||
// Initialize all `pro-mode` widgets. This is a NOOP if in normal mode.
|
||||
for (const viewContribution of [
|
||||
this.fileNavigatorContributions,
|
||||
@@ -267,6 +274,31 @@ export class ArduinoFrontendContribution
|
||||
viewContribution.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
|
||||
this.updater
|
||||
.init(
|
||||
this.arduinoPreferences.get('arduino.ide.updateChannel'),
|
||||
this.arduinoPreferences.get('arduino.ide.updateBaseUrl')
|
||||
)
|
||||
.then(() => this.updater.checkForUpdates(true))
|
||||
.then(async (updateInfo) => {
|
||||
if (!updateInfo) return;
|
||||
const versionToSkip = await this.localStorageService.getData<string>(
|
||||
SKIP_IDE_VERSION
|
||||
);
|
||||
if (versionToSkip === updateInfo.version) return;
|
||||
this.updaterDialog.open(updateInfo);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/errorCheckingForUpdates',
|
||||
'Error while checking for Arduino IDE updates.\n{0}',
|
||||
e.message
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
const start = async ({ selectedBoard }: BoardsConfig.Config) => {
|
||||
if (selectedBoard) {
|
||||
const { name, fqbn } = selectedBoard;
|
||||
@@ -277,11 +309,25 @@ export class ArduinoFrontendContribution
|
||||
};
|
||||
this.boardsServiceClientImpl.onBoardsConfigChanged(start);
|
||||
this.arduinoPreferences.onPreferenceChanged((event) => {
|
||||
if (
|
||||
event.preferenceName === 'arduino.language.log' &&
|
||||
event.newValue !== event.oldValue
|
||||
) {
|
||||
start(this.boardsServiceClientImpl.boardsConfig);
|
||||
if (event.newValue !== event.oldValue) {
|
||||
switch (event.preferenceName) {
|
||||
case 'arduino.language.log':
|
||||
start(this.boardsServiceClientImpl.boardsConfig);
|
||||
break;
|
||||
case 'arduino.window.zoomLevel':
|
||||
if (typeof event.newValue === 'number') {
|
||||
const webContents = remote.getCurrentWebContents();
|
||||
webContents.setZoomLevel(event.newValue || 0);
|
||||
}
|
||||
break;
|
||||
case 'arduino.ide.updateChannel':
|
||||
case 'arduino.ide.updateBaseUrl':
|
||||
this.updater.init(
|
||||
this.arduinoPreferences.get('arduino.ide.updateChannel'),
|
||||
this.arduinoPreferences.get('arduino.ide.updateBaseUrl')
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.arduinoPreferences.ready.then(() => {
|
||||
@@ -289,16 +335,7 @@ export class ArduinoFrontendContribution
|
||||
const zoomLevel = this.arduinoPreferences.get('arduino.window.zoomLevel');
|
||||
webContents.setZoomLevel(zoomLevel);
|
||||
});
|
||||
this.arduinoPreferences.onPreferenceChanged((event) => {
|
||||
if (
|
||||
event.preferenceName === 'arduino.window.zoomLevel' &&
|
||||
typeof event.newValue === 'number' &&
|
||||
event.newValue !== event.oldValue
|
||||
) {
|
||||
const webContents = remote.getCurrentWebContents();
|
||||
webContents.setZoomLevel(event.newValue || 0);
|
||||
}
|
||||
});
|
||||
|
||||
app.shell.leftPanelHandler.removeBottomMenu('settings-menu');
|
||||
}
|
||||
|
||||
|
@@ -262,6 +262,19 @@ import {
|
||||
UserFieldsDialogWidget,
|
||||
} from './dialogs/user-fields/user-fields-dialog';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { IDEUpdaterCommands } from './ide-updater/ide-updater-commands';
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
IDEUpdaterPath,
|
||||
} from '../common/protocol/ide-updater';
|
||||
import { IDEUpdaterClientImpl } from './ide-updater/ide-updater-client-impl';
|
||||
import {
|
||||
IDEUpdaterDialog,
|
||||
IDEUpdaterDialogProps,
|
||||
IDEUpdaterDialogWidget,
|
||||
} from './dialogs/ide-updater/ide-updater-dialog';
|
||||
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
|
||||
|
||||
const ElementQueries = require('css-element-queries/src/ElementQueries');
|
||||
|
||||
@@ -407,8 +420,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(SerialService)
|
||||
.toDynamicValue((context) => {
|
||||
const connection = context.container.get(WebSocketConnectionProvider);
|
||||
const client =
|
||||
context.container.get<SerialServiceClient>(SerialServiceClient);
|
||||
const client = context.container.get<SerialServiceClient>(
|
||||
SerialServiceClient
|
||||
);
|
||||
return connection.createProxy(SerialServicePath, client);
|
||||
})
|
||||
.inSingletonScope();
|
||||
@@ -472,12 +486,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
.inSingletonScope();
|
||||
rebind(TheiaEditorWidgetFactory).to(EditorWidgetFactory).inSingletonScope();
|
||||
rebind(TabBarToolbarFactory).toFactory(
|
||||
({ container: parentContainer }) =>
|
||||
() => {
|
||||
const container = parentContainer.createChild();
|
||||
container.bind(TabBarToolbar).toSelf().inSingletonScope();
|
||||
return container.get(TabBarToolbar);
|
||||
}
|
||||
({ container: parentContainer }) => () => {
|
||||
const container = parentContainer.createChild();
|
||||
container.bind(TabBarToolbar).toSelf().inSingletonScope();
|
||||
return container.get(TabBarToolbar);
|
||||
}
|
||||
);
|
||||
bind(OutputWidget).toSelf().inSingletonScope();
|
||||
rebind(TheiaOutputWidget).toService(OutputWidget);
|
||||
@@ -642,13 +655,15 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
|
||||
// Enable the dirty indicator on uncloseable widgets.
|
||||
rebind(TabBarRendererFactory).toFactory((context) => () => {
|
||||
const contextMenuRenderer =
|
||||
context.container.get<ContextMenuRenderer>(ContextMenuRenderer);
|
||||
const contextMenuRenderer = context.container.get<ContextMenuRenderer>(
|
||||
ContextMenuRenderer
|
||||
);
|
||||
const decoratorService = context.container.get<TabBarDecoratorService>(
|
||||
TabBarDecoratorService
|
||||
);
|
||||
const iconThemeService =
|
||||
context.container.get<IconThemeService>(IconThemeService);
|
||||
const iconThemeService = context.container.get<IconThemeService>(
|
||||
IconThemeService
|
||||
);
|
||||
return new TabBarRenderer(
|
||||
contextMenuRenderer,
|
||||
decoratorService,
|
||||
@@ -756,9 +771,32 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
title: 'UploadCertificate',
|
||||
});
|
||||
|
||||
bind(IDEUpdaterDialogWidget).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterDialog).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterDialogProps).toConstantValue({
|
||||
title: 'IDEUpdater',
|
||||
});
|
||||
|
||||
bind(UserFieldsDialogWidget).toSelf().inSingletonScope();
|
||||
bind(UserFieldsDialog).toSelf().inSingletonScope();
|
||||
bind(UserFieldsDialogProps).toConstantValue({
|
||||
title: 'UserFields',
|
||||
});
|
||||
|
||||
bind(IDEUpdaterCommands).toSelf().inSingletonScope();
|
||||
bind(CommandContribution).toService(IDEUpdaterCommands);
|
||||
|
||||
// Frontend binding for the IDE Updater service
|
||||
bind(IDEUpdaterClientImpl).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterClient).toService(IDEUpdaterClientImpl);
|
||||
bind(IDEUpdater)
|
||||
.toDynamicValue((context) => {
|
||||
const client = context.container.get(IDEUpdaterClientImpl);
|
||||
return ElectronIpcConnectionProvider.createProxy(
|
||||
context.container,
|
||||
IDEUpdaterPath,
|
||||
client
|
||||
);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
|
@@ -9,6 +9,11 @@ import {
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { CompilerWarningLiterals, CompilerWarnings } from '../common/protocol';
|
||||
|
||||
export enum UpdateChannel {
|
||||
Stable = 'stable',
|
||||
Nightly = 'nightly',
|
||||
}
|
||||
|
||||
export const ArduinoConfigSchema: PreferenceSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -64,13 +69,22 @@ export const ArduinoConfigSchema: PreferenceSchema = {
|
||||
),
|
||||
default: 0,
|
||||
},
|
||||
'arduino.ide.autoUpdate': {
|
||||
type: 'boolean',
|
||||
'arduino.ide.updateChannel': {
|
||||
type: 'string',
|
||||
enum: Object.values(UpdateChannel) as UpdateChannel[],
|
||||
default: UpdateChannel.Stable,
|
||||
description: nls.localize(
|
||||
'arduino/preferences/ide.autoUpdate',
|
||||
'True to enable automatic update checks. The IDE will check for updates automatically and periodically.'
|
||||
'arduino/preferences/ide.updateChannel',
|
||||
"Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build."
|
||||
),
|
||||
},
|
||||
'arduino.ide.updateBaseUrl': {
|
||||
type: 'string',
|
||||
default: 'https://downloads.arduino.cc/arduino-ide',
|
||||
description: nls.localize(
|
||||
'arduino/preferences/ide.updateBaseUrl',
|
||||
`The base URL where to download updates from. Defaults to 'https://downloads.arduino.cc/arduino-ide'`
|
||||
),
|
||||
default: true,
|
||||
},
|
||||
'arduino.board.certificates': {
|
||||
type: 'string',
|
||||
@@ -171,7 +185,8 @@ export interface ArduinoConfiguration {
|
||||
'arduino.upload.verify': boolean;
|
||||
'arduino.window.autoScale': boolean;
|
||||
'arduino.window.zoomLevel': number;
|
||||
'arduino.ide.autoUpdate': boolean;
|
||||
'arduino.ide.updateChannel': UpdateChannel;
|
||||
'arduino.ide.updateBaseUrl': string;
|
||||
'arduino.board.certificates': string;
|
||||
'arduino.sketchbook.showAllFiles': boolean;
|
||||
'arduino.cloud.enabled': boolean;
|
||||
@@ -188,16 +203,10 @@ export interface ArduinoConfiguration {
|
||||
export const ArduinoPreferences = Symbol('ArduinoPreferences');
|
||||
export type ArduinoPreferences = PreferenceProxy<ArduinoConfiguration>;
|
||||
|
||||
export function createArduinoPreferences(
|
||||
preferences: PreferenceService
|
||||
): ArduinoPreferences {
|
||||
return createPreferenceProxy(preferences, ArduinoConfigSchema);
|
||||
}
|
||||
|
||||
export function bindArduinoPreferences(bind: interfaces.Bind): void {
|
||||
bind(ArduinoPreferences).toDynamicValue((ctx) => {
|
||||
const preferences = ctx.container.get<PreferenceService>(PreferenceService);
|
||||
return createArduinoPreferences(preferences);
|
||||
return createPreferenceProxy(preferences, ArduinoConfigSchema);
|
||||
});
|
||||
bind(PreferenceContribution).toConstantValue({
|
||||
schema: ArduinoConfigSchema,
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { toUnix } from 'upath';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { URI } from '@theia/core/shared/vscode-uri';
|
||||
import { isWindows } from '@theia/core/lib/common/os';
|
||||
import { notEmpty } from '@theia/core/lib/common/objects';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
@@ -61,12 +60,8 @@ export class ArduinoWorkspaceRootResolver {
|
||||
// - https://github.com/eclipse-theia/theia/blob/8196e9dcf9c8de8ea0910efeb5334a974f426966/packages/workspace/src/browser/workspace-service.ts#L423
|
||||
protected hashToUri(hash: string | undefined): string | undefined {
|
||||
if (hash && hash.length > 1 && hash.startsWith('#')) {
|
||||
const path = hash.slice(1); // Trim the leading `#`.
|
||||
return new URI(
|
||||
toUnix(path.slice(isWindows && hash.startsWith('/') ? 1 : 0))
|
||||
)
|
||||
.withScheme('file')
|
||||
.toString();
|
||||
const path = decodeURI(hash.slice(1)).replace(/\\/g, '/'); // Trim the leading `#`, decode the URI and replace Windows separators
|
||||
return URI.file(path.slice(isWindows && hash.startsWith('/') ? 1 : 0)).toString();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
@@ -84,7 +84,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
|
||||
),
|
||||
nls.localize(
|
||||
'arduino/board/configDialog2',
|
||||
'If you only select a Board you will be able just to compile, but not to upload your sketch.'
|
||||
'If you only select a Board you will be able to compile, but not to upload your sketch.'
|
||||
),
|
||||
]) {
|
||||
const p = document.createElement('div');
|
||||
|
@@ -167,7 +167,7 @@ export class BoardsConfig extends React.Component<
|
||||
this.queryPorts(Promise.resolve(ports)).then(({ knownPorts }) => {
|
||||
let { selectedPort } = this.state;
|
||||
// If the currently selected port is not available anymore, unset the selected port.
|
||||
if (removedPorts.some((port) => Port.equals(port, selectedPort))) {
|
||||
if (removedPorts.some((port) => Port.sameAs(port, selectedPort))) {
|
||||
selectedPort = undefined;
|
||||
}
|
||||
this.setState({ knownPorts, selectedPort }, () =>
|
||||
@@ -213,11 +213,11 @@ export class BoardsConfig extends React.Component<
|
||||
} else if (left.protocol === right.protocol) {
|
||||
// We show ports, including those that have guessed
|
||||
// or unrecognized boards, so we must sort those too.
|
||||
const leftBoard = this.availableBoards.find((board) =>
|
||||
Port.sameAs(board.port, left)
|
||||
const leftBoard = this.availableBoards.find(
|
||||
(board) => board.port === left
|
||||
);
|
||||
const rightBoard = this.availableBoards.find((board) =>
|
||||
Port.sameAs(board.port, right)
|
||||
const rightBoard = this.availableBoards.find(
|
||||
(board) => board.port === right
|
||||
);
|
||||
if (leftBoard && !rightBoard) {
|
||||
return -1;
|
||||
@@ -348,10 +348,10 @@ export class BoardsConfig extends React.Component<
|
||||
<div className="ports list">
|
||||
{ports.map((port) => (
|
||||
<Item<Port>
|
||||
key={Port.toString(port)}
|
||||
key={`${port.id}`}
|
||||
item={port}
|
||||
label={Port.toString(port)}
|
||||
selected={Port.equals(this.state.selectedPort, port)}
|
||||
selected={Port.sameAs(this.state.selectedPort, port)}
|
||||
onClick={this.selectPort}
|
||||
/>
|
||||
))}
|
||||
@@ -410,7 +410,7 @@ export namespace BoardsConfig {
|
||||
return options.default;
|
||||
}
|
||||
const { name } = selectedBoard;
|
||||
return `${name}${port ? ' at ' + Port.toString(port) : ''}`;
|
||||
return `${name}${port ? ` at ${port.address}` : ''}`;
|
||||
}
|
||||
|
||||
export function setConfig(
|
||||
|
@@ -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 {
|
||||
|
@@ -185,8 +185,8 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
|
||||
const selectedAvailableBoard = AvailableBoard.is(selectedBoard)
|
||||
? selectedBoard
|
||||
: this._availableBoards.find((availableBoard) =>
|
||||
Board.sameAs(availableBoard, selectedBoard)
|
||||
);
|
||||
Board.sameAs(availableBoard, selectedBoard)
|
||||
);
|
||||
if (
|
||||
selectedAvailableBoard &&
|
||||
selectedAvailableBoard.selected &&
|
||||
@@ -230,7 +230,8 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
|
||||
)) {
|
||||
if (
|
||||
this.latestValidBoardsConfig.selectedBoard.fqbn === board.fqbn &&
|
||||
this.latestValidBoardsConfig.selectedBoard.name === board.name
|
||||
this.latestValidBoardsConfig.selectedBoard.name === board.name &&
|
||||
this.latestValidBoardsConfig.selectedPort.protocol === board.port?.protocol
|
||||
) {
|
||||
this.boardsConfig = {
|
||||
...this.latestValidBoardsConfig,
|
||||
@@ -244,7 +245,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
|
||||
}
|
||||
|
||||
set boardsConfig(config: BoardsConfig.Config) {
|
||||
this.doSetBoardsConfig(config);
|
||||
this.setBoardsConfig(config);
|
||||
this.saveState().finally(() =>
|
||||
this.reconcileAvailableBoards().finally(() =>
|
||||
this.onBoardsConfigChangedEmitter.fire(this._boardsConfig)
|
||||
@@ -256,7 +257,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
|
||||
return this._boardsConfig;
|
||||
}
|
||||
|
||||
protected doSetBoardsConfig(config: BoardsConfig.Config): void {
|
||||
protected setBoardsConfig(config: BoardsConfig.Config): void {
|
||||
this.logger.info('Board config changed: ', JSON.stringify(config));
|
||||
this._boardsConfig = config;
|
||||
this.latestBoardsConfig = this._boardsConfig;
|
||||
@@ -370,19 +371,19 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
|
||||
const find = (needle: Board & { port: Port }, haystack: AvailableBoard[]) =>
|
||||
haystack.find(
|
||||
(board) =>
|
||||
Board.equals(needle, board) && Port.equals(needle.port, board.port)
|
||||
Board.equals(needle, board) && Port.sameAs(needle.port, board.port)
|
||||
);
|
||||
const timeoutTask =
|
||||
!!timeout && timeout > 0
|
||||
? new Promise<void>((_, reject) =>
|
||||
setTimeout(
|
||||
() => reject(new Error(`Timeout after ${timeout} ms.`)),
|
||||
timeout
|
||||
)
|
||||
setTimeout(
|
||||
() => reject(new Error(`Timeout after ${timeout} ms.`)),
|
||||
timeout
|
||||
)
|
||||
)
|
||||
: new Promise<void>(() => {
|
||||
/* never */
|
||||
});
|
||||
/* never */
|
||||
});
|
||||
const waitUntilTask = new Promise<void>((resolve) => {
|
||||
let candidate = find(what, this.availableBoards);
|
||||
if (candidate) {
|
||||
@@ -409,7 +410,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
|
||||
Port.sameAs(port, this.boardsConfig.selectedPort)
|
||||
)
|
||||
) {
|
||||
this.doSetBoardsConfig({
|
||||
this.setBoardsConfig({
|
||||
selectedBoard: this.boardsConfig.selectedBoard,
|
||||
selectedPort: undefined,
|
||||
});
|
||||
@@ -533,9 +534,8 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
|
||||
|
||||
protected getLastSelectedBoardOnPortKey(port: Port | string): string {
|
||||
// TODO: we lose the port's `protocol` info (`serial`, `network`, etc.) here if the `port` is a `string`.
|
||||
return `last-selected-board-on-port:${
|
||||
typeof port === 'string' ? port : Port.toString(port)
|
||||
}`;
|
||||
return `last-selected-board-on-port:${typeof port === 'string' ? port : port.address
|
||||
}`;
|
||||
}
|
||||
|
||||
protected async loadState(): Promise<void> {
|
||||
|
28
arduino-ide-extension/src/browser/components/ProgressBar.tsx
Normal file
28
arduino-ide-extension/src/browser/components/ProgressBar.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export type ProgressBarProps = {
|
||||
percent?: number;
|
||||
showPercentage?: boolean;
|
||||
};
|
||||
|
||||
export default function ProgressBar({
|
||||
percent = 0,
|
||||
showPercentage = false,
|
||||
}: ProgressBarProps): React.ReactElement {
|
||||
const roundedPercent = Math.round(percent);
|
||||
return (
|
||||
<div className="progress-bar">
|
||||
<div className="progress-bar--outer">
|
||||
<div
|
||||
className="progress-bar--inner"
|
||||
style={{ width: `${roundedPercent}%` }}
|
||||
/>
|
||||
</div>
|
||||
{showPercentage && (
|
||||
<div className="progress-bar--percentage">
|
||||
<div className="progress-bar--percentage-text">{roundedPercent}%</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import * as moment from 'moment';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { isOSX, isWindows } from '@theia/core/lib/common/os';
|
||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
||||
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import {
|
||||
SketchContribution,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
|
||||
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import * as dateFormat from 'dateformat';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import {
|
||||
DisposableCollection,
|
||||
@@ -204,10 +204,9 @@ PID: ${PID}`;
|
||||
|
||||
const packageLabel =
|
||||
packageName +
|
||||
`${
|
||||
manuallyInstalled
|
||||
? nls.localize('arduino/board/inSketchbook', ' (in Sketchbook)')
|
||||
: ''
|
||||
`${manuallyInstalled
|
||||
? nls.localize('arduino/board/inSketchbook', ' (in Sketchbook)')
|
||||
: ''
|
||||
}`;
|
||||
// Platform submenu
|
||||
const platformMenuPath = [...boardsPackagesGroup, packageId];
|
||||
@@ -255,8 +254,8 @@ PID: ${PID}`;
|
||||
protocolOrder: number,
|
||||
ports: AvailablePorts
|
||||
) => {
|
||||
const addresses = Object.keys(ports);
|
||||
if (!addresses.length) {
|
||||
const portIDs = Object.keys(ports);
|
||||
if (!portIDs.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -279,27 +278,26 @@ PID: ${PID}`;
|
||||
|
||||
// First we show addresses with recognized boards connected,
|
||||
// then all the rest.
|
||||
const sortedAddresses = Object.keys(ports);
|
||||
sortedAddresses.sort((left: string, right: string): number => {
|
||||
const sortedIDs = Object.keys(ports).sort((left: string, right: string): number => {
|
||||
const [, leftBoards] = ports[left];
|
||||
const [, rightBoards] = ports[right];
|
||||
return rightBoards.length - leftBoards.length;
|
||||
});
|
||||
|
||||
for (let i = 0; i < sortedAddresses.length; i++) {
|
||||
const address = sortedAddresses[i];
|
||||
const [port, boards] = ports[address];
|
||||
let label = `${address}`;
|
||||
for (let i = 0; i < sortedIDs.length; i++) {
|
||||
const portID = sortedIDs[i];
|
||||
const [port, boards] = ports[portID];
|
||||
let label = `${port.address}`;
|
||||
if (boards.length) {
|
||||
const boardsList = boards.map((board) => board.name).join(', ');
|
||||
label = `${label} (${boardsList})`;
|
||||
}
|
||||
const id = `arduino-select-port--${address}`;
|
||||
const id = `arduino-select-port--${portID}`;
|
||||
const command = { id };
|
||||
const handler = {
|
||||
execute: () => {
|
||||
if (
|
||||
!Port.equals(
|
||||
!Port.sameAs(
|
||||
port,
|
||||
this.boardsServiceProvider.boardsConfig.selectedPort
|
||||
)
|
||||
@@ -312,7 +310,7 @@ PID: ${PID}`;
|
||||
}
|
||||
},
|
||||
isToggled: () =>
|
||||
Port.equals(
|
||||
Port.sameAs(
|
||||
port,
|
||||
this.boardsServiceProvider.boardsConfig.selectedPort
|
||||
),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { toArray } from '@phosphor/algorithm';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
||||
import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
|
||||
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
||||
|
@@ -13,6 +13,7 @@ import {
|
||||
KeybindingRegistry,
|
||||
} from './contribution';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { IDEUpdaterCommands } from '../ide-updater/ide-updater-commands';
|
||||
|
||||
@injectable()
|
||||
export class Help extends Contribution {
|
||||
@@ -115,6 +116,10 @@ export class Help extends Contribution {
|
||||
commandId: Help.Commands.VISIT_ARDUINO.id,
|
||||
order: '6',
|
||||
});
|
||||
registry.registerMenuAction(ArduinoMenus.HELP__FIND_GROUP, {
|
||||
commandId: IDEUpdaterCommands.CHECK_FOR_UPDATES.id,
|
||||
order: '7',
|
||||
});
|
||||
}
|
||||
|
||||
registerKeybindings(registry: KeybindingRegistry): void {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { Widget, ContextMenuRenderer } from '@theia/core/lib/browser';
|
||||
import {
|
||||
@@ -190,7 +190,7 @@ export class OpenSketch extends SketchContribution {
|
||||
],
|
||||
message: nls.localize(
|
||||
'arduino/sketch/movingMsg',
|
||||
'The file "{0}" needs to be inside a sketch folder named as "{1}".\nCreate this folder, move the file, and continue?',
|
||||
'The file "{0}" needs to be inside a sketch folder named "{1}".\nCreate this folder, move the file, and continue?',
|
||||
nameWithExt,
|
||||
name
|
||||
),
|
||||
|
@@ -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 {
|
||||
|
@@ -45,7 +45,7 @@ export namespace UploadFirmware {
|
||||
id: 'arduino-upload-firmware-open',
|
||||
label: nls.localize(
|
||||
'arduino/firmware/updater',
|
||||
'WiFi101 / WiFiNINA Firmware Updater'
|
||||
'WiFi101 / WiFiNINA Firmware Updater'
|
||||
),
|
||||
category: 'Arduino',
|
||||
};
|
||||
|
@@ -15,6 +15,47 @@ export namespace ResponseResultProvider {
|
||||
export const JSON: ResponseResultProvider = (response) => response.json();
|
||||
}
|
||||
|
||||
export function Utf8ArrayToStr(array: Uint8Array): string {
|
||||
let out, i, c;
|
||||
let char2, char3;
|
||||
|
||||
out = '';
|
||||
const len = array.length;
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
c = array[i++];
|
||||
switch (c >> 4) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
// 0xxxxxxx
|
||||
out += String.fromCharCode(c);
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
// 110x xxxx 10xx xxxx
|
||||
char2 = array[i++];
|
||||
out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
|
||||
break;
|
||||
case 14:
|
||||
// 1110 xxxx 10xx xxxx 10xx xxxx
|
||||
char2 = array[i++];
|
||||
char3 = array[i++];
|
||||
out += String.fromCharCode(
|
||||
((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
type ResourceType = 'f' | 'd';
|
||||
|
||||
@injectable()
|
||||
@@ -275,9 +316,7 @@ export class CreateApi {
|
||||
|
||||
// parse the secret file
|
||||
const secrets = (
|
||||
typeof content === 'string'
|
||||
? content
|
||||
: new TextDecoder().decode(content)
|
||||
typeof content === 'string' ? content : Utf8ArrayToStr(content)
|
||||
)
|
||||
.split(/\r?\n/)
|
||||
.reduce((prev, curr) => {
|
||||
@@ -341,7 +380,7 @@ export class CreateApi {
|
||||
const headers = await this.headers();
|
||||
|
||||
let data: string =
|
||||
typeof content === 'string' ? content : new TextDecoder().decode(content);
|
||||
typeof content === 'string' ? content : Utf8ArrayToStr(content);
|
||||
data = await this.toggleSecretsInclude(posixPath, data, 'remove');
|
||||
|
||||
const payload = { data: btoa(data) };
|
||||
|
@@ -201,7 +201,7 @@ export const FirmwareUploaderComponent = ({
|
||||
<i className="fa fa-info status-icon" />
|
||||
{nls.localize(
|
||||
'arduino/firmware/successfullyInstalled',
|
||||
'Firmware succesfully installed.'
|
||||
'Firmware successfully installed.'
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
@@ -0,0 +1,210 @@
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { shell } from 'electron';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { ProgressInfo, UpdateInfo } from '../../../common/protocol/ide-updater';
|
||||
import ProgressBar from '../../components/ProgressBar';
|
||||
|
||||
export type IDEUpdaterComponentProps = {
|
||||
updateInfo: UpdateInfo;
|
||||
windowService: WindowService;
|
||||
downloadFinished?: boolean;
|
||||
downloadStarted?: boolean;
|
||||
progress?: ProgressInfo;
|
||||
error?: Error;
|
||||
onDownload: () => void;
|
||||
onClose: () => void;
|
||||
onSkipVersion: () => void;
|
||||
onCloseAndInstall: () => void;
|
||||
};
|
||||
|
||||
export const IDEUpdaterComponent = ({
|
||||
updateInfo: { version, releaseNotes },
|
||||
downloadStarted = false,
|
||||
downloadFinished = false,
|
||||
windowService,
|
||||
progress,
|
||||
error,
|
||||
onDownload,
|
||||
onClose,
|
||||
onSkipVersion,
|
||||
onCloseAndInstall,
|
||||
}: IDEUpdaterComponentProps): React.ReactElement => {
|
||||
const changelogDivRef = React.useRef() as React.MutableRefObject<
|
||||
HTMLDivElement
|
||||
>;
|
||||
React.useEffect(() => {
|
||||
if (!!releaseNotes) {
|
||||
let changelog: string;
|
||||
if (typeof releaseNotes === 'string') changelog = releaseNotes;
|
||||
else
|
||||
changelog = releaseNotes.reduce((acc, item) => {
|
||||
return item.note ? (acc += `${item.note}\n\n`) : acc;
|
||||
}, '');
|
||||
ReactDOM.render(
|
||||
<ReactMarkdown
|
||||
components={{
|
||||
a: ({ href, children, ...props }) => (
|
||||
<a onClick={() => href && shell.openExternal(href)} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{changelog}
|
||||
</ReactMarkdown>,
|
||||
changelogDivRef.current
|
||||
);
|
||||
}
|
||||
}, [releaseNotes]);
|
||||
const closeButton = (
|
||||
<button onClick={onClose} type="button" className="theia-button secondary">
|
||||
{nls.localize('arduino/ide-updater/notNowButton', 'Not now')}
|
||||
</button>
|
||||
);
|
||||
|
||||
const DownloadCompleted: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--downloaded">
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/versionDownloaded',
|
||||
'Arduino IDE {0} has been downloaded.',
|
||||
version
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/closeToInstallNotice',
|
||||
'Close the software and install the update on your machine.'
|
||||
)}
|
||||
</div>
|
||||
<div className="buttons-container">
|
||||
{closeButton}
|
||||
<button
|
||||
onClick={onCloseAndInstall}
|
||||
type="button"
|
||||
className="theia-button close-and-install"
|
||||
>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/closeAndInstallButton',
|
||||
'Close and Install'
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const DownloadStarted: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--downloading">
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/downloadingNotice',
|
||||
'Downloading the latest version of the Arduino IDE.'
|
||||
)}
|
||||
</div>
|
||||
<ProgressBar percent={progress?.percent} showPercentage />
|
||||
</div>
|
||||
);
|
||||
|
||||
const PreDownload: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--pre-download">
|
||||
<div className="ide-updater-dialog--logo-container">
|
||||
<div className="ide-updater-dialog--logo"></div>
|
||||
</div>
|
||||
<div className="ide-updater-dialog--new-version-text dialogSection">
|
||||
<div className="dialogRow">
|
||||
<div className="bold">
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/updateAvailable',
|
||||
'Update Available'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="dialogRow">
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/newVersionAvailable',
|
||||
'A new version of Arduino IDE ({0}) is available for download.',
|
||||
version
|
||||
)}
|
||||
</div>
|
||||
{releaseNotes && (
|
||||
<div className="dialogRow">
|
||||
<div className="changelog-container" ref={changelogDivRef} />
|
||||
</div>
|
||||
)}
|
||||
<div className="buttons-container">
|
||||
<button
|
||||
onClick={onSkipVersion}
|
||||
type="button"
|
||||
className="theia-button secondary skip-version"
|
||||
>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/skipVersionButton',
|
||||
'Skip Version'
|
||||
)}
|
||||
</button>
|
||||
<div className="push"></div>
|
||||
{closeButton}
|
||||
<button
|
||||
onClick={onDownload}
|
||||
type="button"
|
||||
className="theia-button primary"
|
||||
>
|
||||
{nls.localize('arduino/ide-updater/downloadButton', 'Download')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const onGoToDownloadClick = (
|
||||
event: React.SyntheticEvent<HTMLAnchorElement, Event>
|
||||
) => {
|
||||
const { target } = event.nativeEvent;
|
||||
if (target instanceof HTMLAnchorElement) {
|
||||
event.nativeEvent.preventDefault();
|
||||
windowService.openNewWindow(target.href, { external: true });
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
const GoToDownloadPage: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--go-to-download-page">
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/goToDownloadPage',
|
||||
"An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there."
|
||||
)}
|
||||
</div>
|
||||
<div className="buttons-container">
|
||||
{closeButton}
|
||||
<a
|
||||
className="theia-button primary"
|
||||
href="https://www.arduino.cc/en/software#experimental-software"
|
||||
onClick={onGoToDownloadClick}
|
||||
>
|
||||
{nls.localize(
|
||||
'arduino/ide-updater/goToDownloadButton',
|
||||
'Go To Download'
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="ide-updater-dialog--content">
|
||||
{!!error ? (
|
||||
<GoToDownloadPage />
|
||||
) : downloadFinished ? (
|
||||
<DownloadCompleted />
|
||||
) : downloadStarted ? (
|
||||
<DownloadStarted />
|
||||
) : (
|
||||
<PreDownload />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
@@ -0,0 +1,173 @@
|
||||
import * as React from 'react';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||
import { Widget } from '@phosphor/widgets';
|
||||
import { Message } from '@phosphor/messaging';
|
||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||
import { nls } from '@theia/core';
|
||||
import { IDEUpdaterComponent } from './ide-updater-component';
|
||||
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
ProgressInfo,
|
||||
UpdateInfo,
|
||||
} from '../../../common/protocol/ide-updater';
|
||||
import { LocalStorageService } from '@theia/core/lib/browser';
|
||||
import { SKIP_IDE_VERSION } from '../../arduino-frontend-contribution';
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialogWidget extends ReactWidget {
|
||||
protected isOpen = new Object();
|
||||
updateInfo: UpdateInfo;
|
||||
progressInfo: ProgressInfo | undefined;
|
||||
error: Error | undefined;
|
||||
downloadFinished: boolean;
|
||||
downloadStarted: boolean;
|
||||
onClose: () => void;
|
||||
|
||||
@inject(IDEUpdater)
|
||||
protected readonly updater: IDEUpdater;
|
||||
|
||||
@inject(IDEUpdaterClient)
|
||||
protected readonly updaterClient: IDEUpdaterClient;
|
||||
|
||||
@inject(LocalStorageService)
|
||||
protected readonly localStorageService: LocalStorageService;
|
||||
|
||||
@inject(WindowService)
|
||||
protected windowService: WindowService;
|
||||
|
||||
init(updateInfo: UpdateInfo, onClose: () => void): void {
|
||||
this.updateInfo = updateInfo;
|
||||
this.progressInfo = undefined;
|
||||
this.error = undefined;
|
||||
this.downloadStarted = false;
|
||||
this.downloadFinished = false;
|
||||
this.onClose = onClose;
|
||||
|
||||
this.updaterClient.onError((e) => {
|
||||
this.error = e;
|
||||
this.update();
|
||||
});
|
||||
this.updaterClient.onDownloadProgressChanged((e) => {
|
||||
this.progressInfo = e;
|
||||
this.update();
|
||||
});
|
||||
this.updaterClient.onDownloadFinished((e) => {
|
||||
this.downloadFinished = true;
|
||||
this.update();
|
||||
});
|
||||
}
|
||||
|
||||
async onSkipVersion(): Promise<void> {
|
||||
this.localStorageService.setData<string>(
|
||||
SKIP_IDE_VERSION,
|
||||
this.updateInfo.version
|
||||
);
|
||||
this.close();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
super.close();
|
||||
this.onClose();
|
||||
}
|
||||
|
||||
onDispose(): void {
|
||||
if (this.downloadStarted && !this.downloadFinished)
|
||||
this.updater.stopDownload();
|
||||
}
|
||||
|
||||
async onDownload(): Promise<void> {
|
||||
this.progressInfo = undefined;
|
||||
this.downloadStarted = true;
|
||||
this.error = undefined;
|
||||
this.updater.downloadUpdate();
|
||||
this.update();
|
||||
}
|
||||
|
||||
onCloseAndInstall(): void {
|
||||
this.updater.quitAndInstall();
|
||||
}
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return !!this.updateInfo ? (
|
||||
<form>
|
||||
<IDEUpdaterComponent
|
||||
updateInfo={this.updateInfo}
|
||||
windowService={this.windowService}
|
||||
downloadStarted={this.downloadStarted}
|
||||
downloadFinished={this.downloadFinished}
|
||||
progress={this.progressInfo}
|
||||
error={this.error}
|
||||
onClose={this.close.bind(this)}
|
||||
onSkipVersion={this.onSkipVersion.bind(this)}
|
||||
onDownload={this.onDownload.bind(this)}
|
||||
onCloseAndInstall={this.onCloseAndInstall.bind(this)}
|
||||
/>
|
||||
</form>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
||||
@inject(IDEUpdaterDialogWidget)
|
||||
protected readonly widget: IDEUpdaterDialogWidget;
|
||||
|
||||
constructor(
|
||||
@inject(IDEUpdaterDialogProps)
|
||||
protected readonly props: IDEUpdaterDialogProps
|
||||
) {
|
||||
super({
|
||||
title: nls.localize(
|
||||
'arduino/ide-updater/ideUpdaterDialog',
|
||||
'Software Update'
|
||||
),
|
||||
});
|
||||
this.contentNode.classList.add('ide-updater-dialog');
|
||||
this.acceptButton = undefined;
|
||||
}
|
||||
|
||||
get value(): UpdateInfo {
|
||||
return this.widget.updateInfo;
|
||||
}
|
||||
|
||||
protected onAfterAttach(msg: Message): void {
|
||||
if (this.widget.isAttached) {
|
||||
Widget.detach(this.widget);
|
||||
}
|
||||
Widget.attach(this.widget, this.contentNode);
|
||||
super.onAfterAttach(msg);
|
||||
this.update();
|
||||
}
|
||||
|
||||
async open(
|
||||
data: UpdateInfo | undefined = undefined
|
||||
): Promise<UpdateInfo | undefined> {
|
||||
if (data && data.version) {
|
||||
this.widget.init(data, this.close.bind(this));
|
||||
return super.open();
|
||||
}
|
||||
}
|
||||
|
||||
protected onUpdateRequest(msg: Message): void {
|
||||
super.onUpdateRequest(msg);
|
||||
this.widget.update();
|
||||
}
|
||||
|
||||
protected onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
this.widget.activate();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.widget.dispose();
|
||||
super.close();
|
||||
}
|
||||
}
|
@@ -260,18 +260,6 @@ export class SettingsComponent extends React.Component<
|
||||
'Verify code after upload'
|
||||
)}
|
||||
</label>
|
||||
<label className="flex-line">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={this.state.checkForUpdates}
|
||||
onChange={this.checkForUpdatesDidChange}
|
||||
disabled={true}
|
||||
/>
|
||||
{nls.localize(
|
||||
'arduino/preferences/checkForUpdates',
|
||||
'Check for updates on startup'
|
||||
)}
|
||||
</label>
|
||||
<label className="flex-line">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -444,7 +432,9 @@ export class SettingsComponent extends React.Component<
|
||||
);
|
||||
}
|
||||
|
||||
protected noopKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
protected noopKeyDown = (
|
||||
event: React.KeyboardEvent<HTMLInputElement>
|
||||
): void => {
|
||||
if (this.isControlKey(event)) {
|
||||
return;
|
||||
}
|
||||
@@ -454,7 +444,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected numbersOnlyKeyDown = (
|
||||
event: React.KeyboardEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.isControlKey(event)) {
|
||||
return;
|
||||
}
|
||||
@@ -466,7 +456,7 @@ export class SettingsComponent extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
protected browseSketchbookDidClick = async () => {
|
||||
protected browseSketchbookDidClick = async (): Promise<void> => {
|
||||
const uri = await this.props.fileDialogService.showOpenDialog({
|
||||
title: nls.localize(
|
||||
'arduino/preferences/newSketchbookLocation',
|
||||
@@ -483,7 +473,7 @@ export class SettingsComponent extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
protected editAdditionalUrlDidClick = async () => {
|
||||
protected editAdditionalUrlDidClick = async (): Promise<void> => {
|
||||
const additionalUrls = await new AdditionalUrlsDialog(
|
||||
this.state.additionalUrls,
|
||||
this.props.windowService
|
||||
@@ -495,7 +485,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected editorFontSizeDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
const { value } = event.target;
|
||||
if (value) {
|
||||
this.setState({ editorFontSize: parseInt(value, 10) });
|
||||
@@ -504,7 +494,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected additionalUrlsDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({
|
||||
additionalUrls: event.target.value.split(',').map((url) => url.trim()),
|
||||
});
|
||||
@@ -512,13 +502,13 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected autoScaleInterfaceDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ autoScaleInterface: event.target.checked });
|
||||
};
|
||||
|
||||
protected interfaceScaleDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
const { value } = event.target;
|
||||
const percentage = parseInt(value, 10);
|
||||
if (isNaN(percentage)) {
|
||||
@@ -532,31 +522,25 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected verifyAfterUploadDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ verifyAfterUpload: event.target.checked });
|
||||
};
|
||||
|
||||
protected checkForUpdatesDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
this.setState({ checkForUpdates: event.target.checked });
|
||||
};
|
||||
|
||||
protected sketchbookShowAllFilesDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ sketchbookShowAllFiles: event.target.checked });
|
||||
};
|
||||
|
||||
protected autoSaveDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ autoSave: event.target.checked ? 'on' : 'off' });
|
||||
};
|
||||
|
||||
protected quickSuggestionsOtherDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
// need to persist react events through lifecycle https://reactjs.org/docs/events.html#event-pooling
|
||||
const newVal = event.target.checked ? true : false;
|
||||
|
||||
@@ -570,7 +554,9 @@ export class SettingsComponent extends React.Component<
|
||||
});
|
||||
};
|
||||
|
||||
protected themeDidChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
protected themeDidChange = (
|
||||
event: React.ChangeEvent<HTMLSelectElement>
|
||||
): void => {
|
||||
const { selectedIndex } = event.target.options;
|
||||
const theme = ThemeService.get().getThemes()[selectedIndex];
|
||||
if (theme) {
|
||||
@@ -580,14 +566,14 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected languageDidChange = (
|
||||
event: React.ChangeEvent<HTMLSelectElement>
|
||||
) => {
|
||||
): void => {
|
||||
const selectedLanguage = event.target.value;
|
||||
this.setState({ currentLanguage: selectedLanguage });
|
||||
};
|
||||
|
||||
protected compilerWarningsDidChange = (
|
||||
event: React.ChangeEvent<HTMLSelectElement>
|
||||
) => {
|
||||
): void => {
|
||||
const { selectedIndex } = event.target.options;
|
||||
const compilerWarnings = CompilerWarningLiterals[selectedIndex];
|
||||
if (compilerWarnings) {
|
||||
@@ -597,26 +583,28 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected verboseOnCompileDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ verboseOnCompile: event.target.checked });
|
||||
};
|
||||
|
||||
protected verboseOnUploadDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
this.setState({ verboseOnUpload: event.target.checked });
|
||||
};
|
||||
|
||||
protected sketchpathDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
const sketchbookPath = event.target.value;
|
||||
if (sketchbookPath) {
|
||||
this.setState({ sketchbookPath });
|
||||
}
|
||||
};
|
||||
|
||||
protected noProxyDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
protected noProxyDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
): void => {
|
||||
if (event.target.checked) {
|
||||
this.setState({ network: 'none' });
|
||||
} else {
|
||||
@@ -626,7 +614,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected manualProxyDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (event.target.checked) {
|
||||
this.setState({ network: Network.Default() });
|
||||
} else {
|
||||
@@ -636,7 +624,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected httpProtocolDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.protocol = event.target.checked ? 'http' : 'socks';
|
||||
@@ -646,7 +634,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected socksProtocolDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.protocol = event.target.checked ? 'socks' : 'http';
|
||||
@@ -656,7 +644,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected hostnameDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.hostname = event.target.value;
|
||||
@@ -664,7 +652,9 @@ export class SettingsComponent extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
protected portDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
protected portDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.port = event.target.value;
|
||||
@@ -674,7 +664,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected usernameDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.username = event.target.value;
|
||||
@@ -684,7 +674,7 @@ export class SettingsComponent extends React.Component<
|
||||
|
||||
protected passwordDidChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
): void => {
|
||||
if (this.state.network !== 'none') {
|
||||
const network = this.cloneProxySettings;
|
||||
network.password = event.target.value;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { injectable, inject, postConstruct } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { Deferred, timeout } from '@theia/core/lib/common/promise-util';
|
||||
import { deepClone } from '@theia/core/lib/common/objects';
|
||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||
import { ThemeService } from '@theia/core/lib/browser/theming';
|
||||
@@ -18,24 +18,22 @@ import {
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { AsyncLocalizationProvider } from '@theia/core/lib/common/i18n/localization';
|
||||
|
||||
const EDITOR_SETTING = 'editor';
|
||||
const FONT_SIZE_SETTING = `${EDITOR_SETTING}.fontSize`;
|
||||
const AUTO_SAVE_SETTING = `${EDITOR_SETTING}.autoSave`;
|
||||
const QUICK_SUGGESTIONS_SETTING = `${EDITOR_SETTING}.quickSuggestions`;
|
||||
const ARDUINO_SETTING = 'arduino';
|
||||
const WINDOW_SETTING = `${ARDUINO_SETTING}.window`;
|
||||
// const IDE_SETTING = `${ARDUINO_SETTING}.ide`;
|
||||
const COMPILE_SETTING = `${ARDUINO_SETTING}.compile`;
|
||||
const UPLOAD_SETTING = `${ARDUINO_SETTING}.upload`;
|
||||
const SKETCHBOOK_SETTING = `${ARDUINO_SETTING}.sketchbook`;
|
||||
const AUTO_SCALE_SETTING = `${WINDOW_SETTING}.autoScale`;
|
||||
const ZOOM_LEVEL_SETTING = `${WINDOW_SETTING}.zoomLevel`;
|
||||
// const AUTO_UPDATE_SETTING = `${IDE_SETTING}.autoUpdate`;
|
||||
const COMPILE_VERBOSE_SETTING = `${COMPILE_SETTING}.verbose`;
|
||||
const COMPILE_WARNINGS_SETTING = `${COMPILE_SETTING}.warnings`;
|
||||
const UPLOAD_VERBOSE_SETTING = `${UPLOAD_SETTING}.verbose`;
|
||||
const UPLOAD_VERIFY_SETTING = `${UPLOAD_SETTING}.verify`;
|
||||
const SHOW_ALL_FILES_SETTING = `${SKETCHBOOK_SETTING}.showAllFiles`;
|
||||
export const EDITOR_SETTING = 'editor';
|
||||
export const FONT_SIZE_SETTING = `${EDITOR_SETTING}.fontSize`;
|
||||
export const AUTO_SAVE_SETTING = `${EDITOR_SETTING}.autoSave`;
|
||||
export const QUICK_SUGGESTIONS_SETTING = `${EDITOR_SETTING}.quickSuggestions`;
|
||||
export const ARDUINO_SETTING = 'arduino';
|
||||
export const WINDOW_SETTING = `${ARDUINO_SETTING}.window`;
|
||||
export const COMPILE_SETTING = `${ARDUINO_SETTING}.compile`;
|
||||
export const UPLOAD_SETTING = `${ARDUINO_SETTING}.upload`;
|
||||
export const SKETCHBOOK_SETTING = `${ARDUINO_SETTING}.sketchbook`;
|
||||
export const AUTO_SCALE_SETTING = `${WINDOW_SETTING}.autoScale`;
|
||||
export const ZOOM_LEVEL_SETTING = `${WINDOW_SETTING}.zoomLevel`;
|
||||
export const COMPILE_VERBOSE_SETTING = `${COMPILE_SETTING}.verbose`;
|
||||
export const COMPILE_WARNINGS_SETTING = `${COMPILE_SETTING}.warnings`;
|
||||
export const UPLOAD_VERBOSE_SETTING = `${UPLOAD_SETTING}.verbose`;
|
||||
export const UPLOAD_VERIFY_SETTING = `${UPLOAD_SETTING}.verify`;
|
||||
export const SHOW_ALL_FILES_SETTING = `${SKETCHBOOK_SETTING}.showAllFiles`;
|
||||
|
||||
export interface Settings extends Index {
|
||||
editorFontSize: number; // `editor.fontSize`
|
||||
@@ -48,7 +46,6 @@ export interface Settings extends Index {
|
||||
|
||||
autoScaleInterface: boolean; // `arduino.window.autoScale`
|
||||
interfaceScale: number; // `arduino.window.zoomLevel` https://github.com/eclipse-theia/theia/issues/8751
|
||||
checkForUpdates?: boolean; // `arduino.ide.autoUpdate`
|
||||
verboseOnCompile: boolean; // `arduino.compile.verbose`
|
||||
compilerWarnings: CompilerWarnings; // `arduino.compile.warnings`
|
||||
verboseOnUpload: boolean; // `arduino.upload.verbose`
|
||||
@@ -93,7 +90,6 @@ export class SettingsService {
|
||||
|
||||
@postConstruct()
|
||||
protected async init(): Promise<void> {
|
||||
await this.appStateService.reachedState('ready'); // Hack for https://github.com/eclipse-theia/theia/issues/8993
|
||||
const settings = await this.loadSettings();
|
||||
this._settings = deepClone(settings);
|
||||
this.ready.resolve();
|
||||
@@ -110,7 +106,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -135,7 +130,6 @@ export class SettingsService {
|
||||
}),
|
||||
this.preferenceService.get<boolean>(AUTO_SCALE_SETTING, true),
|
||||
this.preferenceService.get<number>(ZOOM_LEVEL_SETTING, 0),
|
||||
// this.preferenceService.get<string>(AUTO_UPDATE_SETTING, true),
|
||||
this.preferenceService.get<boolean>(COMPILE_VERBOSE_SETTING, true),
|
||||
this.preferenceService.get<any>(COMPILE_WARNINGS_SETTING, 'None'),
|
||||
this.preferenceService.get<boolean>(UPLOAD_VERBOSE_SETTING, true),
|
||||
@@ -154,7 +148,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -224,6 +217,11 @@ export class SettingsService {
|
||||
}
|
||||
}
|
||||
|
||||
private async savePreference(name: string, value: unknown): Promise<void> {
|
||||
await this.preferenceService.set(name, value, PreferenceScope.User);
|
||||
await timeout(5);
|
||||
}
|
||||
|
||||
async save(): Promise<string | true> {
|
||||
await this.ready.promise;
|
||||
const {
|
||||
@@ -234,7 +232,6 @@ export class SettingsService {
|
||||
quickSuggestions,
|
||||
autoScaleInterface,
|
||||
interfaceScale,
|
||||
// checkForUpdates,
|
||||
verboseOnCompile,
|
||||
compilerWarnings,
|
||||
verboseOnUpload,
|
||||
@@ -253,70 +250,29 @@ export class SettingsService {
|
||||
(config as any).network = network;
|
||||
(config as any).locale = currentLanguage;
|
||||
|
||||
await Promise.all([
|
||||
this.preferenceService.set(
|
||||
'editor.fontSize',
|
||||
editorFontSize,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
'workbench.colorTheme',
|
||||
themeId,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
'editor.autoSave',
|
||||
autoSave,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
'editor.quickSuggestions',
|
||||
quickSuggestions,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
AUTO_SCALE_SETTING,
|
||||
autoScaleInterface,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
ZOOM_LEVEL_SETTING,
|
||||
interfaceScale,
|
||||
PreferenceScope.User
|
||||
),
|
||||
// this.preferenceService.set(AUTO_UPDATE_SETTING, checkForUpdates, PreferenceScope.User),
|
||||
this.preferenceService.set(
|
||||
COMPILE_VERBOSE_SETTING,
|
||||
verboseOnCompile,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
COMPILE_WARNINGS_SETTING,
|
||||
compilerWarnings,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
UPLOAD_VERBOSE_SETTING,
|
||||
verboseOnUpload,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
UPLOAD_VERIFY_SETTING,
|
||||
verifyAfterUpload,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.preferenceService.set(
|
||||
SHOW_ALL_FILES_SETTING,
|
||||
sketchbookShowAllFiles,
|
||||
PreferenceScope.User
|
||||
),
|
||||
this.configService.setConfiguration(config),
|
||||
]);
|
||||
await this.savePreference('editor.fontSize', editorFontSize);
|
||||
await this.savePreference('workbench.colorTheme', themeId);
|
||||
await this.savePreference('editor.autoSave', autoSave);
|
||||
await this.savePreference('editor.quickSuggestions', quickSuggestions);
|
||||
await this.savePreference(AUTO_SCALE_SETTING, autoScaleInterface);
|
||||
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
||||
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
||||
await this.savePreference(COMPILE_VERBOSE_SETTING, verboseOnCompile);
|
||||
await this.savePreference(COMPILE_WARNINGS_SETTING, compilerWarnings);
|
||||
await this.savePreference(UPLOAD_VERBOSE_SETTING, verboseOnUpload);
|
||||
await this.savePreference(UPLOAD_VERIFY_SETTING, verifyAfterUpload);
|
||||
await this.savePreference(SHOW_ALL_FILES_SETTING, sketchbookShowAllFiles);
|
||||
await this.configService.setConfiguration(config);
|
||||
this.onDidChangeEmitter.fire(this._settings);
|
||||
|
||||
// after saving all the settings, if we need to change the language we need to perform a reload
|
||||
if (currentLanguage !== nls.locale) {
|
||||
window.localStorage.setItem(nls.localeId, currentLanguage);
|
||||
// Only reload if the language differs from the current locale. `nls.locale === undefined` signals english as well
|
||||
if (currentLanguage !== nls.locale && !(currentLanguage === 'en' && nls.locale === undefined)) {
|
||||
if (currentLanguage === 'en') {
|
||||
window.localStorage.removeItem(nls.localeId);
|
||||
} else {
|
||||
window.localStorage.setItem(nls.localeId, currentLanguage);
|
||||
}
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,40 @@
|
||||
import { Emitter } from '@theia/core';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { UpdateInfo, ProgressInfo } from 'electron-updater';
|
||||
import { IDEUpdaterClient } from '../../common/protocol/ide-updater';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterClientImpl implements IDEUpdaterClient {
|
||||
protected readonly onErrorEmitter = new Emitter<Error>();
|
||||
protected readonly onCheckingForUpdateEmitter = new Emitter<void>();
|
||||
protected readonly onUpdateAvailableEmitter = new Emitter<UpdateInfo>();
|
||||
protected readonly onUpdateNotAvailableEmitter = new Emitter<UpdateInfo>();
|
||||
protected readonly onDownloadProgressEmitter = new Emitter<ProgressInfo>();
|
||||
protected readonly onDownloadFinishedEmitter = new Emitter<UpdateInfo>();
|
||||
|
||||
readonly onError = this.onErrorEmitter.event;
|
||||
readonly onCheckingForUpdate = this.onCheckingForUpdateEmitter.event;
|
||||
readonly onUpdateAvailable = this.onUpdateAvailableEmitter.event;
|
||||
readonly onUpdateNotAvailable = this.onUpdateNotAvailableEmitter.event;
|
||||
readonly onDownloadProgressChanged = this.onDownloadProgressEmitter.event;
|
||||
readonly onDownloadFinished = this.onDownloadFinishedEmitter.event;
|
||||
|
||||
notifyError(message: Error): void {
|
||||
this.onErrorEmitter.fire(message);
|
||||
}
|
||||
notifyCheckingForUpdate(message: void): void {
|
||||
this.onCheckingForUpdateEmitter.fire(message);
|
||||
}
|
||||
notifyUpdateAvailable(message: UpdateInfo): void {
|
||||
this.onUpdateAvailableEmitter.fire(message);
|
||||
}
|
||||
notifyUpdateNotAvailable(message: UpdateInfo): void {
|
||||
this.onUpdateNotAvailableEmitter.fire(message);
|
||||
}
|
||||
notifyDownloadProgressChanged(message: ProgressInfo): void {
|
||||
this.onDownloadProgressEmitter.fire(message);
|
||||
}
|
||||
notifyDownloadFinished(message: UpdateInfo): void {
|
||||
this.onDownloadFinishedEmitter.fire(message);
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
Command,
|
||||
CommandContribution,
|
||||
CommandRegistry,
|
||||
MessageService,
|
||||
nls,
|
||||
} from '@theia/core';
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { IDEUpdater, UpdateInfo } from '../../common/protocol/ide-updater';
|
||||
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterCommands implements CommandContribution {
|
||||
constructor(
|
||||
@inject(IDEUpdater)
|
||||
private readonly updater: IDEUpdater,
|
||||
@inject(MessageService)
|
||||
protected readonly messageService: MessageService,
|
||||
@inject(IDEUpdaterDialog)
|
||||
protected readonly updaterDialog: IDEUpdaterDialog
|
||||
) {}
|
||||
|
||||
registerCommands(registry: CommandRegistry): void {
|
||||
registry.registerCommand(IDEUpdaterCommands.CHECK_FOR_UPDATES, {
|
||||
execute: this.checkForUpdates.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
async checkForUpdates(initialCheck?: boolean): Promise<UpdateInfo | void> {
|
||||
try {
|
||||
const updateInfo = await this.updater.checkForUpdates(initialCheck);
|
||||
if (!!updateInfo) {
|
||||
this.updaterDialog.open(updateInfo);
|
||||
} else {
|
||||
this.messageService.info(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/noUpdatesAvailable',
|
||||
'There are no recent updates available for the Arduino IDE'
|
||||
)
|
||||
);
|
||||
}
|
||||
return updateInfo;
|
||||
} catch (e) {
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'arduino/ide-updater/errorCheckingForUpdates',
|
||||
'Error while checking for Arduino IDE updates.\n{0}',
|
||||
e.message
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
export namespace IDEUpdaterCommands {
|
||||
export const CHECK_FOR_UPDATES: Command = {
|
||||
id: 'arduino-ide-check-for-updates',
|
||||
category: 'Arduino',
|
||||
label: 'Check for Arduino IDE updates',
|
||||
};
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { Key, KeyCode } from '@theia/core/lib/browser/keys';
|
||||
import { Board, Port } from '../../../common/protocol/boards-service';
|
||||
import { Board } from '../../../common/protocol/boards-service';
|
||||
import { isOSX } from '@theia/core/lib/common/os';
|
||||
import { DisposableCollection, nls } from '@theia/core/lib/common';
|
||||
import { SerialConnectionManager } from '../serial-connection-manager';
|
||||
@@ -80,14 +80,14 @@ export class SerialMonitorSendInput extends React.Component<
|
||||
const { board, port } = serialConfig;
|
||||
return nls.localize(
|
||||
'arduino/serial/message',
|
||||
"Message ({0} + Enter to send message to '{1}' on '{2}'",
|
||||
"Message ({0} + Enter to send message to '{1}' on '{2}')",
|
||||
isOSX ? '⌘' : nls.localize('vscode/keybindingLabels/ctrlKey', 'Ctrl'),
|
||||
board
|
||||
? Board.toString(board, {
|
||||
useFqbn: false,
|
||||
})
|
||||
: 'unknown',
|
||||
port ? Port.toString(port) : 'unknown'
|
||||
port ? port.address : 'unknown'
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -43,6 +43,7 @@ export class SerialMonitorOutput extends React.Component<
|
||||
itemCount={this.state.lines.length}
|
||||
itemSize={18}
|
||||
width={'100%'}
|
||||
style={{ whiteSpace: 'nowrap' }}
|
||||
ref={this.listRef}
|
||||
>
|
||||
{Row}
|
||||
|
@@ -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';
|
||||
|
@@ -10,7 +10,6 @@ import {
|
||||
} from '../../common/protocol/serial-service';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
import {
|
||||
Port,
|
||||
Board,
|
||||
BoardsService,
|
||||
} from '../../common/protocol/boards-service';
|
||||
@@ -217,7 +216,7 @@ export class SerialConnectionManager {
|
||||
nls.localize(
|
||||
'arduino/serial/connectionBusy',
|
||||
'Connection failed. Serial port is busy: {0}',
|
||||
Port.toString(port)
|
||||
port.address
|
||||
),
|
||||
options
|
||||
);
|
||||
@@ -232,7 +231,7 @@ export class SerialConnectionManager {
|
||||
Board.toString(board, {
|
||||
useFqbn: false,
|
||||
}),
|
||||
Port.toString(port)
|
||||
port.address
|
||||
),
|
||||
options
|
||||
);
|
||||
@@ -244,7 +243,7 @@ export class SerialConnectionManager {
|
||||
'arduino/serial/unexpectedError',
|
||||
'Unexpected error. Reconnecting {0} on port {1}.',
|
||||
Board.toString(board),
|
||||
Port.toString(port)
|
||||
port.address
|
||||
),
|
||||
options
|
||||
);
|
||||
@@ -262,7 +261,7 @@ export class SerialConnectionManager {
|
||||
Board.toString(board, {
|
||||
useFqbn: false,
|
||||
}),
|
||||
Port.toString(port)
|
||||
port.address
|
||||
)
|
||||
);
|
||||
this.serialErrors.length = 0;
|
||||
@@ -280,7 +279,7 @@ export class SerialConnectionManager {
|
||||
Board.toString(board, {
|
||||
useFqbn: false,
|
||||
}),
|
||||
Port.toString(port),
|
||||
port.address,
|
||||
attempts.toString()
|
||||
)
|
||||
);
|
||||
@@ -351,7 +350,7 @@ export namespace Serial {
|
||||
export function toString(config: Partial<SerialConfig>): string {
|
||||
if (!isSerialConfig(config)) return '';
|
||||
const { board, port } = config;
|
||||
return `${Board.toString(board)} ${Port.toString(port)}`;
|
||||
return `${Board.toString(board)} ${port.address}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
arduino-ide-extension/src/browser/style/ide-logo.png
Normal file
BIN
arduino-ide-extension/src/browser/style/ide-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,78 @@
|
||||
.ide-updater-dialog {
|
||||
width: 546px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--pre-download {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--logo-container {
|
||||
margin-right: 28px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog--logo {
|
||||
background: url('./ide-logo.png') round;
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
.dialogContent.ide-updater-dialog
|
||||
.ide-updater-dialog--content
|
||||
.ide-updater-dialog--new-version-text.dialogSection {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container {
|
||||
background: white;
|
||||
border: 1px solid #dae3e3;
|
||||
border-radius: 2px;
|
||||
font-size: 12px;
|
||||
height: 180px;
|
||||
overflow: auto;
|
||||
padding: 0 12px;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container a {
|
||||
color: #018184;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container a:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container code {
|
||||
background: #ecf1f1;
|
||||
border-radius: 2px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .changelog-container a code {
|
||||
color: #018184;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container a.theia-button {
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container a.theia-button:hover {
|
||||
color: var(--theia-button-foreground);
|
||||
}
|
||||
|
||||
.ide-updater-dialog .buttons-container .push {
|
||||
margin-right: auto;
|
||||
}
|
@@ -9,6 +9,7 @@
|
||||
@import './editor.css';
|
||||
@import './settings-dialog.css';
|
||||
@import './firmware-uploader-dialog.css';
|
||||
@import './ide-updater-dialog.css';
|
||||
@import './certificate-uploader-dialog.css';
|
||||
@import './user-fields-dialog.css';
|
||||
@import './debug.css';
|
||||
@@ -16,6 +17,7 @@
|
||||
@import './cloud-sketchbook.css';
|
||||
@import './fonts.css';
|
||||
@import './custom-codicon.css';
|
||||
@import './progress-bar.css';
|
||||
|
||||
.theia-input.warning:focus {
|
||||
outline-width: 1px;
|
||||
|
32
arduino-ide-extension/src/browser/style/progress-bar.css
Normal file
32
arduino-ide-extension/src/browser/style/progress-bar.css
Normal file
@@ -0,0 +1,32 @@
|
||||
.progress-bar {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.progress-bar--outer {
|
||||
background: #e5e5e5;
|
||||
border-radius: 11px;
|
||||
height: 6px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar--inner {
|
||||
transition: width 1s;
|
||||
height: 100%;
|
||||
background: #008184;
|
||||
border-radius: 11px;
|
||||
}
|
||||
|
||||
.progress-bar--percentage {
|
||||
align-items: flex-end;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-bar--percentage-text {
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
}
|
@@ -62,9 +62,15 @@ export class DebugSessionManager extends TheiaDebugSessionManager {
|
||||
}
|
||||
);
|
||||
}
|
||||
// TODO: remove as https://github.com/eclipse-theia/theia/issues/10164 is fixed
|
||||
async terminateSessions(): Promise<void> {
|
||||
await super.terminateSessions();
|
||||
this.destroy(this.currentSession?.id);
|
||||
async terminateSession(session?: DebugSession): Promise<void> {
|
||||
if (!session) {
|
||||
this.updateCurrentSession(this._currentSession);
|
||||
session = this._currentSession;
|
||||
}
|
||||
// The cortex-debug extension does not respond to close requests
|
||||
// So we simply terminate the debug session immediately
|
||||
// Alternatively the `super.terminateSession` call will terminate it after 5 seconds without a response
|
||||
await this.debug.terminateDebugSession(session!.id);
|
||||
await super.terminateSession(session);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/workspace-delete-handler';
|
||||
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { injectable, inject } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
@@ -18,6 +19,7 @@ import { ArduinoWorkspaceRootResolver } from '../../arduino-workspace-resolver';
|
||||
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
||||
import { BoardsConfig } from '../../boards/boards-config';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { URI as VSCodeUri } from '@theia/core/shared/vscode-uri';
|
||||
|
||||
@injectable()
|
||||
export class WorkspaceService extends TheiaWorkspaceService {
|
||||
@@ -67,7 +69,7 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
this.workspaceUri = (async () => {
|
||||
try {
|
||||
const hash = window.location.hash;
|
||||
const [recentWorkspaces, recentSketches] = await Promise.all([
|
||||
const [recentWorkspacesPaths, recentSketches] = await Promise.all([
|
||||
this.server.getRecentWorkspaces(),
|
||||
this.sketchService
|
||||
.getSketches({})
|
||||
@@ -75,6 +77,10 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
SketchContainer.toArray(container).map((s) => s.uri)
|
||||
),
|
||||
]);
|
||||
// On Dindows, `getRecentWorkspaces` returns only file paths, not URIs as expected by the `isValid` method.
|
||||
const recentWorkspaces = recentWorkspacesPaths.map((e) =>
|
||||
VSCodeUri.file(e).toString()
|
||||
);
|
||||
const toOpen = await new ArduinoWorkspaceRootResolver({
|
||||
isValid: this.isValid.bind(this),
|
||||
}).resolve({ hash, recentWorkspaces, recentSketches });
|
||||
@@ -124,6 +130,8 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
}: FocusTracker.IChangedArgs<Widget>): void {
|
||||
if (newValue instanceof EditorWidget) {
|
||||
const { uri } = newValue.editor;
|
||||
const currentWindow = remote.getCurrentWindow();
|
||||
currentWindow.setRepresentedFilename(uri.path.toString());
|
||||
if (Sketch.isSketchFile(uri.toString())) {
|
||||
this.updateTitle();
|
||||
} else {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
@@ -80,7 +80,7 @@ export class SketchbookWidgetContribution
|
||||
}
|
||||
|
||||
onStart(): void {
|
||||
this.shell.currentChanged.connect(() =>
|
||||
this.shell.onDidChangeCurrentWidget(() =>
|
||||
this.onCurrentWidgetChangedHandler()
|
||||
);
|
||||
|
||||
|
@@ -7,13 +7,13 @@ export type AvailablePorts = Record<string, [Port, Array<Board>]>;
|
||||
export namespace AvailablePorts {
|
||||
export function byProtocol(availablePorts: AvailablePorts): Map<string, AvailablePorts> {
|
||||
const grouped = new Map<string, AvailablePorts>();
|
||||
for (const address of Object.keys(availablePorts)) {
|
||||
const [port, boards] = availablePorts[address];
|
||||
for (const portID of Object.keys(availablePorts)) {
|
||||
const [port, boards] = availablePorts[portID];
|
||||
let ports = grouped.get(port.protocol);
|
||||
if (!ports) {
|
||||
ports = {} as AvailablePorts;
|
||||
}
|
||||
ports[address] = [port, boards];
|
||||
ports[portID] = [port, boards];
|
||||
grouped.set(port.protocol, ports);
|
||||
}
|
||||
return grouped;
|
||||
@@ -43,7 +43,7 @@ export namespace AttachedBoardsChangeEvent {
|
||||
const visitedDetachedPorts: Port[] = [];
|
||||
for (const board of attached.boards) {
|
||||
const port = board.port
|
||||
? ` on ${Port.toString(board.port, { useLabel: true })}`
|
||||
? ` on ${Port.toString(board.port)}`
|
||||
: '';
|
||||
rows.push(` - Attached board: ${Board.toString(board)}${port}`);
|
||||
if (board.port) {
|
||||
@@ -52,7 +52,7 @@ export namespace AttachedBoardsChangeEvent {
|
||||
}
|
||||
for (const board of detached.boards) {
|
||||
const port = board.port
|
||||
? ` from ${Port.toString(board.port, { useLabel: true })}`
|
||||
? ` from ${Port.toString(board.port)}`
|
||||
: '';
|
||||
rows.push(` - Detached board: ${Board.toString(board)}${port}`);
|
||||
if (board.port) {
|
||||
@@ -62,18 +62,14 @@ export namespace AttachedBoardsChangeEvent {
|
||||
for (const port of attached.ports) {
|
||||
if (!visitedAttachedPorts.find((p) => Port.sameAs(port, p))) {
|
||||
rows.push(
|
||||
` - New port is available on ${Port.toString(port, {
|
||||
useLabel: true,
|
||||
})}`
|
||||
` - New port is available on ${Port.toString(port)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
for (const port of detached.ports) {
|
||||
if (!visitedDetachedPorts.find((p) => Port.sameAs(port, p))) {
|
||||
rows.push(
|
||||
` - Port is no longer available on ${Port.toString(port, {
|
||||
useLabel: true,
|
||||
})}`
|
||||
` - Port is no longer available on ${Port.toString(port)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -147,12 +143,14 @@ export interface BoardsService
|
||||
}
|
||||
|
||||
export interface Port {
|
||||
// id is the combination of address and protocol
|
||||
// formatted like "<address>|<protocol>" used
|
||||
// to univocally recognize a port
|
||||
readonly id: string;
|
||||
readonly address: string;
|
||||
readonly addressLabel: string;
|
||||
readonly protocol: string;
|
||||
/**
|
||||
* Optional label for the protocol. For example: `Serial Port (USB)`.
|
||||
*/
|
||||
readonly label?: string;
|
||||
readonly protocolLabel: string;
|
||||
}
|
||||
export namespace Port {
|
||||
export function is(arg: any): arg is Port {
|
||||
@@ -165,14 +163,8 @@ export namespace Port {
|
||||
);
|
||||
}
|
||||
|
||||
export function toString(
|
||||
port: Port,
|
||||
options: { useLabel: boolean } = { useLabel: false }
|
||||
): string {
|
||||
if (options.useLabel && port.label) {
|
||||
return `${port.address} ${port.label}`;
|
||||
}
|
||||
return port.address;
|
||||
export function toString(port: Port): string {
|
||||
return `${port.addressLabel} ${port.protocolLabel}`;
|
||||
}
|
||||
|
||||
export function compare(left: Port, right: Port): number {
|
||||
@@ -192,29 +184,12 @@ export namespace Port {
|
||||
return naturalCompare(left.address!, right.address!);
|
||||
}
|
||||
|
||||
export function equals(
|
||||
export function sameAs(
|
||||
left: Port | undefined,
|
||||
right: Port | undefined
|
||||
): boolean {
|
||||
if (left && right) {
|
||||
return (
|
||||
left.address === right.address &&
|
||||
left.protocol === right.protocol &&
|
||||
(left.label || '') === (right.label || '')
|
||||
);
|
||||
}
|
||||
return left === right;
|
||||
}
|
||||
|
||||
export function sameAs(
|
||||
left: Port | undefined,
|
||||
right: Port | string | undefined
|
||||
) {
|
||||
if (left && right) {
|
||||
if (typeof right === 'string') {
|
||||
return left.address === right;
|
||||
}
|
||||
return left.address === right.address;
|
||||
return left.address === right.address && left.protocol === right.protocol;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
71
arduino-ide-extension/src/common/protocol/ide-updater.ts
Normal file
71
arduino-ide-extension/src/common/protocol/ide-updater.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { JsonRpcServer } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||
import { Event } from '@theia/core/lib/common/event';
|
||||
import { UpdateChannel } from '../../browser/arduino-preferences';
|
||||
|
||||
export interface ProgressInfo {
|
||||
total: number;
|
||||
delta: number;
|
||||
transferred: number;
|
||||
percent: number;
|
||||
bytesPerSecond: number;
|
||||
}
|
||||
|
||||
export interface ReleaseNoteInfo {
|
||||
readonly version: string;
|
||||
readonly note: string | null;
|
||||
}
|
||||
|
||||
export interface BlockMapDataHolder {
|
||||
size?: number;
|
||||
blockMapSize?: number;
|
||||
readonly sha512: string;
|
||||
readonly isAdminRightsRequired?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateFileInfo extends BlockMapDataHolder {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export type UpdateInfo = {
|
||||
readonly version: string;
|
||||
readonly files: Array<UpdateFileInfo>;
|
||||
releaseName?: string | null;
|
||||
releaseNotes?: string | Array<ReleaseNoteInfo> | null;
|
||||
releaseDate: string;
|
||||
readonly stagingPercentage?: number;
|
||||
};
|
||||
|
||||
export interface ProgressInfo {
|
||||
total: number;
|
||||
delta: number;
|
||||
transferred: number;
|
||||
percent: number;
|
||||
bytesPerSecond: number;
|
||||
}
|
||||
|
||||
export const IDEUpdaterPath = '/services/ide-updater';
|
||||
export const IDEUpdater = Symbol('IDEUpdater');
|
||||
export interface IDEUpdater extends JsonRpcServer<IDEUpdaterClient> {
|
||||
init(channel: UpdateChannel, baseUrl: string): Promise<void>;
|
||||
checkForUpdates(initialCheck?: boolean): Promise<UpdateInfo | void>;
|
||||
downloadUpdate(): Promise<void>;
|
||||
quitAndInstall(): void;
|
||||
stopDownload(): void;
|
||||
disconnectClient(client: IDEUpdaterClient): void;
|
||||
}
|
||||
|
||||
export const IDEUpdaterClient = Symbol('IDEUpdaterClient');
|
||||
export interface IDEUpdaterClient {
|
||||
onError: Event<Error>;
|
||||
onCheckingForUpdate: Event<void>;
|
||||
onUpdateAvailable: Event<UpdateInfo>;
|
||||
onUpdateNotAvailable: Event<UpdateInfo>;
|
||||
onDownloadProgressChanged: Event<ProgressInfo>;
|
||||
onDownloadFinished: Event<UpdateInfo>;
|
||||
notifyError(message: Error): void;
|
||||
notifyCheckingForUpdate(message: void): void;
|
||||
notifyUpdateAvailable(message: UpdateInfo): void;
|
||||
notifyUpdateNotAvailable(message: UpdateInfo): void;
|
||||
notifyDownloadProgressChanged(message: ProgressInfo): void;
|
||||
notifyDownloadFinished(message: UpdateInfo): void;
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import {
|
||||
ConnectionStatus,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { remote } from 'electron';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { isOSX } from '@theia/core/lib/common/os';
|
||||
import { Keybinding } from '@theia/core/lib/common/keybinding';
|
||||
import {
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
ArduinoMenus,
|
||||
PlaceholderMenuNode,
|
||||
} from '../../../browser/menu/arduino-menus';
|
||||
import electron = require('@theia/core/shared/electron');
|
||||
|
||||
@injectable()
|
||||
export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
@@ -35,9 +34,9 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
await this.preferencesService.ready;
|
||||
const createdMenuBar = this.createElectronMenuBar();
|
||||
if (isOSX) {
|
||||
electron.remote.Menu.setApplicationMenu(createdMenuBar);
|
||||
remote.Menu.setApplicationMenu(createdMenuBar);
|
||||
} else {
|
||||
electron.remote.getCurrentWindow().setMenu(createdMenuBar);
|
||||
remote.getCurrentWindow().setMenu(createdMenuBar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +80,7 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
protected createOSXMenu(): Electron.MenuItemConstructorOptions {
|
||||
const { submenu } = super.createOSXMenu();
|
||||
const label = 'Arduino IDE';
|
||||
if (!!submenu && !(submenu instanceof remote.Menu)) {
|
||||
if (!!submenu && Array.isArray(submenu)) {
|
||||
const [, , /* about */ /* preferences */ ...rest] = submenu;
|
||||
const about = this.fillMenuTemplate(
|
||||
[],
|
||||
|
@@ -2,7 +2,10 @@ import { ContainerModule } from 'inversify';
|
||||
import { JsonRpcConnectionHandler } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||
import { ElectronConnectionHandler } from '@theia/core/lib/electron-common/messaging/electron-connection-handler';
|
||||
import { ElectronMainWindowService } from '@theia/core/lib/electron-common/electron-main-window-service';
|
||||
import { ElectronMainApplication as TheiaElectronMainApplication } from '@theia/core/lib/electron-main/electron-main-application';
|
||||
import {
|
||||
ElectronMainApplication as TheiaElectronMainApplication,
|
||||
ElectronMainApplicationContribution,
|
||||
} from '@theia/core/lib/electron-main/electron-main-application';
|
||||
import {
|
||||
SplashService,
|
||||
splashServicePath,
|
||||
@@ -10,6 +13,12 @@ import {
|
||||
import { SplashServiceImpl } from './splash/splash-service-impl';
|
||||
import { ElectronMainApplication } from './theia/electron-main-application';
|
||||
import { ElectronMainWindowServiceImpl } from './theia/electron-main-window-service';
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
IDEUpdaterPath,
|
||||
} from '../common/protocol/ide-updater';
|
||||
import { IDEUpdaterImpl } from './ide-updater/ide-updater-impl';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(ElectronMainApplication).toSelf().inSingletonScope();
|
||||
@@ -28,4 +37,23 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
)
|
||||
)
|
||||
.inSingletonScope();
|
||||
|
||||
// IDE updater bindings
|
||||
bind(IDEUpdaterImpl).toSelf().inSingletonScope();
|
||||
bind(IDEUpdater).toService(IDEUpdaterImpl);
|
||||
bind(ElectronMainApplicationContribution).toService(IDEUpdater);
|
||||
bind(ElectronConnectionHandler)
|
||||
.toDynamicValue(
|
||||
(context) =>
|
||||
new JsonRpcConnectionHandler<IDEUpdaterClient>(
|
||||
IDEUpdaterPath,
|
||||
(client) => {
|
||||
const server = context.container.get<IDEUpdater>(IDEUpdater);
|
||||
server.setClient(client);
|
||||
client.onDidCloseConnection(() => server.disconnectClient(client));
|
||||
return server;
|
||||
}
|
||||
)
|
||||
)
|
||||
.inSingletonScope();
|
||||
});
|
||||
|
@@ -0,0 +1,131 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { UpdateInfo, CancellationToken, autoUpdater } from 'electron-updater';
|
||||
import fetch, { Response } from 'node-fetch';
|
||||
import { UpdateChannel } from '../../browser/arduino-preferences';
|
||||
import {
|
||||
IDEUpdater,
|
||||
IDEUpdaterClient,
|
||||
} from '../../common/protocol/ide-updater';
|
||||
|
||||
const CHANGELOG_BASE_URL = 'https://downloads.arduino.cc/arduino-ide/changelog';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterImpl implements IDEUpdater {
|
||||
private isAlreadyChecked = false;
|
||||
private updater = autoUpdater;
|
||||
private cancellationToken?: CancellationToken;
|
||||
protected theiaFEClient?: IDEUpdaterClient;
|
||||
protected clients: Array<IDEUpdaterClient> = [];
|
||||
|
||||
constructor() {
|
||||
this.updater.on('checking-for-update', (e) => {
|
||||
this.clients.forEach((c) => c.notifyCheckingForUpdate(e));
|
||||
});
|
||||
this.updater.on('update-available', (e) => {
|
||||
this.clients.forEach((c) => c.notifyUpdateAvailable(e));
|
||||
});
|
||||
this.updater.on('update-not-available', (e) => {
|
||||
this.clients.forEach((c) => c.notifyUpdateNotAvailable(e));
|
||||
});
|
||||
this.updater.on('download-progress', (e) => {
|
||||
this.clients.forEach((c) => c.notifyDownloadProgressChanged(e));
|
||||
});
|
||||
this.updater.on('update-downloaded', (e) => {
|
||||
this.clients.forEach((c) => c.notifyDownloadFinished(e));
|
||||
});
|
||||
this.updater.on('error', (e) => {
|
||||
this.clients.forEach((c) => c.notifyError(e));
|
||||
});
|
||||
}
|
||||
|
||||
async init(channel: UpdateChannel, baseUrl: string): Promise<void> {
|
||||
this.updater.autoDownload = false;
|
||||
this.updater.channel = channel;
|
||||
this.updater.setFeedURL({
|
||||
provider: 'generic',
|
||||
url: `${baseUrl}/${channel === UpdateChannel.Nightly ? 'nightly' : ''}`,
|
||||
channel,
|
||||
});
|
||||
}
|
||||
|
||||
setClient(client: IDEUpdaterClient | undefined): void {
|
||||
if (client) this.clients.push(client);
|
||||
}
|
||||
|
||||
async checkForUpdates(initialCheck?: boolean): Promise<UpdateInfo | void> {
|
||||
if (initialCheck) {
|
||||
if (this.isAlreadyChecked) return Promise.resolve();
|
||||
this.isAlreadyChecked = true;
|
||||
}
|
||||
|
||||
const {
|
||||
updateInfo,
|
||||
cancellationToken,
|
||||
} = await this.updater.checkForUpdates();
|
||||
|
||||
this.cancellationToken = cancellationToken;
|
||||
if (this.updater.currentVersion.compare(updateInfo.version) === -1) {
|
||||
/*
|
||||
'latest.txt' points to the latest changelog that has been generated by the CI,
|
||||
so we need to make a first GET request to get the filename of the changelog
|
||||
and a second GET to the actual changelog file
|
||||
*/
|
||||
try {
|
||||
let response: Response | null = await fetch(
|
||||
`${CHANGELOG_BASE_URL}/latest.txt`
|
||||
);
|
||||
const latestChangelogFileName = response.ok
|
||||
? await response.text()
|
||||
: null;
|
||||
response = latestChangelogFileName
|
||||
? await fetch(`${CHANGELOG_BASE_URL}/${latestChangelogFileName}`)
|
||||
: null;
|
||||
const changelog = response?.ok ? await response?.text() : null;
|
||||
|
||||
// We only want to see the release notes of newer versions
|
||||
const currentVersionIndex = changelog?.indexOf(
|
||||
`\r\n\r\n---\r\n\r\n## ${this.updater.currentVersion}\r\n\r\n`
|
||||
);
|
||||
const newChangelog =
|
||||
currentVersionIndex && currentVersionIndex > 0
|
||||
? changelog?.slice(0, currentVersionIndex)
|
||||
: changelog;
|
||||
updateInfo.releaseNotes = newChangelog;
|
||||
} catch {
|
||||
/*
|
||||
if the request for the changelog fails, we'll just avoid to show it
|
||||
to the user, but we will still show the update info
|
||||
*/
|
||||
}
|
||||
return updateInfo;
|
||||
}
|
||||
}
|
||||
|
||||
async downloadUpdate(): Promise<void> {
|
||||
try {
|
||||
await this.updater.downloadUpdate(this.cancellationToken);
|
||||
} catch (e) {
|
||||
if (e.message === 'cancelled') return;
|
||||
this.clients.forEach((c) => c.notifyError(e));
|
||||
}
|
||||
}
|
||||
|
||||
stopDownload(): void {
|
||||
this.cancellationToken?.cancel();
|
||||
}
|
||||
|
||||
quitAndInstall(): void {
|
||||
this.updater.quitAndInstall();
|
||||
}
|
||||
|
||||
disconnectClient(client: IDEUpdaterClient): void {
|
||||
const index = this.clients.indexOf(client);
|
||||
if (index !== -1) {
|
||||
this.clients.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.clients.forEach(this.disconnectClient.bind(this));
|
||||
}
|
||||
}
|
@@ -1,29 +1,44 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import {
|
||||
app,
|
||||
BrowserWindow,
|
||||
BrowserWindowConstructorOptions,
|
||||
screen,
|
||||
} from 'electron';
|
||||
import { app, BrowserWindow, BrowserWindowConstructorOptions, ipcMain, screen, Event as ElectronEvent } from '@theia/core/electron-shared/electron';
|
||||
import { fork } from 'child_process';
|
||||
import { AddressInfo } from 'net';
|
||||
import { join } from 'path';
|
||||
import { join, dirname } from 'path';
|
||||
import * as fs from 'fs-extra';
|
||||
import { initSplashScreen } from '../splash/splash-screen';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token';
|
||||
import { FrontendApplicationConfig } from '@theia/application-package/lib/application-props';
|
||||
import {
|
||||
ElectronMainApplication as TheiaElectronMainApplication,
|
||||
ElectronMainExecutionParams,
|
||||
TheiaBrowserWindowOptions,
|
||||
} from '@theia/core/lib/electron-main/electron-main-application';
|
||||
import { SplashServiceImpl } from '../splash/splash-service-impl';
|
||||
import { ipcMain } from '@theia/core/shared/electron';
|
||||
import { URI } from '@theia/core/shared/vscode-uri';
|
||||
import * as electronRemoteMain from '@theia/core/electron-shared/@electron/remote/main';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import * as os from '@theia/core/lib/common/os';
|
||||
|
||||
app.commandLine.appendSwitch('disable-http-cache');
|
||||
|
||||
interface WorkspaceOptions {
|
||||
file: string
|
||||
x: number
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
isMaximized: boolean
|
||||
isFullScreen: boolean
|
||||
time: number
|
||||
}
|
||||
|
||||
const WORKSPACES = 'workspaces';
|
||||
|
||||
@injectable()
|
||||
export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
protected _windows: BrowserWindow[] = [];
|
||||
protected startup = false;
|
||||
protected openFilePromise = new Deferred();
|
||||
|
||||
@inject(SplashServiceImpl)
|
||||
protected readonly splashService: SplashServiceImpl;
|
||||
@@ -33,9 +48,106 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
// See: https://github.com/electron-userland/electron-builder/issues/2468
|
||||
// Regression in Theia: https://github.com/eclipse-theia/theia/issues/8701
|
||||
app.on('ready', () => app.setName(config.applicationName));
|
||||
this.attachFileAssociations();
|
||||
return super.start(config);
|
||||
}
|
||||
|
||||
attachFileAssociations() {
|
||||
// OSX: register open-file event
|
||||
if (os.isOSX) {
|
||||
app.on('open-file', async (event, uri) => {
|
||||
event.preventDefault();
|
||||
if (uri.endsWith('.ino') && await fs.pathExists(uri)) {
|
||||
this.openFilePromise.reject();
|
||||
await this.openSketch(dirname(uri));
|
||||
}
|
||||
});
|
||||
setTimeout(() => this.openFilePromise.resolve(), 500);
|
||||
} else {
|
||||
this.openFilePromise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
protected async isValidSketchPath(uri: string): Promise<boolean | undefined> {
|
||||
return typeof uri === 'string' && await fs.pathExists(uri);
|
||||
}
|
||||
|
||||
protected async launch(params: ElectronMainExecutionParams): Promise<void> {
|
||||
try {
|
||||
// When running on MacOS, we either have to wait until
|
||||
// 1. The `open-file` command has been received by the app, rejecting the promise
|
||||
// 2. A short timeout resolves the promise automatically, falling back to the usual app launch
|
||||
await this.openFilePromise.promise;
|
||||
} catch {
|
||||
// Application has received the `open-file` event and will skip the default application launch
|
||||
return;
|
||||
}
|
||||
|
||||
if (!os.isOSX && await this.launchFromArgs(params)) {
|
||||
// Application has received a file in its arguments and will skip the default application launch
|
||||
return;
|
||||
}
|
||||
|
||||
this.startup = true;
|
||||
const workspaces: WorkspaceOptions[] | undefined = this.electronStore.get(WORKSPACES);
|
||||
let useDefault = true;
|
||||
if (workspaces && workspaces.length > 0) {
|
||||
for (const workspace of workspaces) {
|
||||
if (await this.isValidSketchPath(workspace.file)) {
|
||||
useDefault = false;
|
||||
await this.openSketch(workspace);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.startup = false;
|
||||
if (useDefault) {
|
||||
super.launch(params);
|
||||
}
|
||||
}
|
||||
|
||||
protected async launchFromArgs(params: ElectronMainExecutionParams): Promise<boolean> {
|
||||
// Copy to prevent manipulation of original array
|
||||
const argCopy = [...params.argv];
|
||||
let uri: string | undefined;
|
||||
for (const possibleUri of argCopy) {
|
||||
if (possibleUri.endsWith('.ino') && await this.isValidSketchPath(possibleUri)) {
|
||||
uri = possibleUri;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uri) {
|
||||
await this.openSketch(dirname(uri));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected async openSketch(workspace: WorkspaceOptions | string): Promise<BrowserWindow> {
|
||||
const options = await this.getLastWindowOptions();
|
||||
let file: string;
|
||||
if (typeof workspace === 'object') {
|
||||
options.x = workspace.x;
|
||||
options.y = workspace.y;
|
||||
options.width = workspace.width;
|
||||
options.height = workspace.height;
|
||||
options.isMaximized = workspace.isMaximized;
|
||||
options.isFullScreen = workspace.isFullScreen;
|
||||
file = workspace.file;
|
||||
} else {
|
||||
file = workspace;
|
||||
}
|
||||
const [uri, electronWindow] = await Promise.all([this.createWindowUri(), this.createWindow(options)]);
|
||||
electronWindow.loadURL(uri.withFragment(encodeURI(file)).toString(true));
|
||||
return electronWindow;
|
||||
}
|
||||
|
||||
protected avoidOverlap(options: TheiaBrowserWindowOptions): TheiaBrowserWindowOptions {
|
||||
if (this.startup) {
|
||||
return options;
|
||||
}
|
||||
return super.avoidOverlap(options);
|
||||
}
|
||||
|
||||
protected getTitleBarStyle(): 'native' | 'custom' {
|
||||
return 'native';
|
||||
}
|
||||
@@ -50,6 +162,14 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
});
|
||||
}
|
||||
|
||||
protected async onSecondInstance(event: ElectronEvent, argv: string[], cwd: string): Promise<void> {
|
||||
if (!os.isOSX && await this.launchFromArgs({ cwd, argv, secondInstance: true })) {
|
||||
// Application has received a file in its arguments
|
||||
return;
|
||||
}
|
||||
super.onSecondInstance(event, argv, cwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this rather than creating `BrowserWindow` instances from scratch, since some security parameters need to be set, this method will do it.
|
||||
*
|
||||
@@ -148,10 +268,12 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
}
|
||||
}
|
||||
});
|
||||
this.attachClosedWorkspace(electronWindow);
|
||||
this.attachReadyToShow(electronWindow);
|
||||
this.attachSaveWindowState(electronWindow);
|
||||
this.attachGlobalShortcuts(electronWindow);
|
||||
this.restoreMaximizedState(electronWindow, options);
|
||||
electronRemoteMain.enable(electronWindow.webContents);
|
||||
return electronWindow;
|
||||
}
|
||||
|
||||
@@ -218,6 +340,44 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
|
||||
}
|
||||
}
|
||||
|
||||
protected closedWorkspaces: WorkspaceOptions[] = [];
|
||||
|
||||
protected attachClosedWorkspace(window: BrowserWindow): void {
|
||||
// Since the `before-quit` event is only fired when closing the *last* window
|
||||
// We need to keep track of recently closed windows/workspaces manually
|
||||
window.on('close', () => {
|
||||
const url = window.webContents.getURL();
|
||||
const workspace = URI.parse(url).fragment;
|
||||
if (workspace) {
|
||||
const workspaceUri = URI.file(workspace);
|
||||
const bounds = window.getNormalBounds();
|
||||
this.closedWorkspaces.push({
|
||||
...bounds,
|
||||
isMaximized: window.isMaximized(),
|
||||
isFullScreen: window.isFullScreen(),
|
||||
file: workspaceUri.fsPath,
|
||||
time: Date.now()
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected onWillQuit(event: Electron.Event): void {
|
||||
// Only add workspaces which were closed within the last second (1000 milliseconds)
|
||||
const threshold = Date.now() - 1000;
|
||||
const visited = new Set<string>();
|
||||
const workspaces = this.closedWorkspaces.filter(e => {
|
||||
if (e.time < threshold || visited.has(e.file)) {
|
||||
return false;
|
||||
}
|
||||
visited.add(e.file);
|
||||
return true;
|
||||
}).sort((a, b) => a.file.localeCompare(b.file));
|
||||
this.electronStore.set(WORKSPACES, workspaces);
|
||||
|
||||
super.onWillQuit(event);
|
||||
}
|
||||
|
||||
get windows(): BrowserWindow[] {
|
||||
return this._windows.slice();
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import {
|
||||
} from '../common/protocol/arduino-firmware-uploader';
|
||||
import { injectable, inject, named } from 'inversify';
|
||||
import { ExecutableService } from '../common/protocol';
|
||||
import { SerialService } from '../common/protocol/serial-service';
|
||||
import { getExecPath, spawnCommand } from './exec-util';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
|
||||
@@ -18,6 +19,9 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
|
||||
@named('fwuploader')
|
||||
protected readonly logger: ILogger;
|
||||
|
||||
@inject(SerialService)
|
||||
protected readonly serialService: SerialService;
|
||||
|
||||
protected onError(error: any): void {
|
||||
this.logger.error(error);
|
||||
}
|
||||
@@ -66,15 +70,26 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
|
||||
}
|
||||
|
||||
async flash(firmware: FirmwareInfo, port: string): Promise<string> {
|
||||
return await this.runCommand([
|
||||
'firmware',
|
||||
'flash',
|
||||
'--fqbn',
|
||||
firmware.board_fqbn,
|
||||
'--address',
|
||||
port,
|
||||
'--module',
|
||||
`${firmware.module}@${firmware.firmware_version}`,
|
||||
]);
|
||||
let output;
|
||||
try {
|
||||
this.serialService.uploadInProgress = true;
|
||||
await this.serialService.disconnect();
|
||||
output = await this.runCommand([
|
||||
'firmware',
|
||||
'flash',
|
||||
'--fqbn',
|
||||
firmware.board_fqbn,
|
||||
'--address',
|
||||
port,
|
||||
'--module',
|
||||
`${firmware.module}@${firmware.firmware_version}`,
|
||||
]);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
this.serialService.uploadInProgress = false;
|
||||
this.serialService.connectSerialIfRequired();
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -203,7 +203,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
|
||||
// #endregion Theia customizations
|
||||
|
||||
// Monitor client provider per connected frontend.
|
||||
// Serial client provider per connected frontend.
|
||||
bind(ConnectionContainerModule).toConstantValue(
|
||||
ConnectionContainerModule.create(({ bind, bindBackendService }) => {
|
||||
bind(MonitorClientProvider).toSelf().inSingletonScope();
|
||||
@@ -260,17 +260,14 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
)
|
||||
.inSingletonScope();
|
||||
|
||||
bind(ArduinoFirmwareUploaderImpl).toSelf().inSingletonScope();
|
||||
bind(ArduinoFirmwareUploader).toService(ArduinoFirmwareUploaderImpl);
|
||||
bind(BackendApplicationContribution).toService(ArduinoFirmwareUploaderImpl);
|
||||
bind(ConnectionHandler)
|
||||
.toDynamicValue(
|
||||
(context) =>
|
||||
new JsonRpcConnectionHandler(ArduinoFirmwareUploaderPath, () =>
|
||||
context.container.get(ArduinoFirmwareUploader)
|
||||
)
|
||||
)
|
||||
.inSingletonScope();
|
||||
// Singleton per BE, each FE connection gets its proxy.
|
||||
bind(ConnectionContainerModule).toConstantValue(
|
||||
ConnectionContainerModule.create(({ bind, bindBackendService }) => {
|
||||
bind(ArduinoFirmwareUploaderImpl).toSelf().inSingletonScope();
|
||||
bind(ArduinoFirmwareUploader).toService(ArduinoFirmwareUploaderImpl);
|
||||
bindBackendService(ArduinoFirmwareUploaderPath, ArduinoFirmwareUploader);
|
||||
})
|
||||
);
|
||||
|
||||
// Logger for the Arduino daemon
|
||||
bind(ILogger)
|
||||
|
@@ -124,8 +124,22 @@ export class BoardDiscovery extends CoreClientAware {
|
||||
|
||||
const address = (detectedPort as any).getPort().getAddress();
|
||||
const protocol = (detectedPort as any).getPort().getProtocol();
|
||||
// Different discoveries can detect the same port with different
|
||||
// protocols, so we consider the combination of address and protocol
|
||||
// to be the id of a certain port to distinguish it from others.
|
||||
// If we'd use only the address of a port to store it in a map
|
||||
// we can have conflicts the same port is found with multiple
|
||||
// protocols.
|
||||
const portID = `${address}|${protocol}`;
|
||||
const label = (detectedPort as any).getPort().getLabel();
|
||||
const port = { address, protocol, label };
|
||||
const protocolLabel = (detectedPort as any).getPort().getProtocolLabel();
|
||||
const port = {
|
||||
id: portID,
|
||||
address,
|
||||
addressLabel: label,
|
||||
protocol,
|
||||
protocolLabel,
|
||||
};
|
||||
const boards: Board[] = [];
|
||||
for (const item of detectedPort.getMatchingBoardsList()) {
|
||||
boards.push({
|
||||
@@ -136,23 +150,21 @@ export class BoardDiscovery extends CoreClientAware {
|
||||
}
|
||||
|
||||
if (eventType === 'add') {
|
||||
if (newState[port.address]) {
|
||||
const [, knownBoards] = newState[port.address];
|
||||
if (newState[portID]) {
|
||||
const [, knownBoards] = newState[portID];
|
||||
console.warn(
|
||||
`Port '${
|
||||
port.address
|
||||
}' was already available. Known boards before override: ${JSON.stringify(
|
||||
`Port '${Port.toString(port)}' was already available. Known boards before override: ${JSON.stringify(
|
||||
knownBoards
|
||||
)}`
|
||||
);
|
||||
}
|
||||
newState[port.address] = [port, boards];
|
||||
newState[portID] = [port, boards];
|
||||
} else if (eventType === 'remove') {
|
||||
if (!newState[port.address]) {
|
||||
console.warn(`Port '${port.address}' was not available. Skipping`);
|
||||
if (!newState[portID]) {
|
||||
console.warn(`Port '${Port.toString(port)}' was not available. Skipping`);
|
||||
return;
|
||||
}
|
||||
delete newState[port.address];
|
||||
delete newState[portID];
|
||||
}
|
||||
|
||||
const oldAvailablePorts = this.getAvailablePorts(oldState);
|
||||
@@ -179,8 +191,8 @@ export class BoardDiscovery extends CoreClientAware {
|
||||
|
||||
getAttachedBoards(state: AvailablePorts = this.state): Board[] {
|
||||
const attachedBoards: Board[] = [];
|
||||
for (const address of Object.keys(state)) {
|
||||
const [, boards] = state[address];
|
||||
for (const portID of Object.keys(state)) {
|
||||
const [, boards] = state[portID];
|
||||
attachedBoards.push(...boards);
|
||||
}
|
||||
return attachedBoards;
|
||||
@@ -188,8 +200,8 @@ export class BoardDiscovery extends CoreClientAware {
|
||||
|
||||
getAvailablePorts(state: AvailablePorts = this.state): Port[] {
|
||||
const availablePorts: Port[] = [];
|
||||
for (const address of Object.keys(state)) {
|
||||
const [port] = state[address];
|
||||
for (const portID of Object.keys(state)) {
|
||||
const [port] = state[portID];
|
||||
availablePorts.push(port);
|
||||
}
|
||||
return availablePorts;
|
||||
|
@@ -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.
|
||||
|
@@ -96,7 +96,7 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
e.details
|
||||
);
|
||||
this.responseService.appendToOutput({
|
||||
chunk: `${errorMessage}}\n`,
|
||||
chunk: `${errorMessage}\n`,
|
||||
severity: 'error',
|
||||
});
|
||||
throw new Error(errorMessage);
|
||||
@@ -159,8 +159,9 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
const p = new Port();
|
||||
if (port) {
|
||||
p.setAddress(port.address);
|
||||
p.setLabel(port.label || '');
|
||||
p.setLabel(port.addressLabel);
|
||||
p.setProtocol(port.protocol);
|
||||
p.setProtocolLabel(port.protocolLabel);
|
||||
}
|
||||
req.setPort(p);
|
||||
if (programmer) {
|
||||
@@ -229,8 +230,9 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
const p = new Port();
|
||||
if (port) {
|
||||
p.setAddress(port.address);
|
||||
p.setLabel(port.label || '');
|
||||
p.setLabel(port.addressLabel);
|
||||
p.setProtocol(port.protocol);
|
||||
p.setProtocolLabel(port.protocolLabel);
|
||||
}
|
||||
burnReq.setPort(p);
|
||||
if (programmer) {
|
||||
|
@@ -17,7 +17,7 @@ export class ExecutableServiceImpl implements ExecutableService {
|
||||
}> {
|
||||
const [ls, clangd, cli, fwuploader] = await Promise.all([
|
||||
getExecPath('arduino-language-server', this.onError.bind(this)),
|
||||
getExecPath('clangd', this.onError.bind(this), undefined, true),
|
||||
getExecPath('clangd', this.onError.bind(this), undefined),
|
||||
getExecPath('arduino-cli', this.onError.bind(this)),
|
||||
getExecPath('arduino-fwuploader', this.onError.bind(this)),
|
||||
]);
|
||||
|
@@ -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}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ import {
|
||||
MonitorConfig as GrpcMonitorConfig,
|
||||
} from '../cli-protocol/cc/arduino/cli/monitor/v1/monitor_pb';
|
||||
import { MonitorClientProvider } from './monitor-client-provider';
|
||||
import { Board, Port } from '../../common/protocol/boards-service';
|
||||
import { Board } from '../../common/protocol/boards-service';
|
||||
import { WebSocketService } from '../web-socket/web-socket-service';
|
||||
import { SerialPlotter } from '../../browser/serial/plotter/protocol';
|
||||
import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
|
||||
@@ -88,7 +88,7 @@ export class SerialServiceImpl implements SerialService {
|
||||
|
||||
@inject(WebSocketService)
|
||||
protected readonly webSocketService: WebSocketService
|
||||
) {}
|
||||
) { }
|
||||
|
||||
async isSerialPortOpen(): Promise<boolean> {
|
||||
return !!this.serialConnection;
|
||||
@@ -153,7 +153,7 @@ export class SerialServiceImpl implements SerialService {
|
||||
this.logger.info(
|
||||
`>>> Creating serial connection for ${Board.toString(
|
||||
this.serialConfig.board
|
||||
)} on port ${Port.toString(this.serialConfig.port)}...`
|
||||
)} on port ${this.serialConfig.port.address}...`
|
||||
);
|
||||
|
||||
if (this.serialConnection) {
|
||||
@@ -225,7 +225,7 @@ export class SerialServiceImpl implements SerialService {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
}
|
||||
);
|
||||
|
||||
@@ -272,12 +272,12 @@ export class SerialServiceImpl implements SerialService {
|
||||
serialConnection.duplex.write(req, () => {
|
||||
const boardName = this.serialConfig?.board
|
||||
? Board.toString(this.serialConfig.board, {
|
||||
useFqbn: false,
|
||||
})
|
||||
useFqbn: false,
|
||||
})
|
||||
: 'unknown board';
|
||||
|
||||
const portName = this.serialConfig?.port
|
||||
? Port.toString(this.serialConfig.port)
|
||||
? this.serialConfig.port.address
|
||||
: 'unknown port';
|
||||
this.logger.info(
|
||||
`<<< Serial connection created for ${boardName} on port ${portName}.`
|
||||
@@ -330,7 +330,7 @@ export class SerialServiceImpl implements SerialService {
|
||||
this.logger.info(
|
||||
`<<< Disposed serial connection for ${Board.toString(config.board, {
|
||||
useFqbn: false,
|
||||
})} on port ${Port.toString(config.port)}.`
|
||||
})} on port ${config.port.address}.`
|
||||
);
|
||||
|
||||
duplex.cancel();
|
||||
|
@@ -4,11 +4,20 @@ import { Board, BoardsPackage, Port } from '../../../common/protocol';
|
||||
export const aBoard: Board = {
|
||||
fqbn: 'some:board:fqbn',
|
||||
name: 'Some Arduino Board',
|
||||
port: { address: '/lol/port1234', protocol: 'serial' },
|
||||
port: {
|
||||
id: '/lol/port1234|serial',
|
||||
address: '/lol/port1234',
|
||||
addressLabel: '/lol/port1234',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
},
|
||||
};
|
||||
export const aPort: Port = {
|
||||
id: aBoard.port!.id,
|
||||
address: aBoard.port!.address,
|
||||
addressLabel: aBoard.port!.addressLabel,
|
||||
protocol: aBoard.port!.protocol,
|
||||
protocolLabel: aBoard.port!.protocolLabel,
|
||||
};
|
||||
export const aBoardConfig: BoardsConfig.Config = {
|
||||
selectedBoard: aBoard,
|
||||
@@ -17,11 +26,20 @@ export const aBoardConfig: BoardsConfig.Config = {
|
||||
export const anotherBoard: Board = {
|
||||
fqbn: 'another:board:fqbn',
|
||||
name: 'Another Arduino Board',
|
||||
port: { address: '/kek/port5678', protocol: 'serial' },
|
||||
port: {
|
||||
id: '/kek/port5678|serial',
|
||||
address: '/kek/port5678',
|
||||
addressLabel: '/kek/port5678',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
},
|
||||
};
|
||||
export const anotherPort: Port = {
|
||||
id: anotherBoard.port!.id,
|
||||
address: anotherBoard.port!.address,
|
||||
addressLabel: anotherBoard.port!.addressLabel,
|
||||
protocol: anotherBoard.port!.protocol,
|
||||
protocolLabel: anotherBoard.port!.protocolLabel,
|
||||
};
|
||||
export const anotherBoardConfig: BoardsConfig.Config = {
|
||||
selectedBoard: anotherBoard,
|
||||
|
@@ -22,7 +22,7 @@ describe('getExecPath', () => {
|
||||
});
|
||||
|
||||
it('should resolve clangd', async () => {
|
||||
const actual = await getExecPath('clangd', onError, '--version', true);
|
||||
const actual = await getExecPath('clangd', onError, '--version');
|
||||
const expected = os.platform() === 'win32' ? '\\clangd.exe' : '/clangd';
|
||||
expect(actual).to.endsWith(expected);
|
||||
});
|
||||
|
@@ -86,7 +86,7 @@ describe('SerialServiceImpl', () => {
|
||||
|
||||
context('when a disconnection is requested', () => {
|
||||
const sandbox = createSandbox();
|
||||
beforeEach(() => {});
|
||||
beforeEach(() => { });
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
@@ -132,11 +132,11 @@ describe('SerialServiceImpl', () => {
|
||||
return {
|
||||
streamingOpen: () => {
|
||||
return {
|
||||
on: (str: string, cb: any) => {},
|
||||
on: (str: string, cb: any) => { },
|
||||
write: (chunk: any, cb: any) => {
|
||||
cb();
|
||||
},
|
||||
cancel: () => {},
|
||||
cancel: () => { },
|
||||
};
|
||||
},
|
||||
} as MonitorServiceClient;
|
||||
@@ -146,7 +146,7 @@ describe('SerialServiceImpl', () => {
|
||||
|
||||
await subject.setSerialConfig({
|
||||
board: { name: 'test' },
|
||||
port: { address: 'test', protocol: 'test' },
|
||||
port: { id: 'test|test', address: 'test', addressLabel: 'test', protocol: 'test', protocolLabel: 'test' },
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -1,29 +1,29 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "browser-app",
|
||||
"version": "2.0.0-rc2",
|
||||
"version": "2.0.0-rc4",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@theia/core": "1.19.0",
|
||||
"@theia/debug": "1.19.0",
|
||||
"@theia/editor": "1.19.0",
|
||||
"@theia/editor-preview": "1.19.0",
|
||||
"@theia/file-search": "1.19.0",
|
||||
"@theia/filesystem": "1.19.0",
|
||||
"@theia/keymaps": "1.19.0",
|
||||
"@theia/messages": "1.19.0",
|
||||
"@theia/monaco": "1.19.0",
|
||||
"@theia/navigator": "1.19.0",
|
||||
"@theia/plugin-ext": "1.19.0",
|
||||
"@theia/plugin-ext-vscode": "1.19.0",
|
||||
"@theia/preferences": "1.19.0",
|
||||
"@theia/process": "1.19.0",
|
||||
"@theia/terminal": "1.19.0",
|
||||
"@theia/workspace": "1.19.0",
|
||||
"arduino-ide-extension": "2.0.0-rc2"
|
||||
"@theia/core": "1.22.1",
|
||||
"@theia/debug": "1.22.1",
|
||||
"@theia/editor": "1.22.1",
|
||||
"@theia/editor-preview": "1.22.1",
|
||||
"@theia/file-search": "1.22.1",
|
||||
"@theia/filesystem": "1.22.1",
|
||||
"@theia/keymaps": "1.22.1",
|
||||
"@theia/messages": "1.22.1",
|
||||
"@theia/monaco": "1.22.1",
|
||||
"@theia/navigator": "1.22.1",
|
||||
"@theia/plugin-ext": "1.22.1",
|
||||
"@theia/plugin-ext-vscode": "1.22.1",
|
||||
"@theia/preferences": "1.22.1",
|
||||
"@theia/process": "1.22.1",
|
||||
"@theia/terminal": "1.22.1",
|
||||
"@theia/workspace": "1.22.1",
|
||||
"arduino-ide-extension": "2.0.0-rc4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0"
|
||||
"@theia/cli": "1.22.1"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "theia build --mode development",
|
||||
@@ -60,4 +60,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ Arduino IDE provides a Remote Sketchbook feature that can be used to upload sket
|
||||
|
||||
|
||||
In order to use this feature, a user must be registered on [Arduino Cloud](https://store.arduino.cc/digital/create) and logged in.
|
||||
This feature is completely optional and can be disabled in the IDE via _"File > Advanced > Hide Remote Sketchbook"_ menu item.
|
||||
This feature is completely optional and can be disabled in the IDE via the _"File > Advanced > Hide Remote Sketchbook"_ menu item.
|
||||
|
||||
## Developer guide
|
||||
A developer could use the content of this repo to create a customized version of this feature and implement a different remote storage as follows:
|
||||
|
@@ -2,19 +2,18 @@
|
||||
|
||||
Building the Pro IDE on Linux `armv7l` (aka `armhf`) and `aarch64` (aka `arm64`):
|
||||
|
||||
1. Install Node.js 10.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):
|
||||
@@ -42,10 +41,10 @@ Building the Pro IDE on Linux `armv7l` (aka `armhf`) and `aarch64` (aka `arm64`)
|
||||
- `libx11-dev`, and
|
||||
- `libxkbfile-dev`
|
||||
|
||||
4. [Build it](https://github.com/bcmi-labs/arduino-editor#build-from-source) from the source:
|
||||
4. [Build it](../../BUILDING.md#build-from-source) from the source:
|
||||
```
|
||||
git clone https://github.com/bcmi-labs/arduino-editor.git \
|
||||
&& cd arduino-editor \
|
||||
git clone https://github.com/arduino/arduino-ide.git \
|
||||
&& cd arduino-ide \
|
||||
&& yarn \
|
||||
&& yarn rebuild:electron \
|
||||
&& yarn --cwd ./electron-app start
|
||||
|
@@ -1,6 +1,6 @@
|
||||
### Building and start the app from the sources on Ubuntu Linux
|
||||
|
||||
Tested and verified on Ubuntu 18.04.4. The source will be checked out to `~/dev/git/arduino-editor`.
|
||||
Tested and verified on Ubuntu 18.04.4. The source will be checked out to `~/dev/git/arduino-ide`.
|
||||
|
||||
```
|
||||
#!/bin/bash -i
|
||||
@@ -18,16 +18,16 @@ 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 \
|
||||
&& mkdir -p ~/dev/git/ \
|
||||
&& rm -rf ~/dev/git/arduino-editor \
|
||||
&& git clone --depth 1 https://github.com/bcmi-labs/arduino-editor.git ~/dev/git/arduino-editor \
|
||||
&& yarn --cwd ~/dev/git/arduino-editor \
|
||||
&& yarn --cwd ~/dev/git/arduino-editor rebuild:electron \
|
||||
&& yarn --cwd ~/dev/git/arduino-editor/electron-app start
|
||||
&& rm -rf ~/dev/git/arduino-ide \
|
||||
&& git clone --depth 1 https://github.com/arduino/arduino-ide.git ~/dev/git/arduino-ide \
|
||||
&& yarn --cwd ~/dev/git/arduino-ide \
|
||||
&& yarn --cwd ~/dev/git/arduino-ide rebuild:electron \
|
||||
&& yarn --cwd ~/dev/git/arduino-ide/electron-app start
|
||||
```
|
||||
|
@@ -1,31 +1,32 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "electron-app",
|
||||
"version": "2.0.0-rc2",
|
||||
"version": "2.0.0-rc4",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"main": "src-gen/frontend/electron-main.js",
|
||||
"dependencies": {
|
||||
"@theia/core": "1.19.0",
|
||||
"@theia/debug": "1.19.0",
|
||||
"@theia/editor": "1.19.0",
|
||||
"@theia/editor-preview": "1.19.0",
|
||||
"@theia/electron": "1.19.0",
|
||||
"@theia/file-search": "1.19.0",
|
||||
"@theia/filesystem": "1.19.0",
|
||||
"@theia/keymaps": "1.19.0",
|
||||
"@theia/messages": "1.19.0",
|
||||
"@theia/monaco": "1.19.0",
|
||||
"@theia/navigator": "1.19.0",
|
||||
"@theia/plugin-ext": "1.19.0",
|
||||
"@theia/plugin-ext-vscode": "1.19.0",
|
||||
"@theia/preferences": "1.19.0",
|
||||
"@theia/process": "1.19.0",
|
||||
"@theia/terminal": "1.19.0",
|
||||
"@theia/workspace": "1.19.0",
|
||||
"arduino-ide-extension": "2.0.0-rc2"
|
||||
"@theia/core": "1.22.1",
|
||||
"@theia/debug": "1.22.1",
|
||||
"@theia/editor": "1.22.1",
|
||||
"@theia/editor-preview": "1.22.1",
|
||||
"@theia/electron": "1.22.1",
|
||||
"@theia/file-search": "1.22.1",
|
||||
"@theia/filesystem": "1.22.1",
|
||||
"@theia/keymaps": "1.22.1",
|
||||
"@theia/messages": "1.22.1",
|
||||
"@theia/monaco": "1.22.1",
|
||||
"@theia/navigator": "1.22.1",
|
||||
"@theia/plugin-ext": "1.22.1",
|
||||
"@theia/plugin-ext-vscode": "1.22.1",
|
||||
"@theia/preferences": "1.22.1",
|
||||
"@theia/process": "1.22.1",
|
||||
"@theia/terminal": "1.22.1",
|
||||
"@theia/workspace": "1.22.1",
|
||||
"arduino-ide-extension": "2.0.0-rc4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0"
|
||||
"@theia/cli": "1.22.1",
|
||||
"electron": "^15.3.5"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "theia build --mode development",
|
||||
@@ -63,4 +64,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,27 +2,31 @@ const isCI = require('is-ci');
|
||||
const { notarize } = require('electron-notarize');
|
||||
|
||||
exports.default = async function notarizing(context) {
|
||||
if (!isCI) {
|
||||
console.log('Skipping notarization: not on CI.');
|
||||
return;
|
||||
}
|
||||
if (process.env.IS_FORK === 'true') {
|
||||
console.log('Skipping the app notarization: building from a fork.');
|
||||
return;
|
||||
}
|
||||
const { electronPlatformName, appOutDir } = context;
|
||||
if (electronPlatformName !== 'darwin') {
|
||||
return;
|
||||
}
|
||||
if (!isCI) {
|
||||
console.log('Skipping notarization: not on CI.');
|
||||
return;
|
||||
}
|
||||
if (process.env.IS_FORK === 'true') {
|
||||
console.log('Skipping the app notarization: building from a fork.');
|
||||
return;
|
||||
}
|
||||
const { electronPlatformName, appOutDir } = context;
|
||||
if (electronPlatformName !== 'darwin') {
|
||||
return;
|
||||
}
|
||||
|
||||
const appName = context.packager.appInfo.productFilename;
|
||||
const appBundleId = context.packager.config.appId;
|
||||
console.log(`>>> Notarizing ${appBundleId} at ${appOutDir}/${appName}.app...`);
|
||||
const appName = context.packager.appInfo.productFilename;
|
||||
const appBundleId = context.packager.config.appId;
|
||||
console.log(
|
||||
`>>> Notarizing ${appBundleId} at ${appOutDir}/${appName}.app...`
|
||||
);
|
||||
|
||||
return await notarize({
|
||||
appBundleId,
|
||||
appPath: `${appOutDir}/${appName}.app`,
|
||||
appleId: process.env.AC_USERNAME,
|
||||
appleIdPassword: process.env.AC_PASSWORD,
|
||||
});
|
||||
await notarize({
|
||||
appBundleId,
|
||||
appPath: `${appOutDir}/${appName}.app`,
|
||||
appleId: process.env.AC_USERNAME,
|
||||
appleIdPassword: process.env.AC_PASSWORD,
|
||||
teamId: process.env.AC_TEAM_ID,
|
||||
tool: 'notarytool',
|
||||
});
|
||||
};
|
||||
|
@@ -3,16 +3,18 @@
|
||||
"author": "Arduino SA",
|
||||
"resolutions": {
|
||||
"**/fs-extra": "^4.0.3",
|
||||
"electron-builder": "22.7.0"
|
||||
"electron-builder": "22.10.5",
|
||||
"find-git-exec": "0.0.4",
|
||||
"dugite-extra": "0.1.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-log-rotate": "^0.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.19.0",
|
||||
"@theia/cli": "1.22.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"electron-builder": "22.7.0",
|
||||
"electron-notarize": "^0.3.0",
|
||||
"electron-builder": "22.10.5",
|
||||
"electron-notarize": "^1.1.1",
|
||||
"is-ci": "^2.0.0",
|
||||
"ncp": "^2.0.0",
|
||||
"shelljs": "^0.8.3"
|
||||
@@ -20,13 +22,14 @@
|
||||
"scripts": {
|
||||
"build": "yarn download:plugins && theia build --mode development && yarn patch",
|
||||
"build:publish": "yarn download:plugins && theia build --mode production && yarn patch",
|
||||
"rebuild": "yarn theia rebuild:electron",
|
||||
"package": "cross-env DEBUG=* && electron-builder --publish=never",
|
||||
"package:publish": "cross-env DEBUG=* && electron-builder --publish=always",
|
||||
"download:plugins": "theia download:plugins",
|
||||
"patch": "ncp ./patch/main.js ./src-gen/backend/main.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.14.1 <13"
|
||||
"node": ">=14.0.0 <15"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -51,9 +54,18 @@
|
||||
"build": {
|
||||
"productName": "Arduino IDE",
|
||||
"asar": false,
|
||||
"detectUpdateChannel": false,
|
||||
"generateUpdatesFilesForAllChannels": true,
|
||||
"npmRebuild": false,
|
||||
"directories": {
|
||||
"buildResources": "resources"
|
||||
},
|
||||
"fileAssociations": [
|
||||
{
|
||||
"ext": "ino",
|
||||
"role": "Editor"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
"src-gen",
|
||||
"lib",
|
||||
@@ -65,8 +77,7 @@
|
||||
"!node_modules/@theia/**/lib/*browser/*",
|
||||
"node_modules/@theia/core/lib/browser/*",
|
||||
"!node_modules/@typefox/monaco-editor-core/*",
|
||||
"!node_modules/oniguruma/*",
|
||||
"!node_modules/onigasm/*"
|
||||
"!node_modules/electron/**"
|
||||
],
|
||||
"extraResources": [
|
||||
{
|
||||
@@ -86,16 +97,12 @@
|
||||
"hardenedRuntime": true,
|
||||
"gatekeeperAssess": false,
|
||||
"entitlements": "resources/entitlements.mac.plist",
|
||||
"entitlementsInherit": "resources/entitlements.mac.plist",
|
||||
"target": [
|
||||
"dmg"
|
||||
]
|
||||
"entitlementsInherit": "resources/entitlements.mac.plist"
|
||||
},
|
||||
"linux": {
|
||||
"target": [
|
||||
{
|
||||
"target": "zip"
|
||||
}
|
||||
"zip",
|
||||
"AppImage"
|
||||
],
|
||||
"category": "Development",
|
||||
"icon": "resources/icons"
|
||||
@@ -139,9 +146,9 @@
|
||||
"theiaPluginsDir": "plugins",
|
||||
"theiaPlugins": {
|
||||
"vscode-builtin-cpp": "https://open-vsx.org/api/vscode/cpp/1.52.1/file/vscode.cpp-1.52.1.vsix",
|
||||
"vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.1.vsix",
|
||||
"vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.2.vsix",
|
||||
"vscode-builtin-json": "https://open-vsx.org/api/vscode/json/1.46.1/file/vscode.json-1.46.1.vsix",
|
||||
"vscode-builtin-json-language-features": "https://open-vsx.org/api/vscode/json-language-features/1.46.1/file/vscode.json-language-features-1.46.1.vsix",
|
||||
"cortex-debug": "https://open-vsx.org/api/marus25/cortex-debug/0.3.10/file/marus25.cortex-debug-0.3.10.vsix"
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,87 +8,106 @@ const dateFormat = require('dateformat');
|
||||
const { isNightly, isRelease, git } = require('./utils');
|
||||
|
||||
function artifactName() {
|
||||
const { platform, arch } = process;
|
||||
const id = (() => {
|
||||
if (isRelease) {
|
||||
return getVersion();
|
||||
} else if (isNightly) {
|
||||
return `nightly-${timestamp()}`
|
||||
} else {
|
||||
return getVersion();
|
||||
}
|
||||
})();
|
||||
const name = 'arduino-ide';
|
||||
switch (platform) {
|
||||
case 'win32': {
|
||||
if (arch === 'x64') {
|
||||
return `${name}_${id}_Windows_64bit.\$\{ext}`;
|
||||
}
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
case 'darwin': {
|
||||
return `${name}_${id}_macOS_64bit.\$\{ext}`;
|
||||
}
|
||||
case 'linux': {
|
||||
switch (arch) {
|
||||
case 'arm': {
|
||||
return `${name}_${id}_Linux_ARMv7.\$\{ext}`;
|
||||
}
|
||||
case 'arm64': {
|
||||
return `${name}_${id}_Linux_ARM64.\$\{ext}`;
|
||||
}
|
||||
case 'x64': {
|
||||
return `${name}_${id}_Linux_64bit.\$\{ext}`;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
default: throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
const { platform, arch } = process;
|
||||
const id = (() => {
|
||||
if (isRelease) {
|
||||
return getVersion();
|
||||
} else if (isNightly) {
|
||||
return `nightly-${timestamp()}`;
|
||||
} else {
|
||||
return getVersion();
|
||||
}
|
||||
})();
|
||||
const name = 'arduino-ide';
|
||||
switch (platform) {
|
||||
case 'win32': {
|
||||
if (arch === 'x64') {
|
||||
return `${name}_${id}_Windows_64bit.\$\{ext}`;
|
||||
}
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
case 'darwin': {
|
||||
return `${name}_${id}_macOS_64bit.\$\{ext}`;
|
||||
}
|
||||
case 'linux': {
|
||||
switch (arch) {
|
||||
case 'arm': {
|
||||
return `${name}_${id}_Linux_ARMv7.\$\{ext}`;
|
||||
}
|
||||
case 'arm64': {
|
||||
return `${name}_${id}_Linux_ARM64.\$\{ext}`;
|
||||
}
|
||||
case 'x64': {
|
||||
return `${name}_${id}_Linux_64bit.\$\{ext}`;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
|
||||
}
|
||||
}
|
||||
|
||||
function electronPlatform() {
|
||||
switch (process.platform) {
|
||||
case 'win32': {
|
||||
return 'win';
|
||||
}
|
||||
case 'darwin': {
|
||||
return 'mac';
|
||||
}
|
||||
case 'linux': {
|
||||
return 'linux';
|
||||
}
|
||||
default: throw new Error(`Unsupported platform: ${process.platform}.`);
|
||||
switch (process.platform) {
|
||||
case 'win32': {
|
||||
return 'win';
|
||||
}
|
||||
case 'darwin': {
|
||||
return 'mac';
|
||||
}
|
||||
case 'linux': {
|
||||
return 'linux';
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported platform: ${process.platform}.`);
|
||||
}
|
||||
}
|
||||
|
||||
function getVersion() {
|
||||
const repositoryRootPath = git('rev-parse --show-toplevel');
|
||||
let version = JSON.parse(fs.readFileSync(path.join(repositoryRootPath, 'package.json'), { encoding: 'utf8' })).version;
|
||||
const repositoryRootPath = git('rev-parse --show-toplevel');
|
||||
let version = JSON.parse(
|
||||
fs.readFileSync(path.join(repositoryRootPath, 'package.json'), {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
).version;
|
||||
if (!semver.valid(version)) {
|
||||
throw new Error(
|
||||
`Could not read version from root package.json. Version was: '${version}'.`
|
||||
);
|
||||
}
|
||||
if (!isRelease) {
|
||||
if (isNightly) {
|
||||
version = `${version}-nightly-${timestamp()}`;
|
||||
} else {
|
||||
version = `${version}-snapshot-${currentCommitish()}`;
|
||||
}
|
||||
if (!semver.valid(version)) {
|
||||
throw new Error(`Could not read version from root package.json. Version was: '${version}'.`);
|
||||
throw new Error(`Invalid patched version: '${version}'.`);
|
||||
}
|
||||
if (!isRelease) {
|
||||
if (isNightly) {
|
||||
version = `${version}-nightly.${timestamp()}`;
|
||||
} else {
|
||||
version = `${version}-snapshot.${currentCommitish()}`;
|
||||
}
|
||||
if (!semver.valid(version)) {
|
||||
throw new Error(`Invalid patched version: '${version}'.`);
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
function getChannel() {
|
||||
if (isRelease) {
|
||||
return 'stable';
|
||||
}
|
||||
if (isNightly) {
|
||||
return 'nightly';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function timestamp() {
|
||||
return dateFormat(new Date(), 'yyyymmdd');
|
||||
return dateFormat(new Date(), 'yyyymmdd');
|
||||
}
|
||||
|
||||
function currentCommitish() {
|
||||
return git('rev-parse --short HEAD');
|
||||
return git('rev-parse --short HEAD');
|
||||
}
|
||||
|
||||
// function currentBranch() {
|
||||
@@ -96,28 +115,38 @@ function currentCommitish() {
|
||||
// }
|
||||
|
||||
function generateTemplate(buildDate) {
|
||||
// do `export PUBLISH=true yarn package` if you want to mimic CI build locally.
|
||||
// const electronPublish = release || (isCI && currentBranch() === 'main') || process.env.PUBLISH === 'true';
|
||||
const version = getVersion();
|
||||
const productName = 'Arduino IDE';
|
||||
const name = 'arduino-ide';
|
||||
let customizations = {
|
||||
name,
|
||||
description: productName,
|
||||
version,
|
||||
build: {
|
||||
productName,
|
||||
appId: 'arduino.ProIDE',
|
||||
[electronPlatform()]: {
|
||||
artifactName: artifactName()
|
||||
}
|
||||
}
|
||||
};
|
||||
if (buildDate) {
|
||||
customizations = merge(customizations, { theia: { frontend: { config: { buildDate } } } });
|
||||
}
|
||||
const template = require('../build/template-package.json');
|
||||
return merge(template, customizations);
|
||||
// do `export PUBLISH=true yarn package` if you want to mimic CI build locally.
|
||||
// const electronPublish = release || (isCI && currentBranch() === 'main') || process.env.PUBLISH === 'true';
|
||||
const version = getVersion();
|
||||
const productName = 'Arduino IDE';
|
||||
const name = 'arduino-ide';
|
||||
const updateChannel = getChannel();
|
||||
let customizations = {
|
||||
name,
|
||||
description: productName,
|
||||
version,
|
||||
theia: {
|
||||
frontend: {
|
||||
config: {
|
||||
'arduino.ide.updateChannel': updateChannel,
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
productName,
|
||||
appId: 'cc.arduino.IDE2',
|
||||
[electronPlatform()]: {
|
||||
artifactName: artifactName(),
|
||||
},
|
||||
},
|
||||
};
|
||||
if (buildDate) {
|
||||
customizations = merge(customizations, {
|
||||
theia: { frontend: { config: { buildDate } } },
|
||||
});
|
||||
}
|
||||
const template = require('../build/template-package.json');
|
||||
return merge(template, customizations);
|
||||
}
|
||||
|
||||
module.exports = { generateTemplate };
|
||||
|
@@ -1,339 +1,504 @@
|
||||
//@ts-check
|
||||
|
||||
(async () => {
|
||||
const fs = require('fs');
|
||||
const join = require('path').join;
|
||||
const shell = require('shelljs');
|
||||
const glob = require('glob');
|
||||
const isCI = require('is-ci');
|
||||
shell.env.THEIA_ELECTRON_SKIP_REPLACE_FFMPEG = '1'; // Do not run the ffmpeg validation for the packager.
|
||||
shell.env.NODE_OPTIONS = '--max_old_space_size=4096'; // Increase heap size for the CI
|
||||
shell.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = 'true'; // Skip download and avoid `ERROR: Failed to download Chromium`.
|
||||
const template = require('./config').generateTemplate(
|
||||
new Date().toISOString()
|
||||
);
|
||||
const utils = require('./utils');
|
||||
const merge = require('deepmerge');
|
||||
const { isRelease, isElectronPublish, getChannelFile } = utils;
|
||||
const { version } = template;
|
||||
const { productName } = template.build;
|
||||
|
||||
const fs = require('fs');
|
||||
const join = require('path').join;
|
||||
const shell = require('shelljs');
|
||||
const glob = require('glob');
|
||||
const isCI = require('is-ci');
|
||||
shell.env.THEIA_ELECTRON_SKIP_REPLACE_FFMPEG = '1'; // Do not run the ffmpeg validation for the packager.
|
||||
shell.env.NODE_OPTIONS = '--max_old_space_size=4096'; // Increase heap size for the CI
|
||||
shell.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = 'true'; // Skip download and avoid `ERROR: Failed to download Chromium`.
|
||||
const template = require('./config').generateTemplate(new Date().toISOString());
|
||||
const utils = require('./utils');
|
||||
const merge = require('deepmerge');
|
||||
const { isRelease, isElectronPublish } = utils;
|
||||
const { version } = template;
|
||||
const { productName } = template.build;
|
||||
echo(`📦 Building ${isRelease ? 'release ' : ''}version '${version}'...`);
|
||||
|
||||
echo(`📦 Building ${isRelease ? 'release ' : ''}version '${version}'...`);
|
||||
const workingCopy = 'working-copy';
|
||||
|
||||
const workingCopy = 'working-copy';
|
||||
/**
|
||||
* Relative path from the `__dirname` to the root where the `arduino-ide-extension` and the `electron-app` folders are.
|
||||
* This could come handy when moving the location of the `electron/packager`.
|
||||
*/
|
||||
const rootPath = join('..', '..');
|
||||
|
||||
/**
|
||||
* Relative path from the `__dirname` to the root where the `arduino-ide-extension` and the `electron-app` folders are.
|
||||
* This could come handy when moving the location of the `electron/packager`.
|
||||
*/
|
||||
const rootPath = join('..', '..');
|
||||
// This is a HACK! We rename the root `node_modules` to something else. Otherwise, due to the hoisting,
|
||||
// multiple Theia extensions will be picked up.
|
||||
if (fs.existsSync(path(rootPath, 'node_modules'))) {
|
||||
// We either do this or change the project structure.
|
||||
echo(
|
||||
"🔧 >>> [Hack] Renaming the root 'node_modules' folder to '.node_modules'..."
|
||||
);
|
||||
mv('-f', path(rootPath, 'node_modules'), path(rootPath, '.node_modules'));
|
||||
echo(
|
||||
"👌 <<< [Hack] Renamed the root 'node_modules' folder to '.node_modules'."
|
||||
);
|
||||
}
|
||||
|
||||
// This is a HACK! We rename the root `node_modules` to something else. Otherwise, due to the hoisting,
|
||||
// multiple Theia extensions will be picked up.
|
||||
if (fs.existsSync(path(rootPath, 'node_modules'))) {
|
||||
// We either do this or change the project structure.
|
||||
echo('🔧 >>> [Hack] Renaming the root \'node_modules\' folder to \'.node_modules\'...');
|
||||
mv('-f', path(rootPath, 'node_modules'), path(rootPath, '.node_modules'));
|
||||
echo('👌 <<< [Hack] Renamed the root \'node_modules\' folder to \'.node_modules\'.')
|
||||
}
|
||||
//---------------------------+
|
||||
// Clean the previous state. |
|
||||
//---------------------------+
|
||||
// rm -rf ../working-copy
|
||||
rm('-rf', path('..', workingCopy));
|
||||
// Clean up the `./electron/build` folder.
|
||||
const resourcesToKeep = [
|
||||
'patch',
|
||||
'resources',
|
||||
'scripts',
|
||||
'template-package.json',
|
||||
];
|
||||
fs.readdirSync(path('..', 'build'))
|
||||
.filter((filename) => resourcesToKeep.indexOf(filename) === -1)
|
||||
.forEach((filename) => rm('-rf', path('..', 'build', filename)));
|
||||
|
||||
//---------------------------+
|
||||
// Clean the previous state. |
|
||||
//---------------------------+
|
||||
// rm -rf ../working-copy
|
||||
rm('-rf', path('..', workingCopy));
|
||||
// Clean up the `./electron/build` folder.
|
||||
const resourcesToKeep = ['patch', 'resources', 'scripts', 'template-package.json'];
|
||||
for (const filename of fs.readdirSync(path('..', 'build')).filter(filename => resourcesToKeep.indexOf(filename) === -1)) {
|
||||
rm('-rf', path('..', 'build', filename));
|
||||
}
|
||||
const extensions = require('./extensions.json');
|
||||
echo(
|
||||
`Building the application with the following extensions:\n${extensions
|
||||
.map((ext) => ` - ${ext}`)
|
||||
.join(',\n')}`
|
||||
);
|
||||
const allDependencies = [...extensions, 'electron-app'];
|
||||
|
||||
const extensions = require('./extensions.json');
|
||||
echo(`Building the application with the following extensions:\n${extensions.map(ext => ` - ${ext}`).join(',\n')}`);
|
||||
const allDependencies = [
|
||||
...extensions,
|
||||
'electron-app'
|
||||
]
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
// Copy the following items into the `working-copy` folder. Make sure to reuse the `yarn.lock`. |
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
mkdir('-p', path('..', workingCopy));
|
||||
for (const name of [
|
||||
...allDependencies,
|
||||
'yarn.lock',
|
||||
'package.json',
|
||||
'lerna.json',
|
||||
]) {
|
||||
cp('-rf', path(rootPath, name), path('..', workingCopy));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
// Copy the following items into the `working-copy` folder. Make sure to reuse the `yarn.lock`. |
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
mkdir('-p', path('..', workingCopy));
|
||||
for (const name of [...allDependencies, 'yarn.lock', 'package.json', 'lerna.json']) {
|
||||
cp('-rf', path(rootPath, name), path('..', workingCopy));
|
||||
}
|
||||
|
||||
//----------------------------------------------+
|
||||
// Sanity check: all versions must be the same. |
|
||||
//----------------------------------------------+
|
||||
verifyVersions(allDependencies);
|
||||
//----------------------------------------------------------------------+
|
||||
// Use the nightly patch version if not a release but requires publish. |
|
||||
//----------------------------------------------------------------------+
|
||||
if (!isRelease) {
|
||||
for (const dependency of allDependencies) {
|
||||
const pkg = require(`../working-copy/${dependency}/package.json`);
|
||||
pkg.version = version;
|
||||
for (const dependency in pkg.dependencies) {
|
||||
if (allDependencies.indexOf(dependency) !== -1) {
|
||||
pkg.dependencies[dependency] = version;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(path('..', workingCopy, dependency, 'package.json'), JSON.stringify(pkg, null, 2));
|
||||
//----------------------------------------------+
|
||||
// Sanity check: all versions must be the same. |
|
||||
//----------------------------------------------+
|
||||
verifyVersions(allDependencies);
|
||||
//----------------------------------------------------------------------+
|
||||
// Use the nightly patch version if not a release but requires publish. |
|
||||
//----------------------------------------------------------------------+
|
||||
if (!isRelease) {
|
||||
for (const dependency of allDependencies) {
|
||||
const pkg = require(`../working-copy/${dependency}/package.json`);
|
||||
pkg.version = version;
|
||||
for (const dependency in pkg.dependencies) {
|
||||
if (allDependencies.indexOf(dependency) !== -1) {
|
||||
pkg.dependencies[dependency] = version;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, dependency, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
}
|
||||
verifyVersions(allDependencies);
|
||||
}
|
||||
verifyVersions(allDependencies);
|
||||
|
||||
//-------------------------------------------------------------+
|
||||
// Save some time: no need to build the `browser-app` example. |
|
||||
//-------------------------------------------------------------+
|
||||
//@ts-ignore
|
||||
let pkg = require('../working-copy/package.json');
|
||||
const workspaces = pkg.workspaces;
|
||||
// We cannot remove the `electron-app`. Otherwise, there is not way to collect the unused dependencies.
|
||||
const dependenciesToRemove = ['browser-app'];
|
||||
for (const dependencyToRemove of dependenciesToRemove) {
|
||||
const index = workspaces.indexOf(dependencyToRemove);
|
||||
if (index !== -1) {
|
||||
workspaces.splice(index, 1);
|
||||
}
|
||||
//-------------------------------------------------------------+
|
||||
// Save some time: no need to build the `browser-app` example. |
|
||||
//-------------------------------------------------------------+
|
||||
//@ts-ignore
|
||||
let pkg = require('../working-copy/package.json');
|
||||
const workspaces = pkg.workspaces;
|
||||
// We cannot remove the `electron-app`. Otherwise, there is not way to collect the unused dependencies.
|
||||
const dependenciesToRemove = ['browser-app'];
|
||||
for (const dependencyToRemove of dependenciesToRemove) {
|
||||
const index = workspaces.indexOf(dependencyToRemove);
|
||||
if (index !== -1) {
|
||||
workspaces.splice(index, 1);
|
||||
}
|
||||
pkg.workspaces = workspaces;
|
||||
fs.writeFileSync(path('..', workingCopy, 'package.json'), JSON.stringify(pkg, null, 2));
|
||||
}
|
||||
pkg.workspaces = workspaces;
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
// Rebuild the extension with the copied `yarn.lock`. It is a must to use the same Theia versions. |
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)}`, `Building the ${productName} application`);
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
// Rebuild the extension with the copied `yarn.lock`. It is a must to use the same Theia versions. |
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)}`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
// Test the application. With this approach, we cannot publish test results to GH Actions but save 6-10 minutes per builds |
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)} test`, `Testing the ${productName} application`);
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
// Test the application. With this approach, we cannot publish test results to GH Actions but save 6-10 minutes per builds |
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)} test`,
|
||||
`Testing the ${productName} application`
|
||||
);
|
||||
|
||||
// Collect all unused dependencies by the backend. We have to remove them from the electron app.
|
||||
// The `bundle.js` already contains everything we need for the frontend.
|
||||
// We have to do it before changing the dependencies to `local-path`.
|
||||
const unusedDependencies = await utils.collectUnusedDependencies('../working-copy/electron-app/');
|
||||
// Collect all unused dependencies by the backend. We have to remove them from the electron app.
|
||||
// The `bundle.js` already contains everything we need for the frontend.
|
||||
// We have to do it before changing the dependencies to `local-path`.
|
||||
const unusedDependencies = await utils.collectUnusedDependencies(
|
||||
'../working-copy/electron-app/'
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
// Change the regular NPM dependencies to `local-paths`, so that we can build them without any NPM registries. |
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
for (const extension of extensions) {
|
||||
if (extension !== 'arduino-ide-extension') { // Do not unlink self.
|
||||
// @ts-ignore
|
||||
pkg = require(`../working-copy/${extension}/package.json`);
|
||||
// @ts-ignore
|
||||
pkg.dependencies['arduino-ide-extension'] = 'file:../arduino-ide-extension';
|
||||
fs.writeFileSync(path('..', workingCopy, extension, 'package.json'), JSON.stringify(pkg, null, 2));
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
// Change the regular NPM dependencies to `local-paths`, so that we can build them without any NPM registries. |
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
for (const extension of extensions) {
|
||||
if (extension !== 'arduino-ide-extension') {
|
||||
// Do not unlink self.
|
||||
// @ts-ignore
|
||||
pkg = require(`../working-copy/${extension}/package.json`);
|
||||
// @ts-ignore
|
||||
pkg.dependencies['arduino-ide-extension'] =
|
||||
'file:../arduino-ide-extension';
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, extension, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------+
|
||||
// Merge the `working-copy/package.json` with `electron/build/template-package.json`. |
|
||||
//------------------------------------------------------------------------------------+
|
||||
//------------------------------------------------------------------------------------+
|
||||
// Merge the `working-copy/package.json` with `electron/build/template-package.json`. |
|
||||
//------------------------------------------------------------------------------------+
|
||||
// @ts-ignore
|
||||
pkg = require('../working-copy/electron-app/package.json');
|
||||
template.build.files = [
|
||||
...template.build.files,
|
||||
...unusedDependencies.map((name) => `!node_modules/${name}`),
|
||||
];
|
||||
|
||||
const dependencies = {};
|
||||
for (const extension of extensions) {
|
||||
dependencies[extension] = `file:../working-copy/${extension}`;
|
||||
}
|
||||
// @ts-ignore
|
||||
pkg.dependencies = { ...pkg.dependencies, ...dependencies };
|
||||
pkg.devDependencies = { ...pkg.devDependencies, ...template.devDependencies };
|
||||
// Deep-merging the Theia application configuration. We enable the electron window reload in dev mode but not for the final product. (arduino/arduino-pro-ide#187)
|
||||
// @ts-ignore
|
||||
const theia = merge(pkg.theia || {}, template.theia || {});
|
||||
const content = {
|
||||
...pkg,
|
||||
...template,
|
||||
theia,
|
||||
// @ts-ignore
|
||||
pkg = require('../working-copy/electron-app/package.json');
|
||||
template.build.files = [...template.build.files, ...unusedDependencies.map(name => `!node_modules/${name}`)];
|
||||
dependencies: pkg.dependencies,
|
||||
devDependencies: pkg.devDependencies,
|
||||
};
|
||||
const overwriteMerge = (destinationArray, sourceArray, options) =>
|
||||
sourceArray;
|
||||
fs.writeFileSync(
|
||||
path('..', 'build', 'package.json'),
|
||||
JSON.stringify(
|
||||
merge(content, template, { arrayMerge: overwriteMerge }),
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
|
||||
const dependencies = {};
|
||||
for (const extension of extensions) {
|
||||
dependencies[extension] = `file:../working-copy/${extension}`;
|
||||
}
|
||||
// @ts-ignore
|
||||
pkg.dependencies = { ...pkg.dependencies, ...dependencies };
|
||||
pkg.devDependencies = { ...pkg.devDependencies, ...template.devDependencies };
|
||||
// Deep-merging the Theia application configuration. We enable the electron window reload in dev mode but not for the final product. (arduino/arduino-pro-ide#187)
|
||||
// @ts-ignore
|
||||
const theia = merge((pkg.theia || {}), (template.theia || {}));
|
||||
const content = {
|
||||
...pkg,
|
||||
...template,
|
||||
theia,
|
||||
// @ts-ignore
|
||||
dependencies: pkg.dependencies,
|
||||
devDependencies: pkg.devDependencies
|
||||
};
|
||||
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray;
|
||||
fs.writeFileSync(path('..', 'build', 'package.json'), JSON.stringify(merge(content, template, { arrayMerge: overwriteMerge }), null, 2));
|
||||
|
||||
echo(`📜 Effective 'package.json' for the ${productName} application is:
|
||||
echo(`📜 Effective 'package.json' for the ${productName} application is:
|
||||
-----------------------
|
||||
${fs.readFileSync(path('..', 'build', 'package.json')).toString()}
|
||||
-----------------------
|
||||
`);
|
||||
|
||||
// Make sure the original `yarn.lock` file is used from the electron application.
|
||||
if (fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} must not exist.`);
|
||||
// Make sure the original `yarn.lock` file is used from the electron application.
|
||||
if (fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} must not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
cp('-rf', path(rootPath, 'yarn.lock'), path('..', 'build'));
|
||||
if (!fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} does not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
// Install all private and public dependencies for the electron application and build Theia. |
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')}`,
|
||||
'Installing dependencies'
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} build${isElectronPublish ? ':publish' : ''
|
||||
}`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} rebuild`,
|
||||
'Rebuild native dependencies'
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------------+
|
||||
// Create a throw away dotenv file which we use to feed the builder with input. |
|
||||
//------------------------------------------------------------------------------+
|
||||
const dotenv = 'electron-builder.env';
|
||||
if (fs.existsSync(path('..', 'build', dotenv))) {
|
||||
rm('-rf', path('..', 'build', dotenv));
|
||||
}
|
||||
// For the releases we use the desired tag as is defined by `$(Release.Tag)` from Azure.
|
||||
// For the preview builds we use the version from the `electron/build/package.json` with the short commit hash.
|
||||
fs.writeFileSync(path('..', 'build', dotenv), `ARDUINO_VERSION=${version}`);
|
||||
|
||||
//-----------------------------------+
|
||||
// Package the electron application. |
|
||||
//-----------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} package`,
|
||||
`Packaging your ${productName} application`
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
// Recalculate artifacts hash and copy to another folder (because they can change after signing them).
|
||||
// Azure does not support wildcard for `PublishBuildArtifacts@1.pathToPublish` |
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
if (isCI) {
|
||||
try {
|
||||
await recalculateArtifactsHash();
|
||||
await copyFilesToBuildArtifacts();
|
||||
} catch (e) {
|
||||
echo(JSON.stringify(e));
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
echo(`🎉 Success. Your application is at: ${path('..', 'build', 'dist')}`);
|
||||
|
||||
restore();
|
||||
|
||||
//--------+
|
||||
// Utils. |
|
||||
//--------+
|
||||
function exec(command, toEcho) {
|
||||
if (toEcho) {
|
||||
echo(`⏱️ >>> ${toEcho}...`);
|
||||
}
|
||||
const { code, stderr, stdout } = shell.exec(command);
|
||||
if (code !== 0) {
|
||||
echo(`🔥 Error when executing ${command} => ${stderr}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
if (toEcho) {
|
||||
echo(`👌 <<< ${toEcho}.`);
|
||||
}
|
||||
return stdout;
|
||||
}
|
||||
|
||||
function cp(options, source, destination) {
|
||||
shell.cp(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function rm(options, ...files) {
|
||||
shell.rm(options, files);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mv(options, source, destination) {
|
||||
shell.mv(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mkdir(options, ...dir) {
|
||||
shell.mkdir(options, dir);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function echo(command) {
|
||||
return shell.echo(command);
|
||||
}
|
||||
|
||||
function assertNoError() {
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
echo(error);
|
||||
restore();
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function restore() {
|
||||
if (fs.existsSync(path(rootPath, '.node_modules'))) {
|
||||
echo(
|
||||
"🔧 >>> [Restore] Renaming the root '.node_modules' folder to 'node_modules'..."
|
||||
);
|
||||
mv('-f', path(rootPath, '.node_modules'), path(rootPath, 'node_modules'));
|
||||
echo(
|
||||
"👌 >>> [Restore] Renamed the root '.node_modules' folder to 'node_modules'."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyFilesToBuildArtifacts() {
|
||||
echo(`🚢 Detected CI, moving build artifacts...`);
|
||||
const { platform } = process;
|
||||
const cwd = path('..', 'build', 'dist');
|
||||
const targetFolder = path('..', 'build', 'dist', 'build-artifacts');
|
||||
mkdir('-p', targetFolder);
|
||||
const filesToCopy = [];
|
||||
const channelFile = getChannelFile(platform);
|
||||
// Channel file might be an empty string if we're not building a
|
||||
// nightly or a full release. This can happen when building a package
|
||||
// locally or a tester build when creating a new PR on GH.
|
||||
if (!!channelFile && fs.existsSync(join(cwd, channelFile))) {
|
||||
const channelFilePath = join(cwd, channelFile);
|
||||
const newChannelFilePath = channelFilePath
|
||||
?.replace('latest', 'stable')
|
||||
?.replace('beta', 'nightly');
|
||||
echo(`🔨 >>> Renaming ${channelFilePath} to ${newChannelFilePath}.`);
|
||||
cp('-f', channelFilePath, newChannelFilePath);
|
||||
filesToCopy.push(newChannelFilePath);
|
||||
}
|
||||
switch (platform) {
|
||||
case 'linux': {
|
||||
filesToCopy.push(
|
||||
...glob
|
||||
.sync('**/arduino-ide*.{zip,AppImage}', { cwd })
|
||||
.map((p) => join(cwd, p))
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'win32': {
|
||||
filesToCopy.push(
|
||||
...glob
|
||||
.sync('**/arduino-ide*.{exe,msi,zip}', { cwd })
|
||||
.map((p) => join(cwd, p))
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'darwin': {
|
||||
filesToCopy.push(
|
||||
...glob
|
||||
.sync('**/arduino-ide*.{dmg,zip}', { cwd })
|
||||
.map((p) => join(cwd, p))
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
echo(`Unsupported platform: ${platform}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
cp('-rf', path(rootPath, 'yarn.lock'), path('..', 'build'));
|
||||
if (!fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} does not exist.`);
|
||||
if (!filesToCopy.length) {
|
||||
echo(`Could not collect any build artifacts from ${cwd}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
for (const fileToCopy of filesToCopy) {
|
||||
echo(`🚢 >>> Copying ${fileToCopy} to ${targetFolder}.`);
|
||||
const isZip = await utils.isZip(fileToCopy);
|
||||
if (isZip && platform === 'linux') {
|
||||
await utils.adjustArchiveStructure(fileToCopy, targetFolder);
|
||||
} else {
|
||||
cp('-rf', fileToCopy, targetFolder);
|
||||
}
|
||||
echo(`👌 >>> Copied ${fileToCopy} to ${targetFolder}.`);
|
||||
}
|
||||
}
|
||||
|
||||
async function recalculateArtifactsHash() {
|
||||
echo(`🚢 Detected CI, recalculating artifacts hash...`);
|
||||
const { platform } = process;
|
||||
const cwd = path('..', 'build', 'dist');
|
||||
const channelFilePath = join(cwd, getChannelFile(platform));
|
||||
const yaml = require('yaml');
|
||||
|
||||
try {
|
||||
let fileContents = fs.readFileSync(channelFilePath, 'utf8');
|
||||
const newChannelFile = yaml.parse(fileContents);
|
||||
const { files, path } = newChannelFile;
|
||||
const newSha512 = await hashFile(join(cwd, path));
|
||||
newChannelFile.sha512 = newSha512;
|
||||
if (!!files) {
|
||||
const newFiles = [];
|
||||
for (let file of files) {
|
||||
const { url } = file;
|
||||
const { size } = fs.statSync(join(cwd, url));
|
||||
const newSha512 = await hashFile(join(cwd, url));
|
||||
|
||||
if (!newFiles.find((f) => f.sha512 === newSha512)) {
|
||||
newFiles.push({ ...file, sha512: newSha512, size });
|
||||
}
|
||||
}
|
||||
newChannelFile.files = newFiles;
|
||||
}
|
||||
|
||||
const newChannelFileRaw = yaml.stringify(newChannelFile);
|
||||
fs.writeFileSync(channelFilePath, newChannelFileRaw);
|
||||
echo(`👌 >>> Channel file updated successfully. New channel file:`);
|
||||
echo(newChannelFileRaw);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function hashFile(
|
||||
file,
|
||||
algorithm = 'sha512',
|
||||
encoding = 'base64',
|
||||
options
|
||||
) {
|
||||
const crypto = require('crypto');
|
||||
return await new Promise((resolve, reject) => {
|
||||
const hash = crypto.createHash(algorithm);
|
||||
hash.on('error', reject).setEncoding(encoding);
|
||||
fs.createReadStream(
|
||||
file,
|
||||
Object.assign({}, options, {
|
||||
highWaterMark: 1024 * 1024,
|
||||
/* better to use more memory but hash faster */
|
||||
})
|
||||
)
|
||||
.on('error', reject)
|
||||
.on('end', () => {
|
||||
hash.end();
|
||||
resolve(hash.read());
|
||||
})
|
||||
.pipe(hash, {
|
||||
end: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins tha path from `__dirname`.
|
||||
*/
|
||||
function path(...paths) {
|
||||
return join(__dirname, ...paths);
|
||||
}
|
||||
|
||||
function verifyVersions(allDependencies, expectedVersion) {
|
||||
const versions = new Set();
|
||||
for (const dependency of allDependencies) {
|
||||
versions.add(
|
||||
require(`../working-copy/${dependency}/package.json`).version
|
||||
);
|
||||
}
|
||||
if (versions.size !== 1) {
|
||||
echo(
|
||||
`Mismatching version configuration. All dependencies must have the same version. Versions were: ${JSON.stringify(
|
||||
Array.from(versions),
|
||||
null,
|
||||
2
|
||||
)}.`
|
||||
);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
if (expectedVersion) {
|
||||
if (!versions.has(expectedVersion)) {
|
||||
echo(
|
||||
`Mismatching version configuration. Expected version was: '${expectedVersion}' actual was: '${Array.from(versions)[0]
|
||||
}'.`
|
||||
);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
// Install all private and public dependencies for the electron application and build Theia. |
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', 'build')}`, 'Installing dependencies');
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} build${isElectronPublish ? ':publish' : ''}`, `Building the ${productName} application`);
|
||||
|
||||
//------------------------------------------------------------------------------+
|
||||
// Create a throw away dotenv file which we use to feed the builder with input. |
|
||||
//------------------------------------------------------------------------------+
|
||||
const dotenv = 'electron-builder.env';
|
||||
if (fs.existsSync(path('..', 'build', dotenv))) {
|
||||
rm('-rf', path('..', 'build', dotenv));
|
||||
}
|
||||
// For the releases we use the desired tag as is defined by `$(Release.Tag)` from Azure.
|
||||
// For the preview builds we use the version from the `electron/build/package.json` with the short commit hash.
|
||||
fs.writeFileSync(path('..', 'build', dotenv), `ARDUINO_VERSION=${version}`);
|
||||
|
||||
//-----------------------------------+
|
||||
// Package the electron application. |
|
||||
//-----------------------------------+
|
||||
exec(`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} package`, `Packaging your ${productName} application`);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
// Copy to another folder. Azure does not support wildcard for `PublishBuildArtifacts@1.pathToPublish` |
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
if (isCI) {
|
||||
try {
|
||||
await copyFilesToBuildArtifacts();
|
||||
} catch (e) {
|
||||
echo(JSON.stringify(e));
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
echo(`🎉 Success. Your application is at: ${path('..', 'build', 'dist')}`);
|
||||
|
||||
restore();
|
||||
|
||||
//--------+
|
||||
// Utils. |
|
||||
//--------+
|
||||
function exec(command, toEcho) {
|
||||
if (toEcho) {
|
||||
echo(`⏱️ >>> ${toEcho}...`);
|
||||
}
|
||||
const { code, stderr, stdout } = shell.exec(command);
|
||||
if (code !== 0) {
|
||||
echo(`🔥 Error when executing ${command} => ${stderr}`);
|
||||
shell.exit(1);
|
||||
}
|
||||
if (toEcho) {
|
||||
echo(`👌 <<< ${toEcho}.`);
|
||||
}
|
||||
return stdout;
|
||||
}
|
||||
|
||||
function cp(options, source, destination) {
|
||||
shell.cp(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function rm(options, ...files) {
|
||||
shell.rm(options, files);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mv(options, source, destination) {
|
||||
shell.mv(options, source, destination);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function mkdir(options, ...dir) {
|
||||
shell.mkdir(options, dir);
|
||||
assertNoError();
|
||||
}
|
||||
|
||||
function echo(command) {
|
||||
return shell.echo(command);
|
||||
}
|
||||
|
||||
function assertNoError() {
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
echo(error);
|
||||
restore();
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function restore() {
|
||||
if (fs.existsSync(path(rootPath, '.node_modules'))) {
|
||||
echo('🔧 >>> [Restore] Renaming the root \'.node_modules\' folder to \'node_modules\'...');
|
||||
mv('-f', path(rootPath, '.node_modules'), path(rootPath, 'node_modules'));
|
||||
echo('👌 >>> [Restore] Renamed the root \'.node_modules\' folder to \'node_modules\'.');
|
||||
}
|
||||
}
|
||||
|
||||
async function copyFilesToBuildArtifacts() {
|
||||
echo(`🚢 Detected CI, moving build artifacts...`);
|
||||
const { platform } = process;
|
||||
const cwd = path('..', 'build', 'dist');
|
||||
const targetFolder = path('..', 'build', 'dist', 'build-artifacts');
|
||||
mkdir('-p', targetFolder);
|
||||
const filesToCopy = [];
|
||||
switch (platform) {
|
||||
case 'linux': {
|
||||
filesToCopy.push(...glob.sync('**/arduino-ide*.{zip,AppImage}', { cwd }).map(p => join(cwd, p)));
|
||||
break;
|
||||
}
|
||||
case 'win32': {
|
||||
filesToCopy.push(...glob.sync('**/arduino-ide*.{exe,msi,zip}', { cwd }).map(p => join(cwd, p)));
|
||||
break;
|
||||
}
|
||||
case 'darwin': {
|
||||
filesToCopy.push(...glob.sync('**/arduino-ide*.{dmg,zip}', { cwd }).map(p => join(cwd, p)));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
echo(`Unsupported platform: ${platform}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
if (!filesToCopy.length) {
|
||||
echo(`Could not collect any build artifacts from ${cwd}.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
for (const fileToCopy of filesToCopy) {
|
||||
echo(`🚢 >>> Copying ${fileToCopy} to ${targetFolder}.`);
|
||||
const isZip = await utils.isZip(fileToCopy);
|
||||
if (isZip) {
|
||||
await utils.adjustArchiveStructure(fileToCopy, targetFolder);
|
||||
} else {
|
||||
cp('-rf', fileToCopy, targetFolder);
|
||||
}
|
||||
echo(`👌 >>> Copied ${fileToCopy} to ${targetFolder}.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins tha path from `__dirname`.
|
||||
*/
|
||||
function path(...paths) {
|
||||
return join(__dirname, ...paths);
|
||||
}
|
||||
|
||||
function verifyVersions(allDependencies, expectedVersion) {
|
||||
const versions = new Set();
|
||||
for (const dependency of allDependencies) {
|
||||
versions.add(require(`../working-copy/${dependency}/package.json`).version);
|
||||
}
|
||||
if (versions.size !== 1) {
|
||||
echo(`Mismatching version configuration. All dependencies must have the same version. Versions were: ${JSON.stringify(Array.from(versions), null, 2)}.`);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
if (expectedVersion) {
|
||||
if (!versions.has(expectedVersion)) {
|
||||
echo(`Mismatching version configuration. Expected version was: '${expectedVersion}' actual was: '${Array.from(versions)[0]}'.`);
|
||||
shell.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
||||
|
@@ -13,10 +13,11 @@
|
||||
"author": "Arduino SA",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"7zip-min": "^1.1.1",
|
||||
"@types/file-type": "^10.9.1",
|
||||
"@types/temp": "^0.8.32",
|
||||
"7zip-min": "^1.1.1",
|
||||
"chai": "^4.2.0",
|
||||
"crypto": "^1.0.1",
|
||||
"dateformat": "^3.0.3",
|
||||
"deepmerge": "2.01",
|
||||
"depcheck": "^0.9.2",
|
||||
@@ -25,13 +26,14 @@
|
||||
"is-ci": "^2.0.0",
|
||||
"mocha": "^7.1.1",
|
||||
"semver": "^7.3.2",
|
||||
"sinon": "^9.0.1",
|
||||
"shelljs": "^0.8.3",
|
||||
"sinon": "^9.0.1",
|
||||
"temp": "^0.9.1",
|
||||
"yaml": "^1.10.2",
|
||||
"yargs": "^12.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.14.1 <13"
|
||||
"node": ">=14.0.0 <15"
|
||||
},
|
||||
"mocha": {
|
||||
"reporter": "spec",
|
||||
@@ -39,4 +41,4 @@
|
||||
"watch-extensions": "js",
|
||||
"timeout": 10000
|
||||
}
|
||||
}
|
||||
}
|
@@ -8,112 +8,112 @@ const sinon = require('sinon');
|
||||
|
||||
describe('utils', () => {
|
||||
|
||||
describe('adjustArchiveStructure', () => {
|
||||
describe('adjustArchiveStructure', () => {
|
||||
|
||||
let consoleStub;
|
||||
|
||||
beforeEach(() => {
|
||||
consoleStub = sinon.stub(console, 'log').value(() => { });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
consoleStub.reset();
|
||||
track.cleanupSync();
|
||||
});
|
||||
|
||||
it('should reject when not a zip file', async () => {
|
||||
try {
|
||||
const invalid = path.join(__dirname, 'resources', 'not-a-zip.dmg');
|
||||
await testMe.adjustArchiveStructure(invalid, track.mkdirSync());
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message).to.be.equal('Expected a ZIP file.');
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target directory does not exist', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__dirname, 'some', 'missing', 'path'));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('does not exist.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target is a file', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__filename));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('is not a directory.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should be a NOOP when the zip already has the desired base folder', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
const actual = await testMe.adjustArchiveStructure(zip, track.mkdirSync());
|
||||
expect(actual).to.be.equal(zip);
|
||||
});
|
||||
|
||||
it('should handle whitespace in file path gracefully', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip with whitespace.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip with whitespace.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip with whitespace');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
|
||||
it('should keep the symlinks after ZIP adjustments', async function () {
|
||||
if (process.platform === 'win32') {
|
||||
this.skip();
|
||||
}
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-with-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
expect(fs.lstatSync(path.join(verifyOut, 'zip-with-symlink', 'folder', 'symlinked-sub')).isSymbolicLink()).to.be.true;
|
||||
});
|
||||
|
||||
it('should adjust the archive structure if base folder is not present', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-without-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-without-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip-without-symlink');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
let consoleStub;
|
||||
|
||||
beforeEach(() => {
|
||||
consoleStub = sinon.stub(console, 'log').value(() => { });
|
||||
});
|
||||
|
||||
});
|
||||
afterEach(() => {
|
||||
consoleStub.reset();
|
||||
track.cleanupSync();
|
||||
});
|
||||
|
||||
it('should reject when not a zip file', async () => {
|
||||
try {
|
||||
const invalid = path.join(__dirname, 'resources', 'not-a-zip.dmg');
|
||||
await testMe.adjustArchiveStructure(invalid, track.mkdirSync());
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message).to.be.equal('Expected a ZIP file.');
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target directory does not exist', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__dirname, 'some', 'missing', 'path'));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('does not exist.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should reject when target is a file', async () => {
|
||||
try {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
await testMe.adjustArchiveStructure(zip, path.join(__filename));
|
||||
throw new Error('Expected a rejection');
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceOf(Error);
|
||||
expect(e.message.endsWith('is not a directory.')).to.be.true;
|
||||
}
|
||||
});
|
||||
|
||||
it('should be a NOOP when the zip already has the desired base folder', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-base-folder.zip');
|
||||
const actual = await testMe.adjustArchiveStructure(zip, track.mkdirSync());
|
||||
expect(actual).to.be.equal(zip);
|
||||
});
|
||||
|
||||
it('should handle whitespace in file path gracefully', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip with whitespace.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip with whitespace.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip with whitespace');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
|
||||
it('should keep the symlinks after ZIP adjustments', async function () {
|
||||
if (process.platform === 'win32') {
|
||||
this.skip();
|
||||
}
|
||||
const zip = path.join(__dirname, 'resources', 'zip-with-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-with-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
expect(fs.lstatSync(path.join(verifyOut, 'zip-with-symlink', 'folder', 'symlinked-sub')).isSymbolicLink()).to.be.true;
|
||||
});
|
||||
|
||||
it('should adjust the archive structure if base folder is not present', async () => {
|
||||
const zip = path.join(__dirname, 'resources', 'zip-without-symlink.zip');
|
||||
const out = track.mkdirSync();
|
||||
const actual = await testMe.adjustArchiveStructure(zip, out, true);
|
||||
expect(actual).to.be.equal(path.join(out, 'zip-without-symlink.zip'));
|
||||
console.log(actual);
|
||||
expect(fs.existsSync(actual)).to.be.true;
|
||||
|
||||
const verifyOut = track.mkdirSync();
|
||||
await unpack(actual, verifyOut);
|
||||
|
||||
const root = path.join(verifyOut, 'zip-without-symlink');
|
||||
expect(fs.existsSync(root)).to.be.true;
|
||||
expect(fs.lstatSync(root).isDirectory()).to.be.true;
|
||||
const subs = fs.readdirSync(root);
|
||||
expect(subs).to.have.lengthOf(3);
|
||||
expect(subs.sort()).to.be.deep.equal(['a.txt', 'b.txt', 'foo']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
@@ -12,35 +12,42 @@ const fromFile = require('file-type').fromFile;
|
||||
* Resolves to an array of `npm` package names that are declared in the `package.json` but **not** used by the project.
|
||||
*/
|
||||
function collectUnusedDependencies(pathToProject = process.cwd()) {
|
||||
const p = path.isAbsolute(pathToProject) ? pathToProject : path.resolve(process.cwd(), pathToProject);
|
||||
console.log(`⏱️ >>> Collecting unused backend dependencies for ${p}...`);
|
||||
return new Promise(resolve => {
|
||||
depcheck(p, {
|
||||
ignoreDirs: [
|
||||
'frontend'
|
||||
],
|
||||
parsers: {
|
||||
'*.js': depcheck.parser.es6,
|
||||
'*.jsx': depcheck.parser.jsx
|
||||
},
|
||||
detectors: [
|
||||
depcheck.detector.requireCallExpression,
|
||||
depcheck.detector.importDeclaration
|
||||
],
|
||||
specials: [
|
||||
depcheck.special.eslint,
|
||||
depcheck.special.webpack
|
||||
]
|
||||
}, unused => {
|
||||
const { dependencies } = unused
|
||||
if (dependencies && dependencies.length > 0) {
|
||||
console.log(`👌 <<< The following unused dependencies have been found: ${JSON.stringify(dependencies, null, 2)}`);
|
||||
} else {
|
||||
console.log('👌 <<< No unused dependencies have been found.');
|
||||
}
|
||||
resolve(dependencies);
|
||||
});
|
||||
})
|
||||
const p = path.isAbsolute(pathToProject)
|
||||
? pathToProject
|
||||
: path.resolve(process.cwd(), pathToProject);
|
||||
console.log(`⏱️ >>> Collecting unused backend dependencies for ${p}...`);
|
||||
return new Promise((resolve) => {
|
||||
depcheck(
|
||||
p,
|
||||
{
|
||||
ignoreDirs: ['frontend'],
|
||||
parsers: {
|
||||
'*.js': depcheck.parser.es6,
|
||||
'*.jsx': depcheck.parser.jsx,
|
||||
},
|
||||
detectors: [
|
||||
depcheck.detector.requireCallExpression,
|
||||
depcheck.detector.importDeclaration,
|
||||
],
|
||||
specials: [depcheck.special.eslint, depcheck.special.webpack],
|
||||
},
|
||||
(unused) => {
|
||||
const { dependencies } = unused;
|
||||
if (dependencies && dependencies.length > 0) {
|
||||
console.log(
|
||||
`👌 <<< The following unused dependencies have been found: ${JSON.stringify(
|
||||
dependencies,
|
||||
null,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
} else {
|
||||
console.log('👌 <<< No unused dependencies have been found.');
|
||||
}
|
||||
resolve(dependencies);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,101 +57,111 @@ function collectUnusedDependencies(pathToProject = process.cwd()) {
|
||||
* If `pathToZip` is not a ZIP, rejects. `targetFolderName` is the destination folder not the new archive location.
|
||||
*/
|
||||
function adjustArchiveStructure(pathToZip, targetFolderName, noCleanup) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!await isZip(pathToZip)) {
|
||||
reject(new Error(`Expected a ZIP file.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(targetFolderName)) {
|
||||
reject(new Error(`${targetFolderName} does not exist.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.lstatSync(targetFolderName).isDirectory()) {
|
||||
reject(new Error(`${targetFolderName} is not a directory.`));
|
||||
return;
|
||||
}
|
||||
console.log(`⏱️ >>> Adjusting ZIP structure ${pathToZip}...`);
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!(await isZip(pathToZip))) {
|
||||
reject(new Error(`Expected a ZIP file.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.existsSync(targetFolderName)) {
|
||||
reject(new Error(`${targetFolderName} does not exist.`));
|
||||
return;
|
||||
}
|
||||
if (!fs.lstatSync(targetFolderName).isDirectory()) {
|
||||
reject(new Error(`${targetFolderName} is not a directory.`));
|
||||
return;
|
||||
}
|
||||
console.log(`⏱️ >>> Adjusting ZIP structure ${pathToZip}...`);
|
||||
|
||||
const root = basename(pathToZip);
|
||||
const resources = await list(pathToZip);
|
||||
const hasBaseFolder = resources.find(name => name === root);
|
||||
if (hasBaseFolder) {
|
||||
if (resources.filter(name => name.indexOf(path.sep) === -1).length > 1) {
|
||||
console.warn(`${pathToZip} ZIP has the desired root folder ${root}, however the ZIP contains other entries too: ${JSON.stringify(resources)}`);
|
||||
}
|
||||
console.log(`👌 <<< The ZIP already has the desired ${root} folder.`);
|
||||
resolve(pathToZip);
|
||||
return;
|
||||
}
|
||||
const root = basename(pathToZip);
|
||||
const resources = await list(pathToZip);
|
||||
const hasBaseFolder = resources.find((name) => name === root);
|
||||
if (hasBaseFolder) {
|
||||
if (
|
||||
resources.filter((name) => name.indexOf(path.sep) === -1).length > 1
|
||||
) {
|
||||
console.warn(
|
||||
`${pathToZip} ZIP has the desired root folder ${root}, however the ZIP contains other entries too: ${JSON.stringify(
|
||||
resources
|
||||
)}`
|
||||
);
|
||||
}
|
||||
console.log(`👌 <<< The ZIP already has the desired ${root} folder.`);
|
||||
resolve(pathToZip);
|
||||
return;
|
||||
}
|
||||
|
||||
const track = temp.track();
|
||||
try {
|
||||
const unzipOut = path.join(track.mkdirSync(), root);
|
||||
fs.mkdirSync(unzipOut);
|
||||
await unpack(pathToZip, unzipOut);
|
||||
const adjustedZip = path.join(targetFolderName, path.basename(pathToZip));
|
||||
await pack(unzipOut, adjustedZip);
|
||||
console.log(`👌 <<< Adjusted the ZIP structure. Moved the modified ${basename(pathToZip)} to the ${targetFolderName} folder.`);
|
||||
resolve(adjustedZip);
|
||||
} finally {
|
||||
if (!noCleanup) {
|
||||
track.cleanupSync();
|
||||
}
|
||||
}
|
||||
});
|
||||
const track = temp.track();
|
||||
try {
|
||||
const unzipOut = path.join(track.mkdirSync(), root);
|
||||
fs.mkdirSync(unzipOut);
|
||||
await unpack(pathToZip, unzipOut);
|
||||
const adjustedZip = path.join(targetFolderName, path.basename(pathToZip));
|
||||
await pack(unzipOut, adjustedZip);
|
||||
console.log(
|
||||
`👌 <<< Adjusted the ZIP structure. Moved the modified ${basename(
|
||||
pathToZip
|
||||
)} to the ${targetFolderName} folder.`
|
||||
);
|
||||
resolve(adjustedZip);
|
||||
} finally {
|
||||
if (!noCleanup) {
|
||||
track.cleanupSync();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `basename` of `pathToFile` without the file extension.
|
||||
*/
|
||||
function basename(pathToFile) {
|
||||
const name = path.basename(pathToFile);
|
||||
const ext = path.extname(pathToFile);
|
||||
return name.substr(0, name.length - ext.length);
|
||||
const name = path.basename(pathToFile);
|
||||
const ext = path.extname(pathToFile);
|
||||
return name.substr(0, name.length - ext.length);
|
||||
}
|
||||
|
||||
function unpack(what, where) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.unpack(what, where, error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.unpack(what, where, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pack(what, where) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.pack(what, where, error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.pack(what, where, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function list(what) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.list(what, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(result.map(({ name }) => name));
|
||||
})
|
||||
return new Promise((resolve, reject) => {
|
||||
zip.list(what, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(result.map(({ name }) => name));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function isZip(pathToFile) {
|
||||
if (!fs.existsSync(pathToFile)) {
|
||||
throw new Error(`${pathToFile} does not exist`);
|
||||
}
|
||||
const type = await fromFile(pathToFile);
|
||||
return type && type.ext === 'zip';
|
||||
if (!fs.existsSync(pathToFile)) {
|
||||
throw new Error(`${pathToFile} does not exist`);
|
||||
}
|
||||
const type = await fromFile(pathToFile);
|
||||
return type && type.ext === 'zip';
|
||||
}
|
||||
|
||||
const isElectronPublish = false; // TODO: support auto-updates
|
||||
@@ -152,20 +169,56 @@ const isNightly = process.env.IS_NIGHTLY === 'true';
|
||||
const isRelease = process.env.IS_RELEASE === 'true';
|
||||
|
||||
function git(command) {
|
||||
try {
|
||||
const gitPath = shell.which('git');
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
const { stderr, stdout } = shell.exec(`"${gitPath}" ${command}`, { silent: true });
|
||||
if (stderr) {
|
||||
throw new Error(stderr.toString().trim());
|
||||
}
|
||||
return stdout.toString().trim();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
try {
|
||||
const gitPath = shell.which('git');
|
||||
const error = shell.error();
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
const { stderr, stdout } = shell.exec(`"${gitPath}" ${command}`, {
|
||||
silent: true,
|
||||
});
|
||||
if (stderr) {
|
||||
throw new Error(stderr.toString().trim());
|
||||
}
|
||||
return stdout.toString().trim();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { collectUnusedDependencies, adjustArchiveStructure, isZip, unpack, isNightly, isRelease, isElectronPublish, git };
|
||||
// getChannelFile returns the name of the channel file to be released
|
||||
// together with the IDE file.
|
||||
// The channel file depends on the platform and whether we're creating
|
||||
// a nightly build or a full release.
|
||||
// In all other cases, like when building a tester build for a PR,
|
||||
// an empty string is returned since we don't need a channel file.
|
||||
// The channel files are necessary for updates check with electron-updater
|
||||
// to work correctly.
|
||||
// For more information: https://www.electron.build/auto-update
|
||||
function getChannelFile(platform) {
|
||||
let currentChannel = 'beta';
|
||||
if (isRelease) {
|
||||
currentChannel = 'latest';
|
||||
}
|
||||
return (
|
||||
currentChannel +
|
||||
{
|
||||
linux: '-linux.yml',
|
||||
win32: '.yml',
|
||||
darwin: '-mac.yml',
|
||||
}[platform]
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
collectUnusedDependencies,
|
||||
adjustArchiveStructure,
|
||||
isZip,
|
||||
unpack,
|
||||
isNightly,
|
||||
isRelease,
|
||||
isElectronPublish,
|
||||
git,
|
||||
getChannelFile,
|
||||
};
|
||||
|
@@ -437,6 +437,11 @@ cross-spawn@^6.0.0:
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
crypto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037"
|
||||
integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==
|
||||
|
||||
dateformat@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
||||
@@ -1597,6 +1602,11 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
||||
|
||||
yaml@^1.10.2:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||
|
||||
yargs-parser@13.1.2, yargs-parser@^13.1.2:
|
||||
version "13.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
|
||||
|
334
i18n/bg.json
Normal file
334
i18n/bg.json
Normal file
@@ -0,0 +1,334 @@
|
||||
{
|
||||
"arduino": {
|
||||
"common": {
|
||||
"offlineIndicator": "Изглежда, че сте офлайн. Без интернет връзка, Arduino CLI може да не успее да изтегли необходимите ресурси и може да причини неизправност. Моля, свържете се с интернет и рестартирайте приложението.",
|
||||
"noBoardSelected": "Не е избрана платка",
|
||||
"selectedOn": "на {0}",
|
||||
"notConnected": "[няма връзка]",
|
||||
"serialMonitor": "Сериен Монитор",
|
||||
"oldFormat": "„{0}“ все още използва стария формат .pde. Искате ли да преминете към новото разширение `.ino`?",
|
||||
"later": "По-късно",
|
||||
"selectBoard": "Изберете платка",
|
||||
"unknown": "Неизвестно",
|
||||
"processing": "Обработва се",
|
||||
"saveChangesToSketch": "Искате ли да запазите промените в тази скица, преди да затворите?",
|
||||
"loseChanges": "Ако не запазите, промените ви ще бъдат загубени."
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Скица",
|
||||
"tools": "Инструменти"
|
||||
},
|
||||
"debug": {
|
||||
"optimizeForDebugging": "Оптимизиране за отстраняване на грешки",
|
||||
"debugWithMessage": "Отстраняване на грешки - {0}",
|
||||
"noPlatformInstalledFor": "Платформата не е инсталирана за „{0}“",
|
||||
"debuggingNotSupported": "Отстраняването на грешки не се поддържа от „{0}“"
|
||||
},
|
||||
"preferences": {
|
||||
"language.log": "True, ако езиковият сървър на Arduino трябва да генерира лог файлове в папката за скици. В противен случай false. По подразбиране е false.",
|
||||
"compile.verbose": "True за подробен изход за компилиране. False по подразбиране",
|
||||
"compile.warnings": "Указва на gcc кое ниво на предупреждение да използва. По подразбиране е „None“.",
|
||||
"upload.verbose": "True за подробен изход за качване. False по подразбиране.",
|
||||
"window.autoScale": "True , ако потребителският интерфейс автоматично се мащабира с размера на шрифта.",
|
||||
"window.zoomLevel": "Регулирайте нивото на увеличение на прозореца. Оригиналният размер е 0 и всяко увеличение над (напр. 1) или под (напр. -1) представлява увеличение с 20% по-голямо или по-малко. Можете също да въведете десетични знаци, за да регулирате нивото на увеличение по-финно.",
|
||||
"ide.autoUpdate": "True, за да активирате автоматичните проверки за актуализация. IDE ще проверява за актуализации автоматично и периодично.",
|
||||
"board.certificates": "Списък със сертификати, които могат да бъдат качени на платката",
|
||||
"sketchbook.showAllFiles": "True , за да се покажат всички файлове вътре в скицата. По подразбиране е false.",
|
||||
"cloud.enabled": "True , ако функциите за синхронизиране на скицата са активирани. По подразбиране е true.",
|
||||
"cloud.pull.warn": "True е, ако потребителите трябва да бъдат предупредени, преди да се изтегли скица от облака. По подразбиране е true.",
|
||||
"cloud.push.warn": "True, ако потребителите трябва да бъдат предупредени, преди да бъде пусната скица в облака. По подразбиране е true.",
|
||||
"cloud.pushpublic.warn": "True, ако потребителите трябва да бъдат предупредени, преди да бъде изпратена публична скица в облака. По подразбиране е true.",
|
||||
"cloud.sketchSyncEnpoint": "Крайната точка, използвана за изпращане и изтегляне на скици от бекенда. По подразбиране той сочи към Arduino Cloud API.",
|
||||
"auth.clientID": "OAuth2 клиентски идентификатор.",
|
||||
"auth.domain": "OAuth2 домейнът.",
|
||||
"auth.audience": "OAuth2 аудиторията.",
|
||||
"auth.registerUri": "URI, използван за регистриране на нов потребител.",
|
||||
"network": "Мрежа",
|
||||
"sketchbook.location": "Местоположение на скицника",
|
||||
"browse": "Прегледай",
|
||||
"files.inside.sketches": "Показване на файлове в Sketches",
|
||||
"editorFontSize": "Размер на шрифта на редактора",
|
||||
"interfaceScale": "Мащаб на интерфейса",
|
||||
"showVerbose": "Показване на подробен изход по време на",
|
||||
"compilerWarnings": "Компилационни предупреждения",
|
||||
"automatic": "Автоматично",
|
||||
"compile": "компилиране",
|
||||
"upload": "качване",
|
||||
"verifyAfterUpload": "Потвърдете кода след качване",
|
||||
"checkForUpdates": "Проверете за актуализации при стартиране",
|
||||
"editorQuickSuggestions": "Бързи предложения на редактора",
|
||||
"additionalManagerURLs": "Допълнителни URL адреси на мениджър на платки",
|
||||
"noProxy": "Без прокси",
|
||||
"manualProxy": "Ръчна конфигурация на прокси",
|
||||
"newSketchbookLocation": "Изберете местоположение за новата скицниката",
|
||||
"choose": "Изберете",
|
||||
"enterAdditionalURLs": "Въведете допълнителни URL адреси, по един за всеки ред",
|
||||
"unofficialBoardSupport": "Щракнете за списък с неофициално поддържаните URL адреси на платки",
|
||||
"invalid.sketchbook.location": "Невалидно местоположение на скицника: {0}",
|
||||
"invalid.editorFontSize": "Невалиден размер на шрифта на редактора. Трябва да е положително цяло число.",
|
||||
"invalid.theme": "Невалидна тема."
|
||||
},
|
||||
"cloud": {
|
||||
"signIn": "ВПИШИ СЕ",
|
||||
"signOut": "Отписване",
|
||||
"chooseSketchVisibility": "Изберете видимост на вашата скица:",
|
||||
"privateVisibility": "Частен. Само вие можете да видите скицата.",
|
||||
"publicVisibility": "Обществени. Всеки с връзката може да види скицата.",
|
||||
"link": "Връзка:",
|
||||
"embed": "Вграждане:",
|
||||
"cloudSketchbook": "Облачен скицник",
|
||||
"shareSketch": "Споделете скица",
|
||||
"showHideRemoveSketchbook": "Показване/скриване на отдалечен скицник",
|
||||
"pullSketch": "Издърпайте скица",
|
||||
"openInCloudEditor": "Отворете в Cloud Editor",
|
||||
"options": "Настроики...",
|
||||
"share": "Сподели...",
|
||||
"remote": "Отдалечен",
|
||||
"emptySketchbook": "Вашият Скицник е празен",
|
||||
"visitArduinoCloud": "Посетете Arduino Cloud, за да създадете облачни скици.",
|
||||
"signInToCloud": "Влезте в Arduino Cloud",
|
||||
"syncEditSketches": "Синхронизирайте и редактирайте на вашите Arduino облачни скици",
|
||||
"learnMore": "Научете повече",
|
||||
"continue": "Продължи",
|
||||
"pushSketch": "Изпрати скица",
|
||||
"pushSketchMsg": "Това е публична скица. Преди да я изпратите, уверете се, че всяка чувствителна информация е дефинирана във файловете arduino_secrets.h. Можете да направите скица частна от панела за споделяне.",
|
||||
"pull": "Изтегли",
|
||||
"pullSketchMsg": "Изтеглянето на тази скица от облака ще презапише нейната локална версия. Сигурен ли си, че искаш да продължиш?",
|
||||
"donePulling": "Изтеглянето на „{0}“ приключи.",
|
||||
"notYetPulled": "Не може да се изпрати към облака. Още не е изтеглен.",
|
||||
"push": "Изпрати",
|
||||
"pullFirst": "Първо трябва да дръпнете, за да можете да изпратите към облака.",
|
||||
"donePushing": "Изпращането на „{0}“ приключи.",
|
||||
"connected": "Свързано",
|
||||
"offline": "Офлайн",
|
||||
"profilePicture": "Снимка на профила"
|
||||
},
|
||||
"board": {
|
||||
"installManually": "Инсталирай ръчно",
|
||||
"installNow": "Ядрото „{0} {1}“ трябва да бъде инсталирано за текущо избраната платка „{2}“. Искате ли да го инсталирате сега?",
|
||||
"configDialogTitle": "Изберете друга платка и порт",
|
||||
"configDialog1": "Изберете както платка, така и порт, ако искате да качите скица.",
|
||||
"configDialog2": "Ако изберете само платка, ще можете само да компилирате, но не и да качвате скицата си.",
|
||||
"pleasePickBoard": "Моля, изберете платка, свързана към порта, който сте избрали.",
|
||||
"showAllAvailablePorts": "Показва всички налични портове, когато е активиран",
|
||||
"programmer": "Програматор",
|
||||
"succesfullyInstalledPlatform": "Успешно инсталирана платформа {0}:{1}",
|
||||
"succesfullyUninstalledPlatform": "Успешно деинсталирана платформа {0}:{1}",
|
||||
"couldNotFindPreviouslySelected": "Не можа да се намери по-рано избрана платка „{0}“ в инсталираната платформа „{1}“. Моля, изберете отново ръчно платката, която искате да използвате. Искате ли да я изберете отново сега?",
|
||||
"reselectLater": "Изберете отново по-късно",
|
||||
"noneSelected": "Няма избрани платка.",
|
||||
"noPortsSelected": "Няма избрани портове за платка: „{0}“.",
|
||||
"noFQBN": "FQBN не е наличен за избраната платка „{0}“. Имате ли инсталирано съответното ядро?",
|
||||
"openBoardsConfig": "Изберете друга платка и порт...",
|
||||
"boardListItem": "{0} в {1}",
|
||||
"selectBoardForInfo": "Моля, изберете платка, за да получите информация за нея.",
|
||||
"platformMissing": "Платформата за избраната платка „{0}“ не е инсталирана.",
|
||||
"selectPortForInfo": "Моля, изберете порт, за да получите информация за платката.",
|
||||
"boardInfo": "Информация за платка",
|
||||
"board": "Платка{0}",
|
||||
"port": "Порт{0}",
|
||||
"getBoardInfo": "Вземи информация за платката",
|
||||
"inSketchbook": "(в Скицника)"
|
||||
},
|
||||
"boardsManager": "Мениджър на платки",
|
||||
"about": {
|
||||
"label": "Относно {0}",
|
||||
"detail": "Версия: {0}\nДата: {1}{2}\nВерсия на CLI: {3}{4} [{5}]\n\n{6}"
|
||||
},
|
||||
"contributions": {
|
||||
"addFile": "Добави файл",
|
||||
"replaceTitle": "Замени",
|
||||
"fileAdded": "Към скицата е добавен един файл."
|
||||
},
|
||||
"replaceMsg": "Да се замени ли съществуващата версия на {0}?",
|
||||
"library": {
|
||||
"addZip": "Добавяне на .ZIP библиотека...",
|
||||
"zipLibrary": "Библиотека",
|
||||
"overwriteExistingLibrary": "Искате ли да презапишете съществуващата библиотека?",
|
||||
"successfullyInstalledZipLibrary": "Успешно инсталирана библиотека от {0} архив",
|
||||
"namedLibraryAlreadyExists": "Библиотечна папка с име {0} вече съществува. Искате ли да я презапишете?",
|
||||
"libraryAlreadyExists": "Библиотека вече съществува. Искате ли да я презапишете?",
|
||||
"include": "Включи библиотека",
|
||||
"manageLibraries": "Управление на библиотеки...",
|
||||
"arduinoLibraries": "Arduino библиотеки",
|
||||
"contributedLibraries": "Допринесени библиотеки",
|
||||
"title": "Управител на библиотеки",
|
||||
"needsOneDependency": "Библиотеката <b>{0}:{1}</b> се нуждае от друга зависимост, която в момента не е инсталирана:",
|
||||
"needsMultipleDependencies": "Библиотеката <b>{0}:{1}</b> се нуждае от някои други зависимости, които в момента не са инсталирани:",
|
||||
"installOneMissingDependency": "Искате ли да инсталирате липсващата зависимост?",
|
||||
"installMissingDependencies": "Искате ли да инсталирате всички липсващи зависимости?",
|
||||
"dependenciesForLibrary": "Зависимости за библиотека {0}:{1}",
|
||||
"installAll": "Инсталирай всички",
|
||||
"installOnly": "Инсталирайте само {0}",
|
||||
"installedSuccessfully": "Успешно инсталирана библиотека {0}:{1}",
|
||||
"uninstalledSuccessfully": "Успешно деинсталирана библиотека {0}:{1}"
|
||||
},
|
||||
"selectZip": "Изберете zip файл, съдържащ библиотеката, която искате да добавите",
|
||||
"sketch": {
|
||||
"archiveSketch": "Архивирай скица",
|
||||
"saveSketchAs": "Запазете папката със скици като...",
|
||||
"createdArchive": "Създаден е архив „{0}“.",
|
||||
"new": "Нов",
|
||||
"openRecent": "Отвори Скорошен",
|
||||
"showFolder": "Показване на папка за скици",
|
||||
"sketch": "Скица",
|
||||
"moving": "Преместване",
|
||||
"movingMsg": "Файлът „{0}“ трябва да бъде в папка на скица, наречена „{1}“.\nСъздай тази папка, премести файла и продължи?",
|
||||
"cantOpen": "Папка с име „{0}“ вече съществува. Не може да се отвори скица.",
|
||||
"saveFolderAs": "Запазете папката със скица като...",
|
||||
"sketchbook": "Скицник",
|
||||
"upload": "Качване",
|
||||
"uploadUsingProgrammer": "Качване с помощта на програмист",
|
||||
"userFieldsNotFoundError": "Не мога да намеря потребителски полета за свързаната платка",
|
||||
"doneUploading": "Качването приключи.",
|
||||
"configureAndUpload": "Конфигуриране и качване",
|
||||
"verifyOrCompile": "Проверете/компилирайте",
|
||||
"exportBinary": "Експортиране на компилиран двоичен файл",
|
||||
"verify": "Потвърдете",
|
||||
"doneCompiling": "Готово е компилирането.",
|
||||
"couldNotConnectToSerial": "Не можа да се свърже отново със серийния порт. {0}",
|
||||
"openSketchInNewWindow": "Отвори скицата в нов прозорец",
|
||||
"openFolder": "Отвори папка",
|
||||
"titleLocalSketchbook": "Локален скицник",
|
||||
"titleSketchbook": "Скицник",
|
||||
"close": "Наистина ли искате да затворите скицата?"
|
||||
},
|
||||
"bootloader": {
|
||||
"burnBootloader": "Запишете буутлоудъра",
|
||||
"doneBurningBootloader": "Записването на буутлоудъра приключи."
|
||||
},
|
||||
"editor": {
|
||||
"copyForForum": "Копиране за форум (Markdown)",
|
||||
"commentUncomment": "Коментиране/Премахване на коментар",
|
||||
"increaseIndent": "Увеличете отстъпа",
|
||||
"decreaseIndent": "Намаляване на отстъпа",
|
||||
"increaseFontSize": "Увеличете размера на шрифта",
|
||||
"decreaseFontSize": "Намаляване на размера на шрифта",
|
||||
"autoFormat": "Автоматично форматиране"
|
||||
},
|
||||
"examples": {
|
||||
"menu": "Примери",
|
||||
"couldNotInitializeExamples": "Не можа да се инициализира вградените примери.",
|
||||
"builtInExamples": "Вградени примери",
|
||||
"customLibrary": "Примери от персонализирани библиотеки",
|
||||
"for": "Примери за {0}",
|
||||
"forAny": "Примери за всяка платка"
|
||||
},
|
||||
"help": {
|
||||
"search": "Търсете в Arduino.cc",
|
||||
"keyword": "Въведете ключова дума",
|
||||
"gettingStarted": "Да започнем",
|
||||
"environment": "Околна среда",
|
||||
"troubleshooting": "Отстраняване на неизправности",
|
||||
"reference": "Референция",
|
||||
"findInReference": "Намерете в Референцията",
|
||||
"faq": "Често задавани въпроси",
|
||||
"visit": "Посетете Arduino.cc"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "Качете SSL коренни сертификати",
|
||||
"openContext": "Отворен контекст",
|
||||
"remove": "Премахване",
|
||||
"upload": "Качване",
|
||||
"addURL": "Добавете URL за извличане на SSL сертификат",
|
||||
"enterURL": "Въведете URL",
|
||||
"selectCertificateToUpload": "1. Изберете сертификат за качване",
|
||||
"addNew": "Добави нов",
|
||||
"selectDestinationBoardToUpload": "2. Изберете платка и качете сертификат",
|
||||
"uploadingCertificates": "Качване на сертификати.",
|
||||
"certificatesUploaded": "Качени сертификати.",
|
||||
"uploadFailed": "Качването не бе успешно. Моля, опитайте отново.",
|
||||
"selectBoard": "Изберете платка,,,",
|
||||
"boardAtPort": "{0} в {1}",
|
||||
"noSupportedBoardConnected": "Няма свързана поддържана платка"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Обновяване на фърмуера",
|
||||
"selectBoard": "Изберете платка",
|
||||
"checkUpdates": "Проверете актуализации",
|
||||
"selectVersion": "Изберете версия на фърмуера",
|
||||
"install": "Инсталирай",
|
||||
"overwriteSketch": "Инсталацията ще презапише скицата на платката.",
|
||||
"installingFirmware": "Инсталиране на фърмуер.",
|
||||
"successfullyInstalled": "Фърмуерът е инсталиран успешно.",
|
||||
"failedInstall": "Неуспешно инсталиране. Моля, опитайте отново."
|
||||
},
|
||||
"dialog": {
|
||||
"dontAskAgain": "Не питай отново"
|
||||
},
|
||||
"userFields": {
|
||||
"cancel": "Отмяна",
|
||||
"upload": "Качване"
|
||||
},
|
||||
"serial": {
|
||||
"toggleTimestamp": "Превключване на клеймото за време",
|
||||
"autoscroll": "Автоматично превъртане",
|
||||
"timestamp": "Печат за време",
|
||||
"noLineEndings": "Без край на реда",
|
||||
"newLine": "Нов ред",
|
||||
"carriageReturn": "Carriage Return",
|
||||
"newLineCarriageReturn": "Както NL, така и CR",
|
||||
"notConnected": "Няма връзка. Изберете платка и порт за автоматично свързване.",
|
||||
"message": "Съобщение ({0} + Enter, за да изпратите съобщение до „{1}“ на „{2}“",
|
||||
"connectionBusy": "Свързването е неуспешно. Серийният порт е зает: {0}",
|
||||
"disconnected": "Прекъснато е връзката на {0} с {1}.",
|
||||
"unexpectedError": "Неочаквана грешка. Повторно свързване на {0} на порт {1}.",
|
||||
"failedReconnect": "Неуспешно свързване на {0} към серийния порт след 10 последователни опита. Серийният порт {1} е зает.",
|
||||
"reconnect": "Повторно свързване на {0} към {1} след {2} секунди..."
|
||||
},
|
||||
"component": {
|
||||
"uninstall": "Деинсталиране",
|
||||
"uninstallMsg": "Искате ли да деинсталирате {0}?",
|
||||
"by": "от",
|
||||
"version": "Версия {0}",
|
||||
"moreInfo": "Повече информация",
|
||||
"install": "ИНСТАЛИРАЙ",
|
||||
"filterSearch": "Филтрирайте търсенето си..."
|
||||
},
|
||||
"electron": {
|
||||
"couldNotSave": "Скицата не можа да бъде запазена. Моля, копирайте незапазената си работа в любимия си текстов редактор и рестартирайте IDE-то.",
|
||||
"unsavedChanges": "Всички незапазени промени няма да бъдат запазени."
|
||||
},
|
||||
"compile": {
|
||||
"error": "Грешка при компилация: {0}"
|
||||
},
|
||||
"upload": {
|
||||
"error": "{0} грешка: {1}"
|
||||
},
|
||||
"burnBootloader": {
|
||||
"error": "Грешка при записване на зареждащия инструмент: {0}"
|
||||
}
|
||||
},
|
||||
"theia": {
|
||||
"core": {
|
||||
"couldNotSave": "Скицата не можа да бъде запазена. Моля, копирайте незапазената си работа в любимия си текстов редактор и рестартирайте IDE-то.",
|
||||
"offline": "Офлайн",
|
||||
"daemonOffline": "CLI Daemon офлайн",
|
||||
"cannotConnectBackend": "Не може да се свърже с бекенда.",
|
||||
"cannotConnectDaemon": "Не може да се свърже с демона на CLI."
|
||||
},
|
||||
"debug": {
|
||||
"start": "Започнете...",
|
||||
"typeNotSupported": "Типът на сесията за отстраняване на грешки „{0}“ не се поддържа.",
|
||||
"startError": "Възникна грешка при стартиране на сесията за отстраняване на грешки, проверете регистрационните файлове за повече подробности."
|
||||
},
|
||||
"editor": {
|
||||
"unsavedTitle": "Незапазено – {0}"
|
||||
},
|
||||
"messages": {
|
||||
"expand": "Разгънете",
|
||||
"collapse": "Свиване"
|
||||
},
|
||||
"workspace": {
|
||||
"fileNewName": "Име за нов файл",
|
||||
"invalidFilename": "Невалидно име на файла.",
|
||||
"invalidExtension": ".{0} не е валидно разширение",
|
||||
"newFileName": "Ново име на файла",
|
||||
"deleteCurrentSketch": "Искате ли да изтриете текущата скица?",
|
||||
"sketchDirectoryError": "При създаването на директорията на скицата възникна грешка. Вижте дневника за повече подробности. Приложението вероятно няма да работи според очакванията."
|
||||
}
|
||||
},
|
||||
"cloud": {
|
||||
"GoToCloud": "КЪМ ОБЛАКА"
|
||||
}
|
||||
}
|
448
i18n/de.json
448
i18n/de.json
@@ -1,334 +1,334 @@
|
||||
{
|
||||
"arduino": {
|
||||
"common": {
|
||||
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.",
|
||||
"noBoardSelected": "No board selected",
|
||||
"selectedOn": "on {0}",
|
||||
"notConnected": "[not connected]",
|
||||
"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}",
|
||||
"notConnected": "[keine Verbindung]",
|
||||
"serialMonitor": "Serieller Monitor",
|
||||
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
|
||||
"later": "Later",
|
||||
"selectBoard": "Select Board",
|
||||
"unknown": "Unknown",
|
||||
"processing": "Processing",
|
||||
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
|
||||
"loseChanges": "If you don't save, your changes will be lost."
|
||||
"oldFormat": "Der Sketch '{0}' verwendet noch das alte '.pde' Format. Möchtest du auf die neuere '.ino' Endung wechseln?",
|
||||
"later": "später",
|
||||
"selectBoard": "Board wählen",
|
||||
"unknown": "unbekannt",
|
||||
"processing": "Verarbeiten",
|
||||
"saveChangesToSketch": "Änderungen zu diesem Sketch vor dem Schließen sichern?",
|
||||
"loseChanges": "Wenn du nicht sicherst, werden deine Änderungen gelöscht."
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Sketch",
|
||||
"tools": "Werkzeuge"
|
||||
},
|
||||
"debug": {
|
||||
"optimizeForDebugging": "Optimize for Debugging",
|
||||
"optimizeForDebugging": "Für Debugging optimieren",
|
||||
"debugWithMessage": "Debug - {0}",
|
||||
"noPlatformInstalledFor": "Platform is not installed for '{0}'",
|
||||
"debuggingNotSupported": "Debugging is not supported by '{0}'"
|
||||
"noPlatformInstalledFor": "Die Platform für '{0}' ist nicht instaliert.",
|
||||
"debuggingNotSupported": "'{0}' unterstützt kein Debuggen"
|
||||
},
|
||||
"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.autoUpdate": "True to enable automatic update checks. The IDE will check for updates automatically and periodically.",
|
||||
"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": "The OAuth2 domain.",
|
||||
"auth.audience": "The OAuth2 audience.",
|
||||
"auth.registerUri": "The URI used to register a new user.",
|
||||
"language.log": "Wahr, wenn der Arduino Language Server Logfiles in den Sketch-Ordner schreiben soll. Sonst falsch. Standardeinstellung ist falsch.\n ",
|
||||
"compile.verbose": "Wahr für ausführliche Compilerausgaben. Standardmäßig Falsch",
|
||||
"compile.warnings": "Einstellung des Warnlevels für den GCC. Standardeinstellung ist 'None'.",
|
||||
"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.",
|
||||
"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.",
|
||||
"cloud.pull.warn": "Wahr, wenn Benutzer vor dem Herunterladen eines Sketches aus der Cloud gewarnt werden sollen. Standardmäßig Wahr.",
|
||||
"cloud.push.warn": "Wahr, wenn Benutzer vor dem Hochladen eines Cloud-Sketches gewarnt werden sollen. Standardmäßig Wahr.",
|
||||
"cloud.pushpublic.warn": "Wahr, wenn Benutzer vor dem Hochladen eines öffentlichen Sketches in die Cloud gewarnt werden sollen. Standardmäßig Wahr.",
|
||||
"cloud.sketchSyncEnpoint": "Der Endpunkt, um Sketches zu/von einem Backend zu laden. Standardeinstellung ist die Arduino Cloud API.",
|
||||
"auth.clientID": "Die OAuth2 client ID.",
|
||||
"auth.domain": "Die OAuth2 Domain.",
|
||||
"auth.audience": "Das The OAuth2 Audience.",
|
||||
"auth.registerUri": "Das URI hat einen neuen Benutzer registriert.",
|
||||
"network": "Netzwerk",
|
||||
"sketchbook.location": "Sketchbook location",
|
||||
"sketchbook.location": "Dateipfad des Sketchbooks",
|
||||
"browse": "Durchsuchen",
|
||||
"files.inside.sketches": "Show files inside Sketches",
|
||||
"editorFontSize": "Editor font size",
|
||||
"interfaceScale": "Interface scale",
|
||||
"showVerbose": "Show verbose output during",
|
||||
"compilerWarnings": "Compiler warnings",
|
||||
"files.inside.sketches": "Dateien im Sketch zeigen",
|
||||
"editorFontSize": "Editor Schriftgröße",
|
||||
"interfaceScale": "Fenster Skalierung",
|
||||
"showVerbose": "Debug Informationen während",
|
||||
"compilerWarnings": "Warnungen des Übersetzers",
|
||||
"automatic": "Automatisch",
|
||||
"compile": "compile",
|
||||
"upload": "upload",
|
||||
"verifyAfterUpload": "Verify code after upload",
|
||||
"compile": "Kompilieren",
|
||||
"upload": "Hochladen",
|
||||
"verifyAfterUpload": "Code nach Hochladen überprüfen ",
|
||||
"checkForUpdates": "Beim Start nach Updates suchen",
|
||||
"editorQuickSuggestions": "Editor Quick Suggestions",
|
||||
"editorQuickSuggestions": "Schnelle Editor Vorschläge",
|
||||
"additionalManagerURLs": "Zusätzliche Boardverwalter-URLs",
|
||||
"noProxy": "No proxy",
|
||||
"manualProxy": "Manual proxy configuration",
|
||||
"newSketchbookLocation": "Select new sketchbook location",
|
||||
"choose": "Choose",
|
||||
"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."
|
||||
"noProxy": "Kein Proxy",
|
||||
"manualProxy": "Manuelle Proxy Einstellung",
|
||||
"newSketchbookLocation": "Wähle einen neuen Ort für das Sketchbook ",
|
||||
"choose": "Wähle",
|
||||
"enterAdditionalURLs": "Füge zusätzliche URLs hinzu, jede Reihe einzeln",
|
||||
"unofficialBoardSupport": "Klicke hier für eine Liste von inoffiziell unterstützten Boards",
|
||||
"invalid.sketchbook.location": "Ungültiger Sketchbook Speicherort: {0}",
|
||||
"invalid.editorFontSize": "Ungültige Editor Schriftgröße. Sie muss eine positive, ganze Zahl sein.",
|
||||
"invalid.theme": "Ungültiges Erscheinungsbild"
|
||||
},
|
||||
"cloud": {
|
||||
"signIn": "SIGN IN",
|
||||
"signOut": "Sign Out",
|
||||
"chooseSketchVisibility": "Choose visibility of your Sketch:",
|
||||
"privateVisibility": "Private. Only you can view the Sketch.",
|
||||
"publicVisibility": "Public. Anyone with the link can view the Sketch.",
|
||||
"signIn": "Anmelden",
|
||||
"signOut": "Abmelden",
|
||||
"chooseSketchVisibility": "Wähle die Sichtbarkeit deines Sketches:",
|
||||
"privateVisibility": "Private. Nur du siehst diesen Sketch.",
|
||||
"publicVisibility": "Public. Jeder kann mit diesen Link den Sketch sehen.",
|
||||
"link": "Link:",
|
||||
"embed": "Embed:",
|
||||
"embed": "Einbetten:",
|
||||
"cloudSketchbook": "Cloud Sketchbook",
|
||||
"shareSketch": "Share Sketch",
|
||||
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook",
|
||||
"shareSketch": "Sketch teilen",
|
||||
"showHideRemoveSketchbook": "Zeige/Verstecke Remote Sketchbook",
|
||||
"pullSketch": "Pull Sketch",
|
||||
"openInCloudEditor": "Open in Cloud Editor",
|
||||
"options": "Options...",
|
||||
"share": "Share...",
|
||||
"openInCloudEditor": "Im Cloud Editor öffnen",
|
||||
"options": "Optionen....",
|
||||
"share": "Teilen....",
|
||||
"remote": "Remote",
|
||||
"emptySketchbook": "Your Sketchbook is empty",
|
||||
"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",
|
||||
"emptySketchbook": "Dein Sketchbook ist leer",
|
||||
"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",
|
||||
"continue": "Fortfahren",
|
||||
"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.",
|
||||
"pushSketchMsg": "Das ist ein öffentliches Sketch. Vor dem Pushen solltest du überprüfen, ob alle sensiblen Informationen in arduino_secrets.h definiert sind. Du kannst einen Sketch mit dem Teilen-Feld privat machen.",
|
||||
"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.",
|
||||
"pullSketchMsg": "Wenn du diesen Sketch aus der Cloud lädst, wird die lokale Version überschrieben. Möchtest du fortfahren?",
|
||||
"donePulling": "Herunterladen von '{0}' erfolgreich.",
|
||||
"notYetPulled": "Kann nicht in die Cloud geschoben werden. Es ist noch nicht heruntergeladen.",
|
||||
"push": "Push",
|
||||
"pullFirst": "You have to pull first to be able to push to the Cloud.",
|
||||
"donePushing": "Done pushing ‘{0}’.",
|
||||
"connected": "Connected",
|
||||
"pullFirst": "Du musst zuerst herunterladen, damit du in die Cloud schieben kannst.",
|
||||
"donePushing": "Hochladen von '{0}' erfolgreich.",
|
||||
"connected": "Verbunden",
|
||||
"offline": "Offline",
|
||||
"profilePicture": "Profile picture"
|
||||
"profilePicture": "Profilbild"
|
||||
},
|
||||
"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 just 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",
|
||||
"installManually": "Manuell installieren",
|
||||
"installNow": "Der \"{0} {1}\" Core muss für das ausgewählte \"{2}\" Board installiert werden. Jetzt installieren?",
|
||||
"configDialogTitle": "Andere Bords und Ports wählen",
|
||||
"configDialog1": "Wählen Sie ein Board und einen Port, wenn Sie den Sketch hochladen möchten.",
|
||||
"configDialog2": "Wenn Sie nur ein Board auswählen, werden Sie den Sketch nur kompilieren können, jedoch nicht hochladen.",
|
||||
"pleasePickBoard": "Bitte wählen Sie das Board, welches am ausgewählten Port angeschlossen ist.",
|
||||
"showAllAvailablePorts": "Zeige alle verfügbaren Ports, wenn aktiviert.",
|
||||
"programmer": "Programmer",
|
||||
"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": "Reselect 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": "Select other board and port…",
|
||||
"boardListItem": "{0} at {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": "Boardinformationen",
|
||||
"succesfullyInstalledPlatform": "Plattform erfolgreich installiert {0}:{1}",
|
||||
"succesfullyUninstalledPlatform": "Plattform erfolgreich deinstalliert {0}:{1}",
|
||||
"couldNotFindPreviouslySelected": "Zuvor gewähltes Board '{0}' wurde nicht in der installierten Plaftform '{1}' gefunden. Bitte Board erneut auswählen. Jetzt auswählen?",
|
||||
"reselectLater": "Später auswählen",
|
||||
"noneSelected": "Kein Board ausgewählt.",
|
||||
"noPortsSelected": "Kein Port für das Board : '{0}' ausgewählt.",
|
||||
"noFQBN": "Der FQBN ist für das gewählte Board \"{0}\" nicht verfügbar. Wurde der zugehörige Core installiert?",
|
||||
"openBoardsConfig": "Wähle einen anderes Board und einen anderen Port...",
|
||||
"boardListItem": "{0} bei {1}",
|
||||
"selectBoardForInfo": "Wähle ein Board für die Board-Informationen.",
|
||||
"platformMissing": "Die Plattform für das gewählte '{0}' Board ist nicht installiert.",
|
||||
"selectPortForInfo": "Wähle ein Port, um Informationen über das Board zu erhalten.",
|
||||
"boardInfo": "Board-Informationen",
|
||||
"board": "Board{0}",
|
||||
"port": "Port{0}",
|
||||
"getBoardInfo": "Get Board Info",
|
||||
"inSketchbook": " (in Sketchbook)"
|
||||
"getBoardInfo": "Board-Informationen abrufen",
|
||||
"inSketchbook": "(im Sketchbook)"
|
||||
},
|
||||
"boardsManager": "Boardverwalter",
|
||||
"boardsManager": "Board-Verwaltung",
|
||||
"about": {
|
||||
"label": "About {0}",
|
||||
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
|
||||
"label": "Über {0}",
|
||||
"detail": "Version: {0}\nDatum: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
|
||||
},
|
||||
"contributions": {
|
||||
"addFile": "Datei hinzufügen...",
|
||||
"replaceTitle": "Replace",
|
||||
"fileAdded": "One file added to the sketch."
|
||||
"replaceTitle": "Ersetzen",
|
||||
"fileAdded": "Eine Datei wurde zum Sketch hinzugefügt."
|
||||
},
|
||||
"replaceMsg": "Replace the existing version of {0}?",
|
||||
"replaceMsg": "Existierende Version von {0} ersetzen?",
|
||||
"library": {
|
||||
"addZip": ".ZIP-Bibliothek hinzufügen...",
|
||||
"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}"
|
||||
"zipLibrary": "Bibliothek",
|
||||
"overwriteExistingLibrary": "Möchtest du die existierende Bibliothek überschreiben?",
|
||||
"successfullyInstalledZipLibrary": "Bibliothek erfolgreich vom {0} Archiv installiert",
|
||||
"namedLibraryAlreadyExists": "Der Bibliothek-Ordner '{0}' existiert bereits. Überschreiben?",
|
||||
"libraryAlreadyExists": "Eine Bibliothek existiert bereits. Möchten sie diese überschreiben?",
|
||||
"include": "Bibliothek einbinden",
|
||||
"manageLibraries": "Bibliotheken verwalten...",
|
||||
"arduinoLibraries": "Arduino Bibliotheken",
|
||||
"contributedLibraries": "Bibliotheken, zu denen beigetragen wurde",
|
||||
"title": "Bibliotheksverwalter",
|
||||
"needsOneDependency": "Die Bibliothek <b>{0}:{1}</b> benötigt eine andere Abhängigkeit, welche derzeit nicht installiert ist:",
|
||||
"needsMultipleDependencies": "Die Bibliothek <b>{0}:{1}</b> benötigt ein paar andere Abhängigkeiten, die derzeit nicht installiert sind:",
|
||||
"installOneMissingDependency": "Möchten Sie die fehlende Ressource installieren?",
|
||||
"installMissingDependencies": "Möchten Sie alle fehlenden Ressourcen installieren?",
|
||||
"dependenciesForLibrary": "Abhängigkeiten für die Bibliothek {0}:{1}",
|
||||
"installAll": "Alle installieren",
|
||||
"installOnly": "Nur {0} installieren",
|
||||
"installedSuccessfully": "Bibliothek {0}:{1} erfolgreich installiert",
|
||||
"uninstalledSuccessfully": "Bibliothek {0}:{1} erfolgreich deinstalliert"
|
||||
},
|
||||
"selectZip": "Select a zip file containing the library you'd like to add",
|
||||
"selectZip": "Wähle die ZIP-Datei, welche die hinzuzufügende Bibliothek enthält",
|
||||
"sketch": {
|
||||
"archiveSketch": "Sketch archivieren",
|
||||
"saveSketchAs": "Save sketch folder as...",
|
||||
"createdArchive": "Created archive '{0}'.",
|
||||
"new": "New",
|
||||
"openRecent": "Open Recent",
|
||||
"showFolder": "Show Sketch Folder",
|
||||
"saveSketchAs": "Sketch Ordner speichern als...",
|
||||
"createdArchive": "Archiv '{0}' erstellt.",
|
||||
"new": "Neu",
|
||||
"openRecent": "Zuletzt geöffnet",
|
||||
"showFolder": "Zeige Sketch Ordner",
|
||||
"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?",
|
||||
"moving": "Übertragen...",
|
||||
"movingMsg": "Die Datei \"{0}\" muss sich in einem Sketch Ordner \"{1}\" befinden.\nDiesen Ordner erstellen, Datei verschieben und fortfahren?",
|
||||
"cantOpen": "Ein Ordner mit dem Namen \"{0}\" ist bereits vorhanden. Der Sketch kann nicht geöffnet werden.",
|
||||
"saveFolderAs": "Save sketch folder as...",
|
||||
"saveFolderAs": "Sketch Ordner speichern als...",
|
||||
"sketchbook": "Sketchbook",
|
||||
"upload": "Hochladen",
|
||||
"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",
|
||||
"uploadUsingProgrammer": "Mit Programmer hochladen",
|
||||
"userFieldsNotFoundError": "User Fields für das angeschlossene Board nicht gefunden",
|
||||
"doneUploading": "Hochladen erfolgreich! ",
|
||||
"configureAndUpload": "Konfigurieren und hochladen",
|
||||
"verifyOrCompile": "Überprüfen/Kompilieren",
|
||||
"exportBinary": "Kompilierte Binärdatei exportieren",
|
||||
"verify": "Überprüfen",
|
||||
"doneCompiling": "Kompilieren erfolgreich!",
|
||||
"couldNotConnectToSerial": "Verbindung zum seriellen Port fehlgeschlagen. {0}",
|
||||
"openSketchInNewWindow": "Sketch in neuen Fenster öffnen",
|
||||
"openFolder": "Ordner öffnen",
|
||||
"titleLocalSketchbook": "Lokales Sketchbook",
|
||||
"titleSketchbook": "Sketchbook",
|
||||
"close": "Are you sure you want to close the sketch?"
|
||||
"close": "Sind Sie sicher, dass Sie diesen Sketch schließen möchten?"
|
||||
},
|
||||
"bootloader": {
|
||||
"burnBootloader": "Bootloader brennen",
|
||||
"doneBurningBootloader": "Done burning bootloader."
|
||||
"doneBurningBootloader": "Bootloader erfolgreich gebrannt."
|
||||
},
|
||||
"editor": {
|
||||
"copyForForum": "Für Forum kopieren (Markdown)",
|
||||
"commentUncomment": "Kommentieren/Kommentar aufheben",
|
||||
"increaseIndent": "Increase Indent",
|
||||
"decreaseIndent": "Decrease Indent",
|
||||
"increaseFontSize": "Increase Font Size",
|
||||
"decreaseFontSize": "Schriftgröße verringern",
|
||||
"autoFormat": "Automatische Formatierung"
|
||||
"increaseIndent": "Einrückung erweitern",
|
||||
"decreaseIndent": "Einrückung verringern ",
|
||||
"increaseFontSize": "Schriftgröße vergrößern ",
|
||||
"decreaseFontSize": "Schrift verkleinern",
|
||||
"autoFormat": "automatisch Formatieren"
|
||||
},
|
||||
"examples": {
|
||||
"menu": "Examples",
|
||||
"couldNotInitializeExamples": "Could not initialize built-in examples.",
|
||||
"menu": "Beispiele",
|
||||
"couldNotInitializeExamples": "Mitgelieferte Beispiele konnten nicht initialisiert werden",
|
||||
"builtInExamples": "Mitgelieferte Beispiele",
|
||||
"customLibrary": "Examples from Custom Libraries",
|
||||
"for": "Examples for {0}",
|
||||
"forAny": "Examples for any board"
|
||||
"customLibrary": "Beispiele aus eigenen Bibliotheken",
|
||||
"for": "Beispiele für {0}",
|
||||
"forAny": "Beispiele für jedes 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"
|
||||
"search": "Suche auf Arduino.cc",
|
||||
"keyword": "Schlagwort eingeben",
|
||||
"gettingStarted": "Loslegen...",
|
||||
"environment": "Umgebung",
|
||||
"troubleshooting": "Fehlersuche",
|
||||
"reference": "Referenz",
|
||||
"findInReference": "Referenzsuche",
|
||||
"faq": "Häufig gestellte Fragen",
|
||||
"visit": "Besuche Arduino.cc"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "Upload SSL Root Certificates",
|
||||
"openContext": "Open context",
|
||||
"remove": "Remove",
|
||||
"uploadRootCertificates": "SSL Root Zertifikat hochladen",
|
||||
"openContext": "Kontext öffnen",
|
||||
"remove": "entfernen",
|
||||
"upload": "Hochladen",
|
||||
"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} at {1}",
|
||||
"noSupportedBoardConnected": "No supported board connected"
|
||||
"addURL": "URL hinzufügen, um das SSL-Zertifikat abzurufen",
|
||||
"enterURL": "URL eingeben",
|
||||
"selectCertificateToUpload": "1. Zertifikat zum hochladen auswählen",
|
||||
"addNew": "Neu hinzufügen",
|
||||
"selectDestinationBoardToUpload": "2. Zielboard wählen und Zertifikat hochladen",
|
||||
"uploadingCertificates": "Zertifikate hochladen...",
|
||||
"certificatesUploaded": "Die Zertifikate wurden erfolgreich hochgeladen.",
|
||||
"uploadFailed": "Hochladen fehlgeschlagen. Bitte versuchen Sie es erneut.",
|
||||
"selectBoard": "Wähle ein Board...",
|
||||
"boardAtPort": "{0} bei {1}",
|
||||
"noSupportedBoardConnected": "Kein unterstütztes Board angeschlossen"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Updater",
|
||||
"selectBoard": "Select Board",
|
||||
"checkUpdates": "Check Updates",
|
||||
"selectVersion": "Select firmware version",
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Aktualisierer",
|
||||
"selectBoard": "Board auswählen",
|
||||
"checkUpdates": "Nach Updates Suchen",
|
||||
"selectVersion": "Firmware Version wählen",
|
||||
"install": "Installieren",
|
||||
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
|
||||
"installingFirmware": "Installing firmware.",
|
||||
"successfullyInstalled": "Firmware succesfully installed.",
|
||||
"failedInstall": "Installation failed. Please try again."
|
||||
"overwriteSketch": "Die Installation wird den Sketch auf dem Board überschreiben.",
|
||||
"installingFirmware": "Firmware wird installiert.",
|
||||
"successfullyInstalled": "Firmware wurde erfolgreich installiert.",
|
||||
"failedInstall": "Installation fehlgeschlagen. Bitte versuche es erneut "
|
||||
},
|
||||
"dialog": {
|
||||
"dontAskAgain": "Don't ask again"
|
||||
"dontAskAgain": "Nicht noch einmal fragen"
|
||||
},
|
||||
"userFields": {
|
||||
"cancel": "Cancel",
|
||||
"cancel": "abbrechen",
|
||||
"upload": "Hochladen"
|
||||
},
|
||||
"serial": {
|
||||
"toggleTimestamp": "Toggle Timestamp",
|
||||
"autoscroll": "Autoscroll",
|
||||
"timestamp": "Timestamp",
|
||||
"toggleTimestamp": "Zeitstempel an/aus",
|
||||
"autoscroll": "Automatisch scrollen",
|
||||
"timestamp": "Zeitstempel",
|
||||
"noLineEndings": "Kein Zeilenende",
|
||||
"newLine": "Neue Zeile",
|
||||
"carriageReturn": "Zeilenumbruch (CR)",
|
||||
"carriageReturn": "Zeilenumbruch",
|
||||
"newLineCarriageReturn": "Sowohl NL als auch 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": "Connection failed. Serial port is busy: {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..."
|
||||
"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",
|
||||
"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.",
|
||||
"failedReconnect": "Verbindung von {0} zum seriellen Port nach 10 Versuchen abgebrochen. Der {1} serielle Port ist belegt..",
|
||||
"reconnect": "Verbinde {0} erneut zu {1} in {2} Sekunden..."
|
||||
},
|
||||
"component": {
|
||||
"uninstall": "Uninstall",
|
||||
"uninstallMsg": "Do you want to uninstall {0}?",
|
||||
"by": "by",
|
||||
"uninstall": "deinstalieren",
|
||||
"uninstallMsg": "Möchten Sie {0} deinstallieren?",
|
||||
"by": "von",
|
||||
"version": "Version {0}",
|
||||
"moreInfo": "More info",
|
||||
"moreInfo": "Mehr Information",
|
||||
"install": "Installieren",
|
||||
"filterSearch": "Grenzen Sie Ihre Suche ein..."
|
||||
"filterSearch": "Filtern Sie Ihre Suche..."
|
||||
},
|
||||
"electron": {
|
||||
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
|
||||
"unsavedChanges": "Any unsaved changes will not be saved."
|
||||
"couldNotSave": "Der Sketch konnte nicht gesichert werden. Bitte kopiere deine ungesicherte Arbeit in deinen bevorzugten Texteditor und starte die IDE neu.",
|
||||
"unsavedChanges": "Alle ungesicherten Änderung werden nicht gespeichert."
|
||||
},
|
||||
"compile": {
|
||||
"error": "Compilation error: {0}"
|
||||
"error": "Fehler beim kompilieren: {0}"
|
||||
},
|
||||
"upload": {
|
||||
"error": "{0} error: {1}"
|
||||
"error": "{0} Fehler: {1}"
|
||||
},
|
||||
"burnBootloader": {
|
||||
"error": "Error while burning the bootloader: {0}"
|
||||
"error": "Fehler beim Brennen des Bootloaders: {0}"
|
||||
}
|
||||
},
|
||||
"theia": {
|
||||
"core": {
|
||||
"couldNotSave": "Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.",
|
||||
"couldNotSave": "Der Sketch konnte nicht gesichert werden. Bitte kopiere deine ungesicherte Arbeit in deinen bevorzugten Texteditor und starte die IDE neu.",
|
||||
"offline": "Offline",
|
||||
"daemonOffline": "CLI Daemon Offline",
|
||||
"cannotConnectBackend": "Cannot connect to the backend.",
|
||||
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
|
||||
"cannotConnectBackend": "Keine Verbindung zum Backend.",
|
||||
"cannotConnectDaemon": "Keine Verbindung zum CLI Daemon."
|
||||
},
|
||||
"debug": {
|
||||
"start": "Start...",
|
||||
"typeNotSupported": "The debug session type \"{0}\" is not supported.",
|
||||
"startError": "There was an error starting the debug session, check the logs for more details."
|
||||
"typeNotSupported": "Die Debug Session vom Typ \"{0}\" wird nicht unterstützt.",
|
||||
"startError": "Es gab einen Fehler beim Start der Debug-Session. Überprüfe die Logs für mehr Informationen."
|
||||
},
|
||||
"editor": {
|
||||
"unsavedTitle": "Unsaved – {0}"
|
||||
"unsavedTitle": "Nicht gespeichert – {0}"
|
||||
},
|
||||
"messages": {
|
||||
"expand": "Expand",
|
||||
"collapse": "Collapse"
|
||||
"expand": "Ausklappen",
|
||||
"collapse": "Einklappen"
|
||||
},
|
||||
"workspace": {
|
||||
"fileNewName": "Name for new file",
|
||||
"invalidFilename": "Invalid filename.",
|
||||
"fileNewName": "Name für die neue Datei",
|
||||
"invalidFilename": "Ungültiger Dateiname. ",
|
||||
"invalidExtension": "\".{0}\" ist keine gültige Dateierweiterung.",
|
||||
"newFileName": "New name for file",
|
||||
"deleteCurrentSketch": "Do you want to delete the current sketch?",
|
||||
"sketchDirectoryError": "There was an error creating the sketch directory. See the log for more details. The application will probably not work as expected."
|
||||
"newFileName": "Neuer Name für die Datei",
|
||||
"deleteCurrentSketch": "Möchtest du den aktuellen Sketch löschen?",
|
||||
"sketchDirectoryError": "Fehler beim Erstellen des Sketch-Ordners. Mehr Informationen siehe Log. Die Anwendung wird wahrscheinlich nicht wie erwartet funktionieren."
|
||||
}
|
||||
},
|
||||
"cloud": {
|
||||
"GoToCloud": "GO TO CLOUD"
|
||||
"GoToCloud": "Zur Cloud gehen"
|
||||
}
|
||||
}
|
||||
|
334
i18n/el.json
Normal file
334
i18n/el.json
Normal file
@@ -0,0 +1,334 @@
|
||||
{
|
||||
"arduino": {
|
||||
"common": {
|
||||
"offlineIndicator": "Φαίνεται πως είστε εκτός σύνδεσης. Χωρίς σύνδεση στο Internet, το Arduino CLI ίσως να μη μπορεί να κάνει λήψη των απαιτούμενων πόρων και να υπάρξει δυσλειτουργία. Παρακαλώ συνδεθείτε στο Internet και επανεκκινήστε την εφαρμογή.",
|
||||
"noBoardSelected": "Δεν έχει επιλεχθεί πλακέτα",
|
||||
"selectedOn": "στο {0}",
|
||||
"notConnected": "[μη συνδεμένο]",
|
||||
"serialMonitor": "Παρακολούθηση Σειριακής",
|
||||
"oldFormat": "Το '{0}' χρησιμοποιεί ακόμα το παλιό '.pde' στυλ. Θέλετε να αλλάξετε στην νέα κατάληξη '.ino';",
|
||||
"later": "Αργότερα",
|
||||
"selectBoard": "Επιλογή Πλακέτας",
|
||||
"unknown": "Άγνωστο",
|
||||
"processing": "Επεξεργασία",
|
||||
"saveChangesToSketch": "Θέτε να αποθηκεύσετε τις αλλαγές σε αυτο το σχέδιο πριν κλείσετε; ",
|
||||
"loseChanges": "Αν δεν αποθηκεύσετε, οι αλλαγές σας θα χαθούν."
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Σχέδιο",
|
||||
"tools": "Εργαλεία"
|
||||
},
|
||||
"debug": {
|
||||
"optimizeForDebugging": "Βελτιστοποίηση για Αποσφαλμάτωση",
|
||||
"debugWithMessage": "Αποσφαλμάτωση - {0}",
|
||||
"noPlatformInstalledFor": "Δεν έχει εγκατασταθεί πλατφόρμα για '{0}'",
|
||||
"debuggingNotSupported": "Δεν υποστιρίζεται αποσφαλμάτωση από '{0}'"
|
||||
},
|
||||
"preferences": {
|
||||
"language.log": "Αληθές αν ο Arduino Language Server πρέπει να παράξει αρχεία κατάστασης στον φάκελο σχεδίου. Διαφορετικά, ψευδές. Είναι ψευδές απο προεπιλογή.",
|
||||
"compile.verbose": "Αληθές για λεπτομερή έξοδο μεταγλώττισης. Ψευδές απο προεπιλογή.",
|
||||
"compile.warnings": "Λέει στο gcc ποιο επίπεδο προειδοποίησης να χρησιμοποιήσει. Είναι 'None' απο προεπιλογή",
|
||||
"upload.verbose": "Αληθές για λεπτομερή έξοδο ανεβάσματος. Ψευδές απο προεπιλογή.",
|
||||
"window.autoScale": "Αληθές αν η διεπαφή χρήστη κλιμακλωνεται αυτόματα μαζί με το μέγεθος γραμματοσειράς.",
|
||||
"window.zoomLevel": "Ρύθμιση του επιπέδου μεγέθυνσης του παραθύρου. Το αρχικό μέγεθος ειναι 0 και κάθε αύξηση (π.χ. 1) ή μείωση (π.χ. -1) αναπαριστά μεγέθυνση 20% μεγαλύτερη ή μικρότερη. Μπορούν να εισαχθούν και δεκαδικά για προσαρμογή της μεγέθυνσης με μεγαλύτερη λεπτομέρεια.",
|
||||
"ide.autoUpdate": "Αληθές για ενεργοποίηση αυτομάτων ελέγχων ενημερώσεων. Το IDE θα ελέγχει για ενημερώσεις αυτόματα και τακτικά.",
|
||||
"board.certificates": "Λίστα πιστοποιητικών που μπορούν να ανέβουν σε πλακέτες",
|
||||
"sketchbook.showAllFiles": "Αληθές για εμφάνιση όλων των αρχείων σχεδίου μεσα στο σχέδιο. Είναι ψευδές απο προεπιλογή.",
|
||||
"cloud.enabled": "Αληθές αν οι λειτουγίες συγχονισμού σχεδίου είναι ενεργοποιημένες. Προεπιλογή ως αληθές.",
|
||||
"cloud.pull.warn": "Αληθές αν οι χρήστες πρέπει προειδοποιηθούν πριν τραβηχτεί ενα σχέδιο σύννεφου. Προεπιλογή ως αληθές.",
|
||||
"cloud.push.warn": "Αληθές αν οι χρήστες πρέπει προειδοποιηθούν πριν σπρωχθεί ενα σχέδιο σύννεφου. Προεπιλογή ως αληθές. ",
|
||||
"cloud.pushpublic.warn": "Αληθές αν οι χρήστες πρέπει προειδοποιηθούν πριν σπρωχθεί ενα δημόσιο σχέδιο σύννεφου. Προεπιλογή ως αληθές. ",
|
||||
"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": "The OAuth2 domain.",
|
||||
"auth.audience": "The OAuth2 audience.",
|
||||
"auth.registerUri": "The URI used to register a new user.",
|
||||
"network": "Δίκτυο",
|
||||
"sketchbook.location": "Τοποθεσία σχεδίων",
|
||||
"browse": "Περιήγηση",
|
||||
"files.inside.sketches": "Εμφάνιση αρχείων μέσα σε Σχέδια",
|
||||
"editorFontSize": "Μέγεθος γραμματοσειράς Συντάκτη",
|
||||
"interfaceScale": "Κλίμακα διεπαφής",
|
||||
"showVerbose": "Εμφάνιση λεπτομερούς εξόδου κατά τη διάρκεια",
|
||||
"compilerWarnings": "Προειδοποιήσεις μεταγγλωτιστή",
|
||||
"automatic": "Αυτόματο",
|
||||
"compile": "μεταγλώττιση",
|
||||
"upload": "ανέβασμα",
|
||||
"verifyAfterUpload": "Επιβεβαίωση κώδικα μετά το ανέβασμα",
|
||||
"checkForUpdates": "Έλεγχος ενημερώσεων κατά την εκκίνηση",
|
||||
"editorQuickSuggestions": "Editor Quick Suggestions",
|
||||
"additionalManagerURLs": "Πρόσθετοι Σύνδεσμοι Διαχειριστή Πλακετών",
|
||||
"noProxy": "No proxy",
|
||||
"manualProxy": "Manual proxy configuration",
|
||||
"newSketchbookLocation": "Επιλογή νέας τοποθεσίας σχεδίων",
|
||||
"choose": "Επιλογή",
|
||||
"enterAdditionalURLs": "Τοποθετήστε πρόσθετους Συνδέσμους, ένα σε κάθε σειρά",
|
||||
"unofficialBoardSupport": "Κλικ για λίστα Συνδέσμων ανεπίσημης υποστήριξης πλακετών",
|
||||
"invalid.sketchbook.location": "Μη-έγκυρη τοποθεσία σχεδίων: {0}",
|
||||
"invalid.editorFontSize": "Μη-έγκυρο μέγεθος γραμματοσειράς συντάκτη. Πρέπει να είναι θετικός ακέραιος.",
|
||||
"invalid.theme": "Μη-έγκυρο θέμα."
|
||||
},
|
||||
"cloud": {
|
||||
"signIn": "ΣΥΥΝΔΕΣΗ",
|
||||
"signOut": "Αποσύνδεση",
|
||||
"chooseSketchVisibility": "Επίλεξε την ορατότητα του Σχεδίου σου:",
|
||||
"privateVisibility": "Ιδιωτικό. Μόνο εσύ μπορείς να δεις το Σχέδιο.",
|
||||
"publicVisibility": "Δημόσιο. Οποιόσδηποτε με το σύνδεσμο μπορεί να δει το Σχέδιο.",
|
||||
"link": "Σύνδεσμος:",
|
||||
"embed": "Ενσωμάτωση:",
|
||||
"cloudSketchbook": "Σχέδια Cloud",
|
||||
"shareSketch": "Κοινοποίηση Σχεδίου",
|
||||
"showHideRemoveSketchbook": "Εμφάνιση/Απόκρυψη Απομακρυνσμένων Σχεδίων",
|
||||
"pullSketch": "Pull Sketch",
|
||||
"openInCloudEditor": "Άνοιγμα σε Συντάκτη Cloud",
|
||||
"options": "Επιλογές...",
|
||||
"share": "Κοινοποίηση...",
|
||||
"remote": "Απομακρυνσμένο",
|
||||
"emptySketchbook": "Τα Σχέδια σου είναι άδεια.",
|
||||
"visitArduinoCloud": "Επισκέψου το Arduino Cloud για δημιουργία Σχεδίων Cloud.",
|
||||
"signInToCloud": "Σύνδεση στο Arduino Cloud",
|
||||
"syncEditSketches": "Συγχρονισμός και τροποποίηση των Arduino Cloud Σχεδίων σου.",
|
||||
"learnMore": "Μάθε περισσότερα",
|
||||
"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": "Συνδέθηκε",
|
||||
"offline": "Εκτός Σύνδεσης",
|
||||
"profilePicture": "Εικόνα προφίλ"
|
||||
},
|
||||
"board": {
|
||||
"installManually": "Χειροκίνητη Εγκατάσταση",
|
||||
"installNow": "Ο πυρήνας \"{0} {1}\" πρέπει να εγκατασταθεί για την επιλεγμένη πλακέτα {2}. Θέλεις να την εγκαταστήσεις τώρα;",
|
||||
"configDialogTitle": "Επιλέξτε Άλλη Πλακέτα & Θύρα",
|
||||
"configDialog1": "Επίλεξε και Πλακέτα και Θύρα αν θέλεις να ανεβάσεις ένα σχέδιο.",
|
||||
"configDialog2": "Αν επιλέξεις μονο Πλακέτα θα μπορείς να κάνεις μόνο μεταγγλώτιση, αλλά οχι να ανεβάσεις το σχέδιο.",
|
||||
"pleasePickBoard": "Πσρακαλώ επίλεξε μια πλακέτα που συνδέθηκε στην θύρα που έχεις επιλέξει.",
|
||||
"showAllAvailablePorts": "Εμφανίζει όλες τις διαθέσιμες θύρες όταν είναι ενεργοποιημένο.",
|
||||
"programmer": "Προγραμματιστής",
|
||||
"succesfullyInstalledPlatform": "Επιτυχής εγκατάσταση πλατφόρμας {0}:{1}",
|
||||
"succesfullyUninstalledPlatform": "Επιτυχής απεγκατάσταση πλατφόρμας {0}:{1}",
|
||||
"couldNotFindPreviouslySelected": "Δεν έγινε εντοπισμός της προηγουμένως επιλεγμένης πλακέτας '{0}' στην εγκατεστημένη πλατφόρμα '{1}'. Παρακαλώ επίλεξε πάλι χειροκίνητα την πλακέτα που θέλεις να χρησιμοποιήσεις. Θέλεις να την επιλέξεις τώρα;",
|
||||
"reselectLater": "Επιλογή αργότερα",
|
||||
"noneSelected": "Δεν επιλέχθηκε πλακέτα",
|
||||
"noPortsSelected": "Δεν επιλέχθηκε θύρα για την πλακέτα: '{0}'.",
|
||||
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
|
||||
"openBoardsConfig": "Επιλογή διαφορετικής πλακέτας και θύρας...",
|
||||
"boardListItem": "{0} στο {1}",
|
||||
"selectBoardForInfo": "Παρακαλώ επίλεξε μια πλακέτα για εμφάνιση πληροφοριών πλακέτας.",
|
||||
"platformMissing": "Η πλατφόρμα για την επιλεγμένη πλακέτα '{0}' δεν έχει εγκατασταθεί.",
|
||||
"selectPortForInfo": "Παρακαλώ επίλεξε μια θύρα για εμφάνιση πληροφοριών πλακέτας.",
|
||||
"boardInfo": "Πληροφορίες Πλακέτας",
|
||||
"board": "Πλακέτα{0}",
|
||||
"port": "Θύρα{0}",
|
||||
"getBoardInfo": "Εμφάνιση Πληροφοριών Πλακέτας",
|
||||
"inSketchbook": "(στα Σχέδια)"
|
||||
},
|
||||
"boardsManager": "Διαχειριστής Πλακετών",
|
||||
"about": {
|
||||
"label": "Σχετικά με {0}",
|
||||
"detail": "Version: {0}\nDate: {1}{2}\nCLI Version: {3}{4} [{5}]\n\n{6}"
|
||||
},
|
||||
"contributions": {
|
||||
"addFile": "Add File",
|
||||
"replaceTitle": "Replace",
|
||||
"fileAdded": "One file added to the sketch."
|
||||
},
|
||||
"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": "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?",
|
||||
"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"
|
||||
},
|
||||
"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} at {1}",
|
||||
"noSupportedBoardConnected": "No supported board connected"
|
||||
},
|
||||
"firmware": {
|
||||
"updater": "WiFi101 / WiFiNINA Firmware Updater",
|
||||
"selectBoard": "Select Board",
|
||||
"checkUpdates": "Check Updates",
|
||||
"selectVersion": "Select firmware version",
|
||||
"install": "Install",
|
||||
"overwriteSketch": "Installation will overwrite the Sketch on the board.",
|
||||
"installingFirmware": "Installing firmware.",
|
||||
"successfullyInstalled": "Firmware succesfully 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": "Timestamp",
|
||||
"noLineEndings": "No Line Ending",
|
||||
"newLine": "New Line",
|
||||
"carriageReturn": "Carriage Return",
|
||||
"newLineCarriageReturn": "Both 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": "Connection failed. Serial port is busy: {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": "Version {0}",
|
||||
"moreInfo": "More info",
|
||||
"install": "INSTALL",
|
||||
"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": "Οι μη αποθηκευμένες αλλαγές θα χαθούν."
|
||||
},
|
||||
"compile": {
|
||||
"error": "Compilation error: {0}"
|
||||
},
|
||||
"upload": {
|
||||
"error": "{0} error: {1}"
|
||||
},
|
||||
"burnBootloader": {
|
||||
"error": "Error while burning the bootloader: {0}"
|
||||
}
|
||||
},
|
||||
"theia": {
|
||||
"core": {
|
||||
"couldNotSave": "Δεν έγινε αποθήκευση του προγράμματος. Παρακαλώ αντιγράψτε ό,τι δεν έχει αποθηκευθεί στον αγαπημένο σας επεξεργαστή κειμένου, και επανεκινήστε το Ολοκληρωμένο Περιβάλλον Ανάπτυξης IDE.",
|
||||
"offline": "Εκτός Σύνδεσης",
|
||||
"daemonOffline": "CLI Daemon Offline",
|
||||
"cannotConnectBackend": "Cannot connect to the backend.",
|
||||
"cannotConnectDaemon": "Cannot connect to the CLI daemon."
|
||||
},
|
||||
"debug": {
|
||||
"start": "Έναρξη...",
|
||||
"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": "Επαναφορά",
|
||||
"collapse": "Ελαχιστοποίηση"
|
||||
},
|
||||
"workspace": {
|
||||
"fileNewName": "Name for new file",
|
||||
"invalidFilename": "Invalid filename.",
|
||||
"invalidExtension": ".{0} is not a valid extension",
|
||||
"newFileName": "Νέο όνομα για το αρχείο",
|
||||
"deleteCurrentSketch": "Do you want to delete the current sketch?",
|
||||
"sketchDirectoryError": "Υπήρξε ένα λάθος κατά τη δημιουργία του φακέλου. Για περισσότερες λεπτομέρειες δείτε το αρχείο καταγραφής. Η εφαρμογή πιθανόν δε θα δουλέψει όπως αναμένεται."
|
||||
}
|
||||
},
|
||||
"cloud": {
|
||||
"GoToCloud": "GO TO CLOUD"
|
||||
}
|
||||
}
|
29
i18n/en.json
29
i18n/en.json
@@ -14,6 +14,22 @@
|
||||
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
|
||||
"loseChanges": "If you don't save, your changes will be lost."
|
||||
},
|
||||
"ide-updater": {
|
||||
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
|
||||
"notNowButton": "Not now",
|
||||
"versionDownloaded": "Arduino IDE {0} has been downloaded.",
|
||||
"closeToInstallNotice": "Close the software and install the update on your machine.",
|
||||
"closeAndInstallButton": "Close and Install",
|
||||
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
|
||||
"updateAvailable": "Update Available",
|
||||
"newVersionAvailable": "A new version of Arduino IDE ({0}) is available for download.",
|
||||
"skipVersionButton": "Skip Version",
|
||||
"downloadButton": "Download",
|
||||
"goToDownloadPage": "An update for the Arduino IDE is available, but we're not able to download and install it automatically. Please go to the download page and download the latest version from there.",
|
||||
"goToDownloadButton": "Go To Download",
|
||||
"ideUpdaterDialog": "Software Update",
|
||||
"noUpdatesAvailable": "There are no recent updates available for the Arduino IDE"
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Sketch",
|
||||
"tools": "Tools"
|
||||
@@ -31,7 +47,7 @@
|
||||
"upload.verbose": "True for verbose upload output. False by default.",
|
||||
"window.autoScale": "True if the user interface automatically scales with the font size.",
|
||||
"window.zoomLevel": "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.",
|
||||
"ide.autoUpdate": "True to enable automatic update checks. The IDE will check for updates automatically and periodically.",
|
||||
"ide.updateChannel": "Release channel to get updated from. 'stable' is the stable release, 'nightly' is the latest development build.",
|
||||
"board.certificates": "List of certificates that can be uploaded to boards",
|
||||
"sketchbook.showAllFiles": "True to show all sketch files inside the sketch. It is false by default.",
|
||||
"cloud.enabled": "True if the sketch sync functions are enabled. Defaults to true.",
|
||||
@@ -55,7 +71,6 @@
|
||||
"compile": "compile",
|
||||
"upload": "upload",
|
||||
"verifyAfterUpload": "Verify code after upload",
|
||||
"checkForUpdates": "Check for updates on startup",
|
||||
"editorQuickSuggestions": "Editor Quick Suggestions",
|
||||
"additionalManagerURLs": "Additional Boards Manager URLs",
|
||||
"noProxy": "No proxy",
|
||||
@@ -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": "A folder named \"{0}\" already exists. Can't open sketch.",
|
||||
"saveFolderAs": "Save sketch folder as...",
|
||||
"sketchbook": "Sketchbook",
|
||||
@@ -243,14 +258,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": "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 +284,7 @@
|
||||
"carriageReturn": "Carriage Return",
|
||||
"newLineCarriageReturn": "Both 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}.",
|
||||
|
56
i18n/es.json
56
i18n/es.json
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"arduino": {
|
||||
"common": {
|
||||
"offlineIndicator": "You appear to be offline. Without an Internet connection, the Arduino CLI might not be able to download the required resources and could cause malfunction. Please connect to the Internet and restart the application.",
|
||||
"noBoardSelected": "No board selected",
|
||||
"offlineIndicator": "Al parecer no estás en línea. Sin una conexión a internet, el CLI de Arduino no podrá descargar los recursos necesarios, lo cual puede ocasionar fallos. Por favor, conecte a internet y reinicie la aplicación.",
|
||||
"noBoardSelected": "Ninguna placa seleccionada.",
|
||||
"selectedOn": "on {0}",
|
||||
"notConnected": "[not connected]",
|
||||
"serialMonitor": "Monitor Serie",
|
||||
"oldFormat": "The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
|
||||
"oldFormat": "El '{0}' aún usa el antiguo formato `.pde` . ¿Deseas cambiar a la nueva extensión `.ino`?.",
|
||||
"later": "Later",
|
||||
"selectBoard": "Select Board",
|
||||
"selectBoard": "Seleccionar Placa",
|
||||
"unknown": "Unknown",
|
||||
"processing": "Processing",
|
||||
"saveChangesToSketch": "Do you want to save changes to this sketch before closing?",
|
||||
"loseChanges": "If you don't save, your changes will be lost."
|
||||
"processing": "Procesando",
|
||||
"saveChangesToSketch": "¿Deseas guardar los cambios en este código antes de cerrar?",
|
||||
"loseChanges": "Si no guardas, perderás los cambios."
|
||||
},
|
||||
"menu": {
|
||||
"sketch": "Programa",
|
||||
@@ -21,8 +21,8 @@
|
||||
"debug": {
|
||||
"optimizeForDebugging": "Optimize for Debugging",
|
||||
"debugWithMessage": "Debug - {0}",
|
||||
"noPlatformInstalledFor": "Platform is not installed for '{0}'",
|
||||
"debuggingNotSupported": "Debugging is not supported by '{0}'"
|
||||
"noPlatformInstalledFor": "La plataforma no está instalada para '{0}'",
|
||||
"debuggingNotSupported": "La depuracion no esta soportada por '{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.",
|
||||
@@ -34,7 +34,7 @@
|
||||
"ide.autoUpdate": "True to enable automatic update checks. The IDE will check for updates automatically and periodically.",
|
||||
"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.enabled": "Verdadero si la sincronización de código está activada. Valor verdadero por defecto.",
|
||||
"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.",
|
||||
@@ -52,11 +52,11 @@
|
||||
"showVerbose": "Show verbose output during",
|
||||
"compilerWarnings": "Compiler warnings",
|
||||
"automatic": "Automático",
|
||||
"compile": "compile",
|
||||
"upload": "upload",
|
||||
"verifyAfterUpload": "Verify code after upload",
|
||||
"compile": "Compliar",
|
||||
"upload": "Subir",
|
||||
"verifyAfterUpload": "Verificar código después de subir",
|
||||
"checkForUpdates": "Comprobar actualizaciones al iniciar",
|
||||
"editorQuickSuggestions": "Editor Quick Suggestions",
|
||||
"editorQuickSuggestions": "Sugerencias rápidas del editor",
|
||||
"additionalManagerURLs": "Gestor de URLs Adicionales de Tarjetas",
|
||||
"noProxy": "No proxy",
|
||||
"manualProxy": "Manual proxy configuration",
|
||||
@@ -65,24 +65,24 @@
|
||||
"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."
|
||||
"invalid.editorFontSize": "Tamaño de fuente invalido. Debe ser un entero positivo.",
|
||||
"invalid.theme": "Tema no valido."
|
||||
},
|
||||
"cloud": {
|
||||
"signIn": "SIGN IN",
|
||||
"signOut": "Sign Out",
|
||||
"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": "Link:",
|
||||
"privateVisibility": "Privado: Solo tú puedes ver el código.",
|
||||
"publicVisibility": "Público: Cualquiera con el enlace puede ver el código.",
|
||||
"link": "Enlace:",
|
||||
"embed": "Embed:",
|
||||
"cloudSketchbook": "Cloud Sketchbook",
|
||||
"shareSketch": "Share Sketch",
|
||||
"shareSketch": "Compartir código",
|
||||
"showHideRemoveSketchbook": "Show/Hide Remote Sketchbook",
|
||||
"pullSketch": "Pull Sketch",
|
||||
"openInCloudEditor": "Open in Cloud Editor",
|
||||
"options": "Options...",
|
||||
"share": "Share...",
|
||||
"openInCloudEditor": "Abrir en editor web",
|
||||
"options": "Opciones...",
|
||||
"share": "Compartir...",
|
||||
"remote": "Remote",
|
||||
"emptySketchbook": "Your Sketchbook is empty",
|
||||
"visitArduinoCloud": "Visit Arduino Cloud to create Cloud Sketches.",
|
||||
@@ -99,19 +99,19 @@
|
||||
"push": "Push",
|
||||
"pullFirst": "You have to pull first to be able to push to the Cloud.",
|
||||
"donePushing": "Done pushing ‘{0}’.",
|
||||
"connected": "Connected",
|
||||
"connected": "Conectado",
|
||||
"offline": "Offline",
|
||||
"profilePicture": "Profile picture"
|
||||
"profilePicture": "Foto de perfil"
|
||||
},
|
||||
"board": {
|
||||
"installManually": "Install Manually",
|
||||
"installManually": "Instalar manualmente",
|
||||
"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.",
|
||||
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
|
||||
"showAllAvailablePorts": "Shows all available ports when enabled",
|
||||
"programmer": "Programmer",
|
||||
"programmer": "Programador",
|
||||
"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?",
|
||||
@@ -223,7 +223,7 @@
|
||||
"reference": "Reference",
|
||||
"findInReference": "Find in Reference",
|
||||
"faq": "Frequently Asked Questions",
|
||||
"visit": "Visit Arduino.cc"
|
||||
"visit": "Visitar Arduino.cc"
|
||||
},
|
||||
"certificate": {
|
||||
"uploadRootCertificates": "Upload SSL Root Certificates",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user