diff --git a/arduino-ide-extension/src/browser/arduino-preferences.ts b/arduino-ide-extension/src/browser/arduino-preferences.ts index 8450012a6..627c141f6 100644 --- a/arduino-ide-extension/src/browser/arduino-preferences.ts +++ b/arduino-ide-extension/src/browser/arduino-preferences.ts @@ -182,6 +182,14 @@ export const ArduinoConfigSchema: PreferenceSchema = { ), default: true, }, + 'arduino.cli.daemon.debug': { + type: 'boolean', + description: nls.localize( + 'arduino/preferences/cli.daemonDebug', + "Enable debug logging of the gRPC calls to the Arduino CLI. A restart of the IDE is needed for this setting to take effect. It's false by default." + ), + default: false, + }, }, }; @@ -207,6 +215,7 @@ export interface ArduinoConfiguration { 'arduino.auth.audience': string; 'arduino.auth.registerUri': string; 'arduino.survey.notification': boolean; + 'arduino.cli.daemon.debug': boolean; } export const ArduinoPreferences = Symbol('ArduinoPreferences'); diff --git a/arduino-ide-extension/src/node/arduino-daemon-impl.ts b/arduino-ide-extension/src/node/arduino-daemon-impl.ts index e53d6afe3..928861680 100644 --- a/arduino-ide-extension/src/node/arduino-daemon-impl.ts +++ b/arduino-ide-extension/src/node/arduino-daemon-impl.ts @@ -1,4 +1,5 @@ import { join } from 'path'; +import { promises as fs } from 'fs'; import { inject, injectable, named } from '@theia/core/shared/inversify'; import { spawn, ChildProcess } from 'child_process'; import { FileUri } from '@theia/core/lib/node/file-uri'; @@ -142,9 +143,12 @@ export class ArduinoDaemonImpl } protected async getSpawnArgs(): Promise { - const configDirUri = await this.envVariablesServer.getConfigDirUri(); + const [configDirUri, debug] = await Promise.all([ + this.envVariablesServer.getConfigDirUri(), + this.debugDaemon(), + ]); const cliConfigPath = join(FileUri.fsPath(configDirUri), CLI_CONFIG); - return [ + const args = [ 'daemon', '--format', 'jsonmini', @@ -156,6 +160,41 @@ export class ArduinoDaemonImpl '--log-format', 'json', ]; + if (debug) { + args.push('--debug'); + } + return args; + } + + private async debugDaemon(): Promise { + // Poor man's preferences on the backend. (https://github.com/arduino/arduino-ide/issues/1056#issuecomment-1153975064) + const configDirUri = await this.envVariablesServer.getConfigDirUri(); + const configDirPath = FileUri.fsPath(configDirUri); + try { + const raw = await fs.readFile(join(configDirPath, 'settings.json'), { + encoding: 'utf8', + }); + const json = this.tryParse(raw); + if (json) { + const value = json['arduino.cli.daemon.debug']; + return typeof value === 'boolean' && !!value; + } + return false; + } catch (error) { + if ('code' in error && error.code === 'ENOENT') { + return false; + } + throw error; + } + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private tryParse(raw: string): any | undefined { + try { + return JSON.parse(raw); + } catch { + return undefined; + } } protected async spawnDaemonProcess(): Promise<{ diff --git a/i18n/en.json b/i18n/en.json index 08cafdf72..7cfc7fa5e 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -229,6 +229,7 @@ "board.certificates": "List of certificates that can be uploaded to boards", "browse": "Browse", "choose": "Choose", + "cli.daemonDebug": "Enable debug logging of the gRPC calls to the Arduino CLI. A restart of the IDE is needed for this setting to take effect. It's 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.",