mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-06-05 03:36:35 +00:00
Initial support of the default paths from the CLI.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
59553bf81f
commit
f9641a3d76
12
.vscode/tasks.json
vendored
12
.vscode/tasks.json
vendored
@ -4,7 +4,7 @@
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Arduino-PoC - Start Browser Example",
|
||||
"label": "Arduino Editor - Start Browser Example",
|
||||
"type": "shell",
|
||||
"command": "yarn --cwd ./arduino-ide-browser start",
|
||||
"group": "build",
|
||||
@ -15,7 +15,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Arduino-PoC - Watch Theia Extension",
|
||||
"label": "Arduino Editor - Watch Theia Extension",
|
||||
"type": "shell",
|
||||
"command": "yarn --cwd ./arduino-ide-extension watch",
|
||||
"group": "build",
|
||||
@ -26,7 +26,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Arduino-PoC - Watch Browser Example",
|
||||
"label": "Arduino Editor - Watch Browser Example",
|
||||
"type": "shell",
|
||||
"command": "yarn --cwd ./arduino-ide-browser watch",
|
||||
"group": "build",
|
||||
@ -37,11 +37,11 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Arduino-PoC - Watch All",
|
||||
"label": "Arduino Editor - Watch All",
|
||||
"type": "shell",
|
||||
"dependsOn": [
|
||||
"Arduino-PoC - Watch Theia Extension",
|
||||
"Arduino-PoC - Watch Browser Example"
|
||||
"Arduino Editor - Watch Theia Extension",
|
||||
"Arduino Editor - Watch Browser Example"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -30,7 +30,7 @@
|
||||
"theia": {
|
||||
"frontend": {
|
||||
"config": {
|
||||
"applicationName": "Arduino-PoC",
|
||||
"applicationName": "Arduino Editor",
|
||||
"defaultTheme": "arduino-theme",
|
||||
"preferences": {
|
||||
"editor.autoSave": "on"
|
||||
|
@ -33,7 +33,7 @@
|
||||
"target": "electron",
|
||||
"frontend": {
|
||||
"config": {
|
||||
"applicationName": "Arduino-PoC",
|
||||
"applicationName": "Arduino Editor",
|
||||
"defaultTheme": "arduino-theme",
|
||||
"preferences": {
|
||||
"editor.autoSave": "on"
|
||||
|
@ -543,25 +543,6 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// private async onNoBoardsInstalled() {
|
||||
// const action = await this.messageService.info("You have no boards installed. Use the boards manager to install one.", "Open Boards Manager");
|
||||
// if (!action) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// this.boardsListWidgetFrontendContribution.openView({ reveal: true });
|
||||
// }
|
||||
|
||||
// private async onUnknownBoard() {
|
||||
// const action = await this.messageService.warn("There's a board connected for which you need to install software." +
|
||||
// " If this were not a PoC we would offer you the right package now.", "Open Boards Manager");
|
||||
// if (!action) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// this.boardsListWidgetFrontendContribution.openView({ reveal: true });
|
||||
// }
|
||||
|
||||
private isArduinoToolbar(maybeToolbarWidget: any): boolean {
|
||||
if (maybeToolbarWidget instanceof ArduinoToolbar) {
|
||||
return true;
|
||||
|
@ -22,8 +22,19 @@ import { SketchesService, SketchesServicePath } from '../common/protocol/sketche
|
||||
import { MonitorServiceImpl } from './monitor/monitor-service-impl';
|
||||
import { MonitorService, MonitorServicePath, MonitorServiceClient } from '../common/protocol/monitor-service';
|
||||
import { MonitorClientProvider } from './monitor/monitor-client-provider';
|
||||
import { ArduinoCli } from './arduino-cli';
|
||||
import { ArduinoCliContribution } from './arduino-cli-contribution';
|
||||
import { CliContribution } from '@theia/core/lib/node';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
// Theia backend CLI contribution.
|
||||
bind(ArduinoCliContribution).toSelf().inSingletonScope();
|
||||
bind(CliContribution).toService(ArduinoCliContribution);
|
||||
|
||||
// Provides the path of the Ardunio CLI.
|
||||
bind(ArduinoCli).toSelf().inSingletonScope();
|
||||
|
||||
// Shared daemonn
|
||||
bind(ArduinoDaemon).toSelf().inSingletonScope();
|
||||
bind(BackendApplicationContribution).toService(ArduinoDaemon);
|
||||
|
||||
|
27
arduino-ide-extension/src/node/arduino-cli-contribution.ts
Normal file
27
arduino-ide-extension/src/node/arduino-cli-contribution.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { Argv, Arguments } from 'yargs';
|
||||
import { CliContribution } from '@theia/core/lib/node';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoCliContribution implements CliContribution {
|
||||
|
||||
protected _debugCli = false
|
||||
|
||||
configure(conf: Argv): void {
|
||||
conf.option('debug-cli', {
|
||||
description: 'Can be specified if the CLI daemon process was started externally.',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
nargs: 1
|
||||
});
|
||||
}
|
||||
|
||||
setArguments(args: Arguments): void {
|
||||
this._debugCli = args['debug-cli'];
|
||||
}
|
||||
|
||||
get debugCli(): boolean {
|
||||
return this._debugCli;
|
||||
}
|
||||
|
||||
}
|
79
arduino-ide-extension/src/node/arduino-cli.ts
Normal file
79
arduino-ide-extension/src/node/arduino-cli.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import * as os from 'os';
|
||||
import * as which from 'which';
|
||||
import * as cp from 'child_process';
|
||||
import { join, delimiter } from 'path';
|
||||
import { injectable } from 'inversify';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoCli {
|
||||
|
||||
async getExecPath(): Promise<string> {
|
||||
const build = join(__dirname, '..', '..', 'build');
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
which(`arduino-cli${os.platform() === 'win32' ? '.exe' : ''}`, { path: `${process.env.PATH}${delimiter}${build}` }, (err, path) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(path);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async getDefaultConfig(): Promise<ArduinoCli.Config> {
|
||||
const command = await this.getExecPath();
|
||||
return new Promise<ArduinoCli.Config>((resolve, reject) => {
|
||||
cp.execFile(
|
||||
command,
|
||||
['config', 'dump', '--format', 'json'],
|
||||
{ encoding: 'utf8' },
|
||||
(error, stdout, stderr) => {
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
throw new Error(stderr);
|
||||
}
|
||||
|
||||
// const { sketchbook_path: sketchDirPath, arduino_data: dataDirPath } = JSON.parse(raw);
|
||||
|
||||
// https://github.com/arduino/arduino-cli/issues/342
|
||||
// XXX: this is a hack. The CLI provides a non-valid JSON.
|
||||
const config: Partial<ArduinoCli.Config> = {};
|
||||
const raw = stdout.trim();
|
||||
for (const line of raw.split(/\r?\n/) || []) {
|
||||
// TODO: Named capture groups are avail from ES2018.
|
||||
// const pair = line.match(/(?<key>[^:]+):(?<value>[^,]+),?/);
|
||||
const pair = line.split(':').map(entry => entry.trim());
|
||||
if (pair[0] === 'sketchbook_path') {
|
||||
config.sketchDirPath = pair[1];
|
||||
} else if (pair[0] === 'arduino_data') {
|
||||
config.dataDirPath = pair[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.dataDirPath) {
|
||||
reject(new Error(`Could not parse config. 'arduino_data' was missing from: ${stdout}`));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.sketchDirPath) {
|
||||
reject(new Error(`Could not parse config. 'sketchbook_path' was missing from: ${stdout}`));
|
||||
return;
|
||||
}
|
||||
|
||||
resolve({ sketchDirPath: config.sketchDirPath, dataDirPath: config.dataDirPath });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace ArduinoCli {
|
||||
export interface Config {
|
||||
sketchDirPath: string;
|
||||
dataDirPath: string;
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
import * as which from 'which';
|
||||
import * as os from 'os';
|
||||
import { join, delimiter } from 'path';
|
||||
import { join } from 'path';
|
||||
import { exec, spawn, SpawnOptions } from 'child_process';
|
||||
import { inject, injectable, named } from 'inversify';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
@ -9,17 +7,22 @@ import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { environment } from '@theia/application-package/lib/environment';
|
||||
import { DaemonLog } from './daemon-log';
|
||||
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
|
||||
import { ArduinoCliContribution } from './arduino-cli-contribution';
|
||||
import { ArduinoCli } from './arduino-cli';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoDaemon implements BackendApplicationContribution {
|
||||
|
||||
// Set this to `true` if you want to connect to a CLI running in debug mode.
|
||||
static DEBUG_CLI = false;
|
||||
|
||||
@inject(ILogger)
|
||||
@named('daemon')
|
||||
protected readonly logger: ILogger
|
||||
|
||||
@inject(ArduinoCli)
|
||||
protected readonly cli: ArduinoCli;
|
||||
|
||||
@inject(ArduinoCliContribution)
|
||||
protected readonly cliContribution: ArduinoCliContribution;
|
||||
|
||||
@inject(ToolOutputServiceServer)
|
||||
protected readonly toolOutputService: ToolOutputServiceServer;
|
||||
|
||||
@ -27,17 +30,8 @@ export class ArduinoDaemon implements BackendApplicationContribution {
|
||||
|
||||
async onStart() {
|
||||
try {
|
||||
if (!ArduinoDaemon.DEBUG_CLI) {
|
||||
const build = join(__dirname, '..', '..', 'build');
|
||||
const executable = await new Promise<string>((resolve, reject) => {
|
||||
which(`arduino-cli${os.platform() === 'win32' ? '.exe' : ''}`, { path: `${process.env.PATH}${delimiter}${build}` }, (err, path) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(path);
|
||||
});
|
||||
});
|
||||
if (!this.cliContribution.debugCli) {
|
||||
const executable = await this.cli.getExecPath();
|
||||
this.logger.info(`>>> Starting 'arduino-cli' daemon... [${executable}]`);
|
||||
const daemon = exec(`${executable} --debug daemon`, (err, stdout, stderr) => {
|
||||
if (err || stderr) {
|
||||
@ -74,7 +68,7 @@ export class ArduinoDaemon implements BackendApplicationContribution {
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
this.isReady.resolve();
|
||||
if (!ArduinoDaemon.DEBUG_CLI) {
|
||||
if (!this.cliContribution.debugCli) {
|
||||
this.logger.info(`<<< The 'arduino-cli' daemon is up an running.`);
|
||||
} else {
|
||||
this.logger.info(`Assuming the 'arduino-cli' already runs in debug mode.`);
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import * as fs from 'fs';
|
||||
import * as grpc from '@grpc/grpc-js';
|
||||
import * as PQueue from 'p-queue';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common';
|
||||
import { WorkspaceServiceExt } from '../browser/workspace-service-ext';
|
||||
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
|
||||
import { ArduinoCoreClient } from './cli-protocol/commands/commands_grpc_pb';
|
||||
import {
|
||||
InitResp,
|
||||
@ -10,16 +16,9 @@ import {
|
||||
UpdateLibrariesIndexReq,
|
||||
UpdateLibrariesIndexResp
|
||||
} from './cli-protocol/commands/commands_pb';
|
||||
import { WorkspaceServiceExt } from '../browser/workspace-service-ext';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { CoreClientProvider, Client } from './core-client-provider';
|
||||
import * as PQueue from 'p-queue';
|
||||
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
|
||||
import { ArduinoCli } from './arduino-cli';
|
||||
import { Instance } from './cli-protocol/commands/common_pb';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { CoreClientProvider, Client } from './core-client-provider';
|
||||
|
||||
@injectable()
|
||||
export class CoreClientProviderImpl implements CoreClientProvider {
|
||||
@ -36,6 +35,9 @@ export class CoreClientProviderImpl implements CoreClientProvider {
|
||||
@inject(ToolOutputServiceServer)
|
||||
protected readonly toolOutputService: ToolOutputServiceServer;
|
||||
|
||||
@inject(ArduinoCli)
|
||||
protected readonly cli: ArduinoCli;
|
||||
|
||||
async getClient(workspaceRootOrResourceUri?: string): Promise<Client | undefined> {
|
||||
return this.clientRequestQueue.add(() => new Promise<Client | undefined>(async resolve => {
|
||||
const roots = await this.workspaceServiceExt.roots();
|
||||
@ -76,19 +78,19 @@ export class CoreClientProviderImpl implements CoreClientProvider {
|
||||
throw new Error(`Could not resolve filesystem path of URI: ${rootUri}.`);
|
||||
}
|
||||
|
||||
const defaultDownloadsDirPath = path.resolve(os.homedir(), 'Arduino-PoC', 'downloads');
|
||||
if (!fs.existsSync(defaultDownloadsDirPath)) {
|
||||
fs.mkdirpSync(defaultDownloadsDirPath);
|
||||
const { dataDirPath, sketchDirPath } = await this.cli.getDefaultConfig();
|
||||
|
||||
if (!fs.existsSync(dataDirPath)) {
|
||||
throw new Error(`Data dir path does not exist: ${dataDirPath}.`);
|
||||
}
|
||||
|
||||
const defaultDataDirPath = path.resolve(os.homedir(), 'Arduino-PoC', 'data')
|
||||
if (!fs.existsSync(defaultDataDirPath)) {
|
||||
fs.mkdirpSync(defaultDataDirPath);
|
||||
if (!fs.existsSync(sketchDirPath)) {
|
||||
throw new Error(`Sketch dir path does not exist: ${sketchDirPath}.`);
|
||||
}
|
||||
|
||||
config.setSketchbookdir(rootPath);
|
||||
config.setDatadir(defaultDataDirPath);
|
||||
config.setDownloadsdir(defaultDownloadsDirPath);
|
||||
config.setSketchbookdir(sketchDirPath);
|
||||
config.setDatadir(dataDirPath);
|
||||
config.setDownloadsdir(dataDirPath);
|
||||
config.setBoardmanageradditionalurlsList(['https://downloads.arduino.cc/packages/package_index.json']);
|
||||
|
||||
const initReq = new InitReq();
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "arduino-poc",
|
||||
"name": "arduino-editor",
|
||||
"version": "0.0.1",
|
||||
"description": "A PoC demonstrating an Arduino IDE built using Eclipse Theia",
|
||||
"description": "Arduino IDE built using Eclipse Theia",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/bcmi-labs/arduino-editor.git",
|
||||
"author": "Christian Weichel <christian.weichel@typefox.io>",
|
||||
@ -14,7 +14,7 @@
|
||||
"prepare": "lerna run prepare",
|
||||
"rebuild:browser": "theia rebuild:browser",
|
||||
"rebuild:electron": "theia rebuild:electron",
|
||||
"start": "cd arduino-ide-browser && yarn start",
|
||||
"start": "yarn --cwd ./arduino-ide-browser start",
|
||||
"watch": "lerna run watch --parallel"
|
||||
},
|
||||
"workspaces": [
|
||||
|
Loading…
x
Reference in New Issue
Block a user