mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-18 16:56:33 +00:00
Guard against no workspaces root.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
d8625ad9c3
commit
bfb0edf50c
@ -1,4 +1,6 @@
|
|||||||
import { inject, injectable } from 'inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
|
import URI from '@theia/core/lib/common/uri';
|
||||||
|
import { FileSystem } from '@theia/filesystem/lib/common';
|
||||||
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||||
import { WorkspaceServiceExt } from './workspace-service-ext';
|
import { WorkspaceServiceExt } from './workspace-service-ext';
|
||||||
|
|
||||||
@ -8,6 +10,9 @@ import { WorkspaceServiceExt } from './workspace-service-ext';
|
|||||||
@injectable()
|
@injectable()
|
||||||
export class WorkspaceServiceExtImpl implements WorkspaceServiceExt {
|
export class WorkspaceServiceExtImpl implements WorkspaceServiceExt {
|
||||||
|
|
||||||
|
@inject(FileSystem)
|
||||||
|
protected readonly fileSystem: FileSystem;
|
||||||
|
|
||||||
@inject(WorkspaceService)
|
@inject(WorkspaceService)
|
||||||
protected readonly delegate: WorkspaceService;
|
protected readonly delegate: WorkspaceService;
|
||||||
|
|
||||||
@ -16,4 +21,27 @@ export class WorkspaceServiceExtImpl implements WorkspaceServiceExt {
|
|||||||
return stats.map(stat => stat.uri);
|
return stats.map(stat => stat.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
async defaultWorkspaceUri(): Promise<string> {
|
||||||
|
const home = await this.fileSystem.getCurrentUserHome();
|
||||||
|
if (home) {
|
||||||
|
return new URI(home.uri).resolve('Arduino-PoC').resolve('workspace').toString();
|
||||||
|
}
|
||||||
|
throw new Error(`Could not locate current user's home folder.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async defaultDownloadsDirUri(): Promise<string> {
|
||||||
|
const home = await this.fileSystem.getCurrentUserHome();
|
||||||
|
if (home) {
|
||||||
|
return new URI(home.uri).resolve('Arduino-PoC').resolve('downloads').toString();
|
||||||
|
}
|
||||||
|
throw new Error(`Could not locate current user's home folder.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async defaultDataDirUri(): Promise<string> {
|
||||||
|
const home = await this.fileSystem.getCurrentUserHome();
|
||||||
|
if (home) {
|
||||||
|
return new URI(home.uri).resolve('Arduino-PoC').resolve('data').toString();
|
||||||
|
}
|
||||||
|
throw new Error(`Could not locate current user's home folder.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,4 +2,11 @@ export const WorkspaceServiceExtPath = '/services/workspace-service-ext';
|
|||||||
export const WorkspaceServiceExt = Symbol('WorkspaceServiceExt');
|
export const WorkspaceServiceExt = Symbol('WorkspaceServiceExt');
|
||||||
export interface WorkspaceServiceExt {
|
export interface WorkspaceServiceExt {
|
||||||
roots(): Promise<string[]>;
|
roots(): Promise<string[]>;
|
||||||
|
/**
|
||||||
|
* By default it is under `~/Arduino-PoC/workspace`.
|
||||||
|
* It might not exist yet.
|
||||||
|
*/
|
||||||
|
defaultWorkspaceUri(): Promise<string>;
|
||||||
|
defaultDownloadsDirUri(): Promise<string>;
|
||||||
|
defaultDataDirUri(): Promise<string>;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,11 @@ export class BoardsServiceImpl implements BoardsService {
|
|||||||
protected selectedBoard: Board | undefined;
|
protected selectedBoard: Board | undefined;
|
||||||
|
|
||||||
public async getAttachedBoards(): Promise<{ boards: Board[] }> {
|
public async getAttachedBoards(): Promise<{ boards: Board[] }> {
|
||||||
const { client, instance } = await this.coreClientProvider.getClient();
|
const coreClient = await this.coreClientProvider.getClient();
|
||||||
|
if (!coreClient) {
|
||||||
|
return { boards: [] };
|
||||||
|
}
|
||||||
|
const { client, instance } = coreClient;
|
||||||
|
|
||||||
const req = new BoardListReq();
|
const req = new BoardListReq();
|
||||||
req.setInstance(instance);
|
req.setInstance(instance);
|
||||||
@ -51,12 +55,16 @@ export class BoardsServiceImpl implements BoardsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async search(options: { query?: string }): Promise<{ items: BoardPackage[] }> {
|
async search(options: { query?: string }): Promise<{ items: BoardPackage[] }> {
|
||||||
const { client, instance } = await this.coreClientProvider.getClient();
|
const coreClient = await this.coreClientProvider.getClient();
|
||||||
|
if (!coreClient) {
|
||||||
|
return { items: [] };
|
||||||
|
}
|
||||||
|
const { client, instance } = coreClient;
|
||||||
|
|
||||||
const installedPlatformsReq = new PlatformListReq();
|
const installedPlatformsReq = new PlatformListReq();
|
||||||
installedPlatformsReq.setInstance(instance);
|
installedPlatformsReq.setInstance(instance);
|
||||||
const installedPlatformsResp = await new Promise<PlatformListResp>((resolve, reject) =>
|
const installedPlatformsResp = await new Promise<PlatformListResp>((resolve, reject) =>
|
||||||
client.platformList(installedPlatformsReq, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp))
|
client.platformList(installedPlatformsReq, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp))
|
||||||
);
|
);
|
||||||
const installedPlatforms = installedPlatformsResp.getInstalledPlatformList();
|
const installedPlatforms = installedPlatformsResp.getInstalledPlatformList();
|
||||||
|
|
||||||
@ -90,7 +98,11 @@ export class BoardsServiceImpl implements BoardsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async install(pkg: BoardPackage): Promise<void> {
|
async install(pkg: BoardPackage): Promise<void> {
|
||||||
const { client, instance } = await this.coreClientProvider.getClient();
|
const coreClient = await this.coreClientProvider.getClient();
|
||||||
|
if (!coreClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { client, instance } = coreClient;
|
||||||
|
|
||||||
const [ platform, boardName ] = pkg.id.split(":");
|
const [ platform, boardName ] = pkg.id.split(":");
|
||||||
|
|
||||||
|
@ -9,10 +9,12 @@ import { CoreClientProvider, Client } from './core-client-provider';
|
|||||||
import * as PQueue from 'p-queue';
|
import * as PQueue from 'p-queue';
|
||||||
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
|
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
|
||||||
import { Instance } from './cli-protocol/common_pb';
|
import { Instance } from './cli-protocol/common_pb';
|
||||||
|
import * as fs from 'fs-extra';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class CoreClientProviderImpl implements CoreClientProvider {
|
export class CoreClientProviderImpl implements CoreClientProvider {
|
||||||
|
|
||||||
|
protected clients = new Map<string, Client>();
|
||||||
protected readonly clientRequestQueue = new PQueue({ autoStart: true, concurrency: 1 });
|
protected readonly clientRequestQueue = new PQueue({ autoStart: true, concurrency: 1 });
|
||||||
|
|
||||||
@inject(FileSystem)
|
@inject(FileSystem)
|
||||||
@ -24,10 +26,8 @@ export class CoreClientProviderImpl implements CoreClientProvider {
|
|||||||
@inject(ToolOutputServiceServer)
|
@inject(ToolOutputServiceServer)
|
||||||
protected readonly toolOutputService: ToolOutputServiceServer;
|
protected readonly toolOutputService: ToolOutputServiceServer;
|
||||||
|
|
||||||
protected clients = new Map<string, Client>();
|
async getClient(workspaceRootOrResourceUri?: string): Promise<Client | undefined> {
|
||||||
|
return this.clientRequestQueue.add(() => new Promise<Client | undefined>(async resolve => {
|
||||||
async getClient(workspaceRootOrResourceUri?: string): Promise<Client> {
|
|
||||||
return this.clientRequestQueue.add(() => new Promise<Client>(async resolve => {
|
|
||||||
const roots = await this.workspaceServiceExt.roots();
|
const roots = await this.workspaceServiceExt.roots();
|
||||||
if (!workspaceRootOrResourceUri) {
|
if (!workspaceRootOrResourceUri) {
|
||||||
resolve(this.getOrCreateClient(roots[0]));
|
resolve(this.getOrCreateClient(roots[0]));
|
||||||
@ -47,7 +47,10 @@ export class CoreClientProviderImpl implements CoreClientProvider {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getOrCreateClient(rootUri: string): Promise<Client> {
|
protected async getOrCreateClient(rootUri: string | undefined): Promise<Client | undefined> {
|
||||||
|
if (!rootUri) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
const existing = this.clients.get(rootUri);
|
const existing = this.clients.get(rootUri);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
console.debug(`Reusing existing client for ${rootUri}.`);
|
console.debug(`Reusing existing client for ${rootUri}.`);
|
||||||
@ -60,11 +63,30 @@ export class CoreClientProviderImpl implements CoreClientProvider {
|
|||||||
const config = new Configuration();
|
const config = new Configuration();
|
||||||
const rootPath = await this.fileSystem.getFsPath(rootUri);
|
const rootPath = await this.fileSystem.getFsPath(rootUri);
|
||||||
if (!rootPath) {
|
if (!rootPath) {
|
||||||
throw new Error(`Could not resolve file-system path of URI: ${rootUri}.`);
|
throw new Error(`Could not resolve filesystem path of URI: ${rootUri}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultDownloadsDirUri = await this.workspaceServiceExt.defaultDownloadsDirUri();
|
||||||
|
const defaultDownloadsDirPath = await this.fileSystem.getFsPath(defaultDownloadsDirUri);
|
||||||
|
if (!defaultDownloadsDirPath) {
|
||||||
|
throw new Error(`Could not resolve filesystem path of URI: ${defaultDownloadsDirUri}.`);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(defaultDownloadsDirPath)) {
|
||||||
|
fs.mkdirpSync(defaultDownloadsDirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultDataDirUri = await this.workspaceServiceExt.defaultDataDirUri();
|
||||||
|
const defaultDataDirPath = await this.fileSystem.getFsPath(defaultDataDirUri);
|
||||||
|
if (!defaultDataDirPath) {
|
||||||
|
throw new Error(`Could not resolve filesystem path of URI: ${defaultDataDirUri}.`);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(defaultDataDirPath)) {
|
||||||
|
fs.mkdirpSync(defaultDataDirPath);
|
||||||
|
}
|
||||||
|
|
||||||
config.setSketchbookdir(rootPath);
|
config.setSketchbookdir(rootPath);
|
||||||
config.setDatadir(rootPath);
|
config.setDatadir(defaultDataDirPath);
|
||||||
config.setDownloadsdir(rootPath);
|
config.setDownloadsdir(defaultDownloadsDirPath);
|
||||||
|
|
||||||
const initReq = new InitReq();
|
const initReq = new InitReq();
|
||||||
initReq.setConfiguration(config);
|
initReq.setConfiguration(config);
|
||||||
|
@ -4,7 +4,7 @@ import { ArduinoCoreClient } from './cli-protocol/commands_grpc_pb';
|
|||||||
export const CoreClientProviderPath = '/services/core-client-provider';
|
export const CoreClientProviderPath = '/services/core-client-provider';
|
||||||
export const CoreClientProvider = Symbol('CoreClientProvider');
|
export const CoreClientProvider = Symbol('CoreClientProvider');
|
||||||
export interface CoreClientProvider {
|
export interface CoreClientProvider {
|
||||||
getClient(workspaceRootOrResourceUri?: string): Promise<Client>;
|
getClient(workspaceRootOrResourceUri?: string): Promise<Client | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Client {
|
export interface Client {
|
||||||
|
@ -32,7 +32,11 @@ export class CoreServiceImpl implements CoreService {
|
|||||||
}
|
}
|
||||||
const sketchpath = path.dirname(sketchFilePath);
|
const sketchpath = path.dirname(sketchFilePath);
|
||||||
|
|
||||||
const { client, instance } = await this.coreClientProvider.getClient(uri);
|
const coreClient = await this.coreClientProvider.getClient(uri);
|
||||||
|
if (!coreClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { client, instance } = coreClient;
|
||||||
|
|
||||||
const currentBoard = await this.boardsService.getSelectBoard();
|
const currentBoard = await this.boardsService.getSelectBoard();
|
||||||
if (!currentBoard) {
|
if (!currentBoard) {
|
||||||
@ -86,7 +90,11 @@ export class CoreServiceImpl implements CoreService {
|
|||||||
throw new Error(`selected board (${currentBoard.name}) has no FQBN`);
|
throw new Error(`selected board (${currentBoard.name}) has no FQBN`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { client, instance } = await this.coreClientProvider.getClient(uri);
|
const coreClient = await this.coreClientProvider.getClient(uri);
|
||||||
|
if (!coreClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { client, instance } = coreClient;
|
||||||
|
|
||||||
const req = new UploadReq();
|
const req = new UploadReq();
|
||||||
req.setInstance(instance);
|
req.setInstance(instance);
|
||||||
|
@ -15,7 +15,11 @@ export class LibraryServiceImpl implements LibraryService {
|
|||||||
protected readonly toolOutputService: ToolOutputServiceServer;
|
protected readonly toolOutputService: ToolOutputServiceServer;
|
||||||
|
|
||||||
async search(options: { query?: string; }): Promise<{ items: Library[] }> {
|
async search(options: { query?: string; }): Promise<{ items: Library[] }> {
|
||||||
const { client, instance } = await this.coreClientProvider.getClient();
|
const coreClient = await this.coreClientProvider.getClient();
|
||||||
|
if (!coreClient) {
|
||||||
|
return { items: [] };
|
||||||
|
}
|
||||||
|
const { client, instance } = coreClient;
|
||||||
|
|
||||||
const listReq = new LibraryListReq();
|
const listReq = new LibraryListReq();
|
||||||
listReq.setInstance(instance);
|
listReq.setInstance(instance);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user