Skip to content

Commit 6dc0351

Browse files
author
Akos Kitta
committed
feat: use Arduino CLI 0.36.0-rc.1 APIs
Signed-off-by: Akos Kitta <[email protected]>
1 parent 547a630 commit 6dc0351

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+5535
-3273
lines changed

Diff for: .github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ on:
4545

4646
env:
4747
# See vars.GO_VERSION field of https://github.com/arduino/arduino-cli/blob/master/DistTasks.yml
48-
GO_VERSION: '1.19'
48+
GO_VERSION: '1.21'
4949
# See: https://github.com/actions/setup-node/#readme
5050
NODE_VERSION: '18.17'
5151
JOB_TRANSFER_ARTIFACT: build-artifacts

Diff for: .github/workflows/check-i18n-task.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Check Internationalization
22

33
env:
44
# See vars.GO_VERSION field of https://github.com/arduino/arduino-cli/blob/master/DistTasks.yml
5-
GO_VERSION: '1.19'
5+
GO_VERSION: '1.21'
66

77
# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows
88
on:

Diff for: .github/workflows/i18n-nightly-push.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: i18n-nightly-push
22

33
env:
44
# See vars.GO_VERSION field of https://github.com/arduino/arduino-cli/blob/master/DistTasks.yml
5-
GO_VERSION: '1.19'
5+
GO_VERSION: '1.21'
66

77
on:
88
schedule:

Diff for: .github/workflows/i18n-weekly-pull.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: i18n-weekly-pull
22

33
env:
44
# See vars.GO_VERSION field of https://github.com/arduino/arduino-cli/blob/master/DistTasks.yml
5-
GO_VERSION: '1.19'
5+
GO_VERSION: '1.21'
66

77
on:
88
schedule:

Diff for: .github/workflows/themes-weekly-pull.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88

99
env:
1010
# See vars.GO_VERSION field of https://github.com/arduino/arduino-cli/blob/master/DistTasks.yml
11-
GO_VERSION: '1.19'
11+
GO_VERSION: '1.21'
1212
NODE_VERSION: '18.17'
1313

1414
jobs:

Diff for: arduino-ide-extension/package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,17 @@
169169
],
170170
"arduino": {
171171
"arduino-cli": {
172-
"version": "0.35.2"
172+
"version": "0.36.0-rc.1"
173173
},
174174
"arduino-fwuploader": {
175175
"version": "2.4.1"
176176
},
177177
"arduino-language-server": {
178-
"version": "0.7.6"
178+
"version": {
179+
"owner": "arduino",
180+
"repo": "arduino-language-server",
181+
"commitish": "91c2ba8"
182+
}
179183
},
180184
"clangd": {
181185
"version": "14.0.0"

Diff for: arduino-ide-extension/scripts/generate-protocol.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
(async () => {
44
const os = require('node:os');
55
const path = require('node:path');
6-
const { mkdirSync, promises: fs } = require('node:fs');
6+
const { mkdirSync, promises: fs, rmSync } = require('node:fs');
77
const { exec } = require('./utils');
88
const glob = require('glob');
99
const { SemVer, gte, valid: validSemVer } = require('semver');
@@ -140,6 +140,10 @@
140140

141141
const rpc = path.join(repository, 'rpc');
142142
const out = path.join(__dirname, '..', 'src', 'node', 'cli-protocol');
143+
// Must wipe the gen output folder. Otherwise, dangling service implementation remain in IDE2 code,
144+
// although it has been removed from the proto file.
145+
// For example, https://github.com/arduino/arduino-cli/commit/50a8bf5c3e61d5b661ccfcd6a055e82eeb510859.
146+
rmSync(out, { recursive: true, maxRetries: 5, force: true });
143147
mkdirSync(out, { recursive: true });
144148

145149
const protos = await new Promise((resolve) =>

Diff for: arduino-ide-extension/src/browser/contributions/ino-language.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,7 @@ export class InoLanguage extends SketchContribution {
196196
forceStart = false
197197
): Promise<void> {
198198
const port = await this.daemon.tryGetPort();
199-
if (!port) {
200-
return;
201-
}
202-
const portNumber = Number.parseInt(port, 10); // TODO: IDE2 APIs should provide a number and not string
203-
if (Number.isNaN(portNumber)) {
199+
if (typeof port !== 'number') {
204200
return;
205201
}
206202
const release = await this.languageServerStartMutex.acquire();
@@ -280,7 +276,7 @@ export class InoLanguage extends SketchContribution {
280276
lsPath,
281277
daemonAddress: {
282278
hostname: 'localhost',
283-
port: portNumber,
279+
port,
284280
instance: 1, // TODO: get it from the backend
285281
},
286282
clangdPath,

Diff for: arduino-ide-extension/src/browser/notification-center.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class NotificationCenter
4646
new Emitter<ProgressMessage>();
4747
private readonly indexUpdateDidFailEmitter =
4848
new Emitter<IndexUpdateDidFailParams>();
49-
private readonly daemonDidStartEmitter = new Emitter<string>();
49+
private readonly daemonDidStartEmitter = new Emitter<number>();
5050
private readonly daemonDidStopEmitter = new Emitter<void>();
5151
private readonly configDidChangeEmitter = new Emitter<ConfigState>();
5252
private readonly platformDidInstallEmitter = new Emitter<{
@@ -136,7 +136,7 @@ export class NotificationCenter
136136
this.indexUpdateDidFailEmitter.fire(params);
137137
}
138138

139-
notifyDaemonDidStart(port: string): void {
139+
notifyDaemonDidStart(port: number): void {
140140
this.daemonDidStartEmitter.fire(port);
141141
}
142142

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ export class DaemonPort implements FrontendApplicationContribution {
7474
@inject(NotificationCenter)
7575
private readonly notificationCenter: NotificationCenter;
7676

77-
private readonly onPortDidChangeEmitter = new Emitter<string | undefined>();
78-
private _port: string | undefined;
77+
private readonly onPortDidChangeEmitter = new Emitter<number | undefined>();
78+
private _port: number | undefined;
7979

8080
onStart(): void {
8181
this.daemon.tryGetPort().then(
@@ -91,15 +91,15 @@ export class DaemonPort implements FrontendApplicationContribution {
9191
this.onPortDidChangeEmitter.dispose();
9292
}
9393

94-
get port(): string | undefined {
94+
get port(): number | undefined {
9595
return this._port;
9696
}
9797

98-
get onDidChangePort(): Event<string | undefined> {
98+
get onDidChangePort(): Event<number | undefined> {
9999
return this.onPortDidChangeEmitter.event;
100100
}
101101

102-
private setPort(port: string | undefined): void {
102+
private setPort(port: number | undefined): void {
103103
const oldPort = this._port;
104104
this._port = port;
105105
if (this._port !== oldPort) {

Diff for: arduino-ide-extension/src/common/protocol/arduino-daemon.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ export interface ArduinoDaemon {
55
* Returns with a promise that resolves with the port
66
* of the CLI daemon when it's up and running.
77
*/
8-
getPort(): Promise<string>;
8+
getPort(): Promise<number>;
99
/**
1010
* Unlike `getPort` this method returns with a promise
1111
* that resolves to `undefined` when the daemon is not running.
1212
* Otherwise resolves to the CLI daemon port.
1313
*/
14-
tryGetPort(): Promise<string | undefined>;
15-
start(): Promise<string>;
14+
tryGetPort(): Promise<number | undefined>;
15+
start(): Promise<number>;
1616
stop(): Promise<void>;
17-
restart(): Promise<string>;
17+
restart(): Promise<number>;
1818
}

Diff for: arduino-ide-extension/src/common/protocol/boards-service.ts

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ export interface BoardsService
7575
}): Promise<BoardsPackage | undefined>;
7676
searchBoards({ query }: { query?: string }): Promise<BoardWithPackage[]>;
7777
getInstalledBoards(): Promise<BoardWithPackage[]>;
78+
/**
79+
* Returns with all installed platforms including the manually installed ones.
80+
*/
7881
getInstalledPlatforms(): Promise<BoardsPackage[]>;
7982
getBoardUserFields(options: {
8083
fqbn: string;

Diff for: arduino-ide-extension/src/common/protocol/notification-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export interface NotificationServiceClient {
5151
notifyIndexUpdateDidFail(params: IndexUpdateDidFailParams): void;
5252

5353
// Daemon
54-
notifyDaemonDidStart(port: string): void;
54+
notifyDaemonDidStart(port: number): void;
5555
notifyDaemonDidStop(): void;
5656

5757
// CLI config
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { credentials, makeClientConstructor } from '@grpc/grpc-js';
2+
import * as commandsGrpcPb from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
3+
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
4+
5+
export interface CreateClientOptions {
6+
/**
7+
* The port to the Arduino CLI daemon.
8+
*/
9+
readonly port: number;
10+
/**
11+
* Defaults to `'localhost'`.
12+
*/
13+
readonly host?: string;
14+
15+
/**
16+
* gRCP channel options. Defaults to `createDefaultChannelOptions` with `'0.0.0'` `appVersion`
17+
*/
18+
readonly channelOptions?: Record<string, unknown>;
19+
}
20+
21+
export function createDefaultChannelOptions(
22+
appVersion = '0.0.0'
23+
): Record<string, unknown> {
24+
return {
25+
'grpc.max_send_message_length': 512 * 1024 * 1024,
26+
'grpc.max_receive_message_length': 512 * 1024 * 1024,
27+
'grpc.primary_user_agent': `arduino-ide/${appVersion}`,
28+
};
29+
}
30+
31+
export function createArduinoCoreServiceClient(
32+
options: CreateClientOptions
33+
): ArduinoCoreServiceClient {
34+
const {
35+
port,
36+
host = 'localhost',
37+
channelOptions = createDefaultChannelOptions(),
38+
} = options;
39+
const address = `${host}:${port}`;
40+
// https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md#usage
41+
const ArduinoCoreServiceClient = makeClientConstructor(
42+
// @ts-expect-error: ignore
43+
commandsGrpcPb['cc.arduino.cli.commands.v1.ArduinoCoreService'],
44+
'ArduinoCoreServiceService'
45+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
46+
) as any;
47+
const client = new ArduinoCoreServiceClient(
48+
address,
49+
credentials.createInsecure(),
50+
channelOptions
51+
) as ArduinoCoreServiceClient;
52+
return client;
53+
}

Diff for: arduino-ide-extension/src/node/arduino-daemon-impl.ts

+18-12
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ export class ArduinoDaemonImpl
3939
private readonly processUtils: ProcessUtils;
4040

4141
private readonly toDispose = new DisposableCollection();
42-
private readonly onDaemonStartedEmitter = new Emitter<string>();
42+
private readonly onDaemonStartedEmitter = new Emitter<number>();
4343
private readonly onDaemonStoppedEmitter = new Emitter<void>();
4444

4545
private _running = false;
46-
private _port = new Deferred<string>();
46+
private _port = new Deferred<number>();
4747

4848
// Backend application lifecycle.
4949

@@ -53,18 +53,18 @@ export class ArduinoDaemonImpl
5353

5454
// Daemon API
5555

56-
async getPort(): Promise<string> {
56+
async getPort(): Promise<number> {
5757
return this._port.promise;
5858
}
5959

60-
async tryGetPort(): Promise<string | undefined> {
60+
async tryGetPort(): Promise<number | undefined> {
6161
if (this._running) {
6262
return this._port.promise;
6363
}
6464
return undefined;
6565
}
6666

67-
async start(): Promise<string> {
67+
async start(): Promise<number> {
6868
try {
6969
this.toDispose.dispose(); // This will `kill` the previously started daemon process, if any.
7070
const cliPath = this.getExecPath();
@@ -101,13 +101,13 @@ export class ArduinoDaemonImpl
101101
this.toDispose.dispose();
102102
}
103103

104-
async restart(): Promise<string> {
104+
async restart(): Promise<number> {
105105
return this.start();
106106
}
107107

108108
// Backend only daemon API
109109

110-
get onDaemonStarted(): Event<string> {
110+
get onDaemonStarted(): Event<number> {
111111
return this.onDaemonStartedEmitter.event;
112112
}
113113

@@ -150,11 +150,11 @@ export class ArduinoDaemonImpl
150150

151151
protected async spawnDaemonProcess(): Promise<{
152152
daemon: ChildProcess;
153-
port: string;
153+
port: number;
154154
}> {
155155
const args = await this.getSpawnArgs();
156156
const cliPath = this.getExecPath();
157-
const ready = new Deferred<{ daemon: ChildProcess; port: string }>();
157+
const ready = new Deferred<{ daemon: ChildProcess; port: number }>();
158158
const options = {
159159
env: { ...deepClone(process.env), NO_COLOR: String(true) },
160160
};
@@ -195,7 +195,13 @@ export class ArduinoDaemonImpl
195195

196196
if (port.length && address.length) {
197197
grpcServerIsReady = true;
198-
ready.resolve({ daemon, port });
198+
const portNumber = Number.parseInt(port, 10);
199+
if (Number.isNaN(portNumber)) {
200+
ready.reject(
201+
new Error(`Received a NaN port from the CLI: ${port}`)
202+
);
203+
}
204+
ready.resolve({ daemon, port: portNumber });
199205
}
200206
}
201207
});
@@ -225,7 +231,7 @@ export class ArduinoDaemonImpl
225231
return ready.promise;
226232
}
227233

228-
private fireDaemonStarted(port: string): void {
234+
private fireDaemonStarted(port: number): void {
229235
this._running = true;
230236
this._port.resolve(port);
231237
this.onDaemonStartedEmitter.fire(port);
@@ -238,7 +244,7 @@ export class ArduinoDaemonImpl
238244
}
239245
this._running = false;
240246
this._port.reject(); // Reject all pending.
241-
this._port = new Deferred<string>();
247+
this._port = new Deferred<number>();
242248
this.onDaemonStoppedEmitter.fire();
243249
this.notificationService.notifyDaemonDidStop();
244250
}

0 commit comments

Comments
 (0)