8000 Merge branch 'main' into linux_arm64_download_ls · arduino/arduino-ide@8f31d7c · GitHub
[go: up one dir, main page]

Skip to content
Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8f31d7c

Browse files
committed
Merge branch 'main' into linux_arm64_download_ls
2 parents ca8723c + 8f8b46f commit 8f31d7c

29 files changed

+776
-261
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ jobs:
236236
echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
237237
238238
- name: Publish Release [GitHub]
239-
uses: svenstaro/upload-release-action@2.5.0
239+
uses: svenstaro/upload-release-action@2.6.1
240240
with:
241241
repo_token: ${{ secrets.GITHUB_TOKEN }}
242242
release_name: ${{ steps.tag_name.outputs.TAG_NAME }}

arduino-ide-extension/package.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,14 @@
104104
"temp": "^0.9.1",
105105
"temp-dir": "^2.0.0",
106106
"tree-kill": "^1.2.1",
107-
"util": "^0.12.5",
108-
"which": "^1.3.1"
107+
"util": "^0.12.5"
109108
},
110109
"devDependencies": {
111110
"@octokit/rest": "^18.12.0",
112111
"@types/chai": "^4.2.7",
113-
"@types/chai-string": "^1.4.2",
114112
"@types/mocha": "^5.2.7",
115113
"@types/react-window": "^1.8.5",
116114
"chai": "^4.2.0",
117-
"chai-string": "^1.5.0",
118115
"decompress": "^4.2.0",
119116
"decompress-tarbz2": "^4.1.1",
120117
"decompress-targz": "^4.1.1",
@@ -173,7 +170,7 @@
173170
],
174171
"arduino": {
175172
"cli": {
176-
"version": "0.32.2"
173+
"version": "0.33.0"
177174
},
178175
"fwuploader": {
179176
"version": "2.2.2"

arduino-ide-extension/src/browser/contributions/contribution.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import { MainMenuManager } from '../../common/main-menu-manager';
6868
import { ConfigServiceClient } from '../config/config-service-client';
6969
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
7070
import { DialogService } from '../dialog-service';
71+
import { ApplicationConnectionStatusContribution } from '../theia/core/connection-status-service';
7172

7273
export {
7374
Command,
@@ -172,6 +173,9 @@ export abstract class SketchContribution extends Contribution {
172173
@inject(EnvVariablesServer)
173174
protected readonly envVariableServer: EnvVariablesServer;
174175

176+
@inject(ApplicationConnectionStatusContribution)
177+
protected readonly connectionStatusService: ApplicationConnectionStatusContribution;
178+
175179
protected async sourceOverride(): Promise<Record<string, string>> {
176180
const override: Record<string, string> = {};
177181
const sketch = await this.sketchServiceClient.currentSketch();

arduino-ide-extension/src/browser/contributions/save-as-sketch.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
RenameCloudSketch,
2525
RenameCloudSketchParams,
2626
} from './rename-cloud-sketch';
27+
import { assertConnectedToBackend } from './save-sketch';
2728

2829
@injectable()
2930
export class SaveAsSketch extends CloudSketchContribution {
@@ -64,6 +65,10 @@ export class SaveAsSketch extends CloudSketchContribution {
6465
markAsRecentlyOpened,
6566
}: SaveAsSketch.Options = SaveAsSketch.Options.DEFAULT
6667
): Promise<boolean> {
68+
assertConnectedToBackend({
69+
connectionStatusService: this.connectionStatusService,
70+
messageService: this.messageService,
71+
});
6772
const sketch = await this.sketchServiceClient.currentSketch();
6873
if (!CurrentSketch.isValid(sketch)) {
6974
return false;

arduino-ide-extension/src/browser/contributions/save-sketch.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import { injectable } from '@theia/core/shared/inversify';
21
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
2+
import { MessageService } from '@theia/core/lib/common/message-service';
3+
import { nls } from '@theia/core/lib/common/nls';
4+
import { injectable } from '@theia/core/shared/inversify';
35
import { ArduinoMenus } from '../menu/arduino-menus';
4-
import { SaveAsSketch } from './save-as-sketch';
6+
import { CurrentSketch } from '../sketches-service-client-impl';
7+
import { ApplicationConnectionStatusContribution } from '../theia/core/connection-status-service';
58
import {
6-
SketchContribution,
79
Command,
810
CommandRegistry,
9-
MenuModelRegistry,
1011
KeybindingRegistry,
12+
MenuModelRegistry,
13+
SketchContribution,
1114
} from './contribution';
12-
import { nls } from '@theia/core/lib/common';
13-
import { CurrentSketch } from '../sketches-service-client-impl';
15+
import { SaveAsSketch } from './save-as-sketch';
1416

1517
@injectable()
1618
export class SaveSketch extends SketchContribution {
@@ -36,6 +38,10 @@ export class SaveSketch extends SketchContribution {
3638
}
3739

3840
async saveSketch(): Promise<void> {
41+
assertConnectedToBackend({
42+
connectionStatusService: this.connectionStatusService,
43+
messageService: this.messageService,
44+
});
3945
const sketch = await this.sketchServiceClient.currentSketch();
4046
if (!CurrentSketch.isValid(sketch)) {
4147
return;
@@ -63,3 +69,18 @@ export namespace SaveSketch {
6369
};
< 179B code>6470
}
6571
}
72+
73+
// https://github.com/arduino/arduino-ide/issues/2081
74+
export function assertConnectedToBackend(param: {
75+
connectionStatusService: ApplicationConnectionStatusContribution;
76+
messageService: MessageService;
77+
}): void {
78+
if (param.connectionStatusService.offlineStatus === 'backend') {
79+
const message = nls.localize(
80+
'theia/core/couldNotSave',
81+
'Could not save the sketch. Please copy your unsaved work into your favorite text editor, and restart the IDE.'
82+
);
83+
param.messageService.error(message);
84+
throw new Error(message);
85+
}
86+
}

arduino-ide-extension/src/browser/theia/core/application-shell.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,19 @@ import {
88
TabBar,
99
Widget,
1010
} from '@theia/core/lib/browser';
11-
import {
12-
ConnectionStatus,
13-
ConnectionStatusService,
14-
} from '@theia/core/lib/browser/connection-status-service';
1511
import { nls } from '@theia/core/lib/common/nls';
1612
import { MessageService } from '@theia/core/lib/common/message-service';
1713
import { inject, injectable } from '@theia/core/shared/inversify';
14+
import { ApplicationConnectionStatusContribution } from './connection-status-service';
1815
import { ToolbarAwareTabBar } from './tab-bars';
1916

2017
@injectable()
2118
export class ApplicationShell extends TheiaApplicationShell {
2219
@inject(MessageService)
2320
private readonly messageService: MessageService;
2421

25-
@inject(ConnectionStatusService)
26-
private readonly connectionStatusService: ConnectionStatusService;
22+
@inject(ApplicationConnectionStatusContribution)
23+
private readonly connectionStatusService: ApplicationConnectionStatusContribution;
2724

2825
override async addWidget(
2926
widget: Widget,
@@ -64,9 +61,8 @@ export class ApplicationShell extends TheiaApplicationShell {
6461
}
6562

6663
override async saveAll(options?: SaveOptions): Promise<void> {
67-
if (
68-
this.connectionStatusService.currentStatus === ConnectionStatus.OFFLINE
69-
) {
64+
// When there is no connection between the IDE2 frontend and backend.
65+
if (this.connectionStatusService.offlineStatus === 'backend') {
7066
this.messageService.error(
7167
nls.localize(
7268
'theia/core/couldNotSave',

arduino-ide-extension/src/browser/theia/core/connection-status-service.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
FrontendConnectionStatusService as TheiaFrontendConnectionStatusService,
55
} from '@theia/core/lib/browser/connection-status-service';
66
import type { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
7+
import { WebSocketConnectionProvider } from '@theia/core/lib/browser/index';
78
import { StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar';
89
import { Disposable } from '@theia/core/lib/common/disposable';
910
import { Emitter, Event } from '@theia/core/lib/common/event';
@@ -16,11 +17,11 @@ import {
1617
postConstruct,
1718
} from '@theia/core/shared/inversify';
1819
import { NotificationManager } from '@theia/messages/lib/browser/notifications-manager';
20+
import debounce from 'lodash.debounce';
1921
import { ArduinoDaemon } from '../../../common/protocol';
2022
import { assertUnreachable } from '../../../common/utils';
2123
import { CreateFeatures } from '../../create/create-features';
2224
import { NotificationCenter } from '../../notification-center';
23-
import debounce from 'lodash.debounce';
2425

2526
@injectable()
2627
export class IsOnline implements FrontendApplicationContribution {
@@ -113,6 +114,8 @@ export class FrontendConnectionStatusService extends TheiaFrontendConnectionStat
113114
private readonly daemonPort: DaemonPort;
114115
@inject(IsOnline)
115116
private readonly isOnline: IsOnline;
117+
@inject(WebSocketConnectionProvider)
118+
private readonly connectionProvider: WebSocketConnectionProvider;
116119

117120
@postConstruct()
118121
protected override async init(): Promise<void> {
@@ -125,6 +128,10 @@ export class FrontendConnectionStatusService extends TheiaFrontendConnectionStat
125128
}
126129

127130
protected override async performPingRequest(): Promise<void> {
131+
if (!this.connectionProvider['socket'].connected) {
132+
this.updateStatus(false);
133+
return;
134+
}
128135
try {
129136
await this.pingService.ping();
130137
this.updateStatus(this.isOnline.online);
@@ -164,6 +171,8 @@ export class ApplicationConnectionStatusContribution extends TheiaApplicationCon
164171
private readonly notificationManager: NotificationManager;
165172
@inject(CreateFeatures)
166173
private readonly createFeatures: CreateFeatures;
174+
@inject(WebSocketConnectionProvider)
175+
private readonly connectionProvider: WebSocketConnectionProvider;
167176

168177
private readonly offlineStatusDidChangeEmitter = new Emitter<
169178
OfflineConnectionStatus | undefined
@@ -190,9 +199,10 @@ export class ApplicationConnectionStatusContribution extends TheiaApplicationCon
190199
}
191200

192201
protected override handleOffline(): void {
193-
const params = {
202+
const params = <OfflineMessageParams>{
194203
port: this.daemonPort.port,
195204
online: this.isOnline.online,
205+
backendConnected: this.connectionProvider['socket'].connected, // https://github.com/arduino/arduino-ide/issues/2081
196206
};
197207
this._offlineStatus = offlineConnectionStatusType(params);
198208
const { text, tooltip } = offlineMessage(params);
@@ -248,6 +258,7 @@ export class ApplicationConnectionStatusContribution extends TheiaApplicationCon
248258
interface OfflineMessageParams {
249259
readonly port: string | undefined;
250260
readonly online: boolean;
261+
readonly backendConnected: boolean;
251262
}
252263
interface OfflineMessage {
253264
readonly text: string;
@@ -272,8 +283,8 @@ export function offlineMessage(params: OfflineMessageParams): OfflineMessage {
272283
function offlineConnectionStatusType(
273284
params: OfflineMessageParams
274285
): OfflineConnectionStatus {
275-
const { port, online } = params;
276-
if (port && online) {
286+
const { port, online, backendConnected } = params;
287+
if (!backendConnected || (port && online)) {
277288
return 'backend';
278289
}
279290
if (!port) {

arduino-ide-extension/src/common/protocol/executable-service.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@ export interface ExecutableService {
55
clangdUri: string;
66
cliUri: string;
77
lsUri: string;
8-
fwuploaderUri: string;
98
}>;
109
}

arduino-ide-extension/src/node/arduino-daemon-impl.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ export class ArduinoDaemonImpl
4444

4545
private _running = false;
4646
private _port = new Deferred<string>();
47-
private _execPath: string | undefined;
4847

4948
// Backend application lifecycle.
5049

@@ -68,7 +67,7 @@ export class ArduinoDaemonImpl
6867
async start(): Promise<string> {
6968
try {
7069
this.toDispose.dispose(); // This will `kill` the previously started daemon process, if any.
71-
const cliPath = await this.getExecPath();
70+
const cliPath = this.getExecPath();
7271
this.onData(`Starting daemon from ${cliPath}...`);
7372
const { daemon, port } = await this.spawnDaemonProcess();
7473
// Watchdog process for terminating the daemon process when the backend app terminates.
@@ -132,12 +131,8 @@ export class ArduinoDaemonImpl
132131
return this.onDaemonStoppedEmitter.event;
133132
}
134133

135-
async getExecPath(): Promise<string> {
136-
if (this._execPath) {
137-
return this._execPath;
138-
}
139-
this._execPath = await getExecPath('arduino-cli', this.onError.bind(this));
140-
return this._execPath;
134+
getExecPath(): string {
135+
return getExecPath('arduino-cli');
141136
}
142137

143138
protected async getSpawnArgs(): Promise<string[]> {
@@ -151,7 +146,7 @@ export class ArduinoDaemonImpl
151146
'--port',
152147
'0',
153148
'--config-file',
154-
`"${cliConfigPath}"`,
149+
cliConfigPath,
155150
'-v',
156151
];
157152
if (debug) {
@@ -173,10 +168,8 @@ export class ArduinoDaemonImpl
173168
daemon: ChildProcess;
174169
port: string;
175170
}> {
176-
const [cliPath, args] = await Promise.all([
177-
this.getExecPath(),
178-
this.getSpawnArgs(),
179-
]);
171+
const args = await this.getSpawnArgs();
172+
const cliPath = this.getExecPath();
180173
const ready = new Deferred<{ daemon: ChildProcess; port: string }>();
181174
const options = { shell: true };
182175
const daemon = spawn(`"${cliPath}"`, args, options);
Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,22 @@
1+
import { ILogger } from '@theia/core/lib/common/logger';
2+
import { inject, injectable, named } from '@theia/core/shared/inversify';
3+
import type { Port } from '../common/protocol';
14
import {
25
ArduinoFirmwareUploader,
36
FirmwareInfo,
47
} from '../common/protocol/arduino-firmware-uploader';
5-
import { injectable, inject, named } from '@theia/core/shared/inversify';
6-
import { ExecutableService, Port } from '../common/protocol';
78
import { getExecPath, spawnCommand } from './exec-util';
8-
import { ILogger } from '@theia/core/lib/common/logger';
99
import { MonitorManager } from './monitor-manager';
1010

1111
@injectable()
1212
export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
13-
@inject(ExecutableService)
14-
protected executableService: ExecutableService;
15-
16-
protected _execPath: string | undefined;
17-
1813
@inject(ILogger)
1914
@named('fwuploader')
20-
protected readonly logger: ILogger;
21-
15+
private readonly logger: ILogger;
2216
@inject(MonitorManager)
23-
protected readonly monitorManager: MonitorManager;
24-
25-
protected onError(error: any): void {
26-
this.logger.error(error);
27-
}
28-
29-
async getExecPath(): Promise<string> {
30-
if (this._execPath) {
31-
return this._execPath;
32-
}
33-
this._execPath = await getExecPath('arduino-fwuploader');
34-
return this._execPath;
35-
}
36-
37-
async runCommand(args: string[]): Promise<any> {
38-
const execPath = await this.getExecPath();
39-
return await spawnCommand(`"${execPath}"`, args, this.onError.bind(this));
40-
}
17+
private readonly monitorManager: MonitorManager;
4118

42-
async uploadCertificates(command: string): Promise<any> {
19+
async uploadCertificates(command: string): Promise<string> {
4320
return await this.runCommand(['certificates', 'flash', command]);
4421
}
4522

@@ -70,14 +47,13 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
7047
}
7148

7249
async flash(firmware: FirmwareInfo, port: Port): Promise<string> {
73-
let output;
7450
const board = {
7551
name: firmware.board_name,
7652
fqbn: firmware.board_fqbn,
7753
};
7854
try {
7955
await this.monitorManager.notifyUploadStarted(board.fqbn, port);
80-
output = await this.runCommand([
56+
const output = await this.runCommand([
8157
'firmware',
8258
'flash',
8359
'--fqbn',
@@ -87,11 +63,18 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
8763
'--module',
8864
`${firmware.module}@${firmware.firmware_version}`,
8965
]);
90-
} catch (e) {
91-
throw e;
66+
return output;
9267
} finally {
9368
await this.monitorManager.notifyUploadFinished(board.fqbn, port);
94-
return output;
9569
}
9670
}
71+
72+
private onError(error: Error): void {
73+
this.logger.error(error);
74+
}
75+
76+
private async runCommand(args: string[]): Promise<string> {
77+
const execPath = getExecPath('arduino-fwuploader');
78+
return await spawnCommand(execPath, args, this.onError.bind(this));
79+
}
9780
}

0 commit comments

Comments
 (0)
0