From fdda4a72d0ce7bc097d39f1b30a697b0071cfd8b Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Thu, 14 Nov 2019 21:06:51 +0100 Subject: [PATCH] Initial support for updating/downgrading cores. Signed-off-by: Akos Kitta --- .../browser/boards/boards-auto-installer.ts | 6 +-- .../browser/boards/boards-item-renderer.tsx | 35 ++++++++++--- .../component-list/component-list-item.tsx | 32 +++++++++--- .../component-list/component-list.tsx | 8 +-- .../filterable-list-container.tsx | 11 +++-- .../component-list/list-item-renderer.tsx | 13 +++-- .../list-widget-frontend-contribution.ts | 3 +- .../components/component-list/list-widget.tsx | 5 +- .../installation-progress-dialog.tsx | 4 +- .../browser/library/library-item-renderer.tsx | 10 +++- .../src/common/protocol/arduino-component.ts | 5 +- .../src/common/protocol/boards-service.ts | 6 +++ .../src/common/protocol/installable.ts | 14 ++++-- .../src/common/protocol/library-service.ts | 7 +-- .../src/node/boards-service-impl.ts | 49 ++++++++++++------- .../node/cli-protocol/commands/board_pb.d.ts | 1 + .../commands/commands_grpc_pb.d.ts | 1 + .../cli-protocol/commands/commands_pb.d.ts | 1 + .../node/cli-protocol/commands/common_pb.d.ts | 1 + .../cli-protocol/commands/compile_pb.d.ts | 1 + .../node/cli-protocol/commands/core_pb.d.ts | 5 ++ .../src/node/cli-protocol/commands/core_pb.js | 31 +++++++++++- .../node/cli-protocol/commands/lib_pb.d.ts | 1 + .../node/cli-protocol/commands/upload_pb.d.ts | 1 + .../cli-protocol/monitor/monitor_grpc_pb.d.ts | 1 + .../node/cli-protocol/monitor/monitor_pb.d.ts | 1 + .../src/node/library-service-impl.ts | 7 ++- 27 files changed, 195 insertions(+), 65 deletions(-) diff --git a/arduino-ide-extension/src/browser/boards/boards-auto-installer.ts b/arduino-ide-extension/src/browser/boards/boards-auto-installer.ts index 2ee282d6..62eaa6f1 100644 --- a/arduino-ide-extension/src/browser/boards/boards-auto-installer.ts +++ b/arduino-ide-extension/src/browser/boards/boards-auto-installer.ts @@ -43,17 +43,17 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution { // tslint:disable-next-line:max-line-length this.messageService.info(`The \`"${candidate.name}"\` core has to be installed for the currently selected \`"${selectedBoard.name}"\` board. Do you want to install it now?`, 'Yes', 'Install Manually').then(async answer => { if (answer === 'Yes') { - const dialog = new InstallationProgressDialog(candidate.name); + const dialog = new InstallationProgressDialog(candidate.name, candidate.availableVersions[0]); dialog.open(); try { - await this.boardsService.install(candidate); + await this.boardsService.install({ item: candidate }); } finally { dialog.close(); } } if (answer) { this.boardsManagerFrontendContribution.openView({ reveal: true }).then(widget => widget.refresh(candidate.name.toLocaleLowerCase())); - } + } }); } }) diff --git a/arduino-ide-extension/src/browser/boards/boards-item-renderer.tsx b/arduino-ide-extension/src/browser/boards/boards-item-renderer.tsx index 4b84360c..b9e29755 100644 --- a/arduino-ide-extension/src/browser/boards/boards-item-renderer.tsx +++ b/arduino-ide-extension/src/browser/boards/boards-item-renderer.tsx @@ -2,11 +2,18 @@ import * as React from 'react'; import { injectable } from 'inversify'; import { ListItemRenderer } from '../components/component-list/list-item-renderer'; import { BoardPackage } from '../../common/protocol/boards-service'; +import { Installable } from '../../common/protocol/installable'; +import { ComponentListItem } from '../components/component-list/component-list-item'; @injectable() export class BoardItemRenderer extends ListItemRenderer { - renderItem(item: BoardPackage, install: (item: BoardPackage) => Promise): React.ReactNode { + renderItem( + input: ComponentListItem.State & { item: BoardPackage }, + install: (item: BoardPackage) => Promise, + onVersionChange: (version: Installable.Version) => void): React.ReactNode { + + const { item } = input; const name = {item.name}; const author = {item.author}; const installedVersion = !!item.installedVersion &&
@@ -17,18 +24,34 @@ export class BoardItemRenderer extends ListItemRenderer { const summary =
{item.summary}
; const description =
{item.description}
; - const moreInfo = !!item.moreInfoLink && More info; - const installButton = item.installable && !item.installedVersion && - ; + const moreInfo = !!item.moreInfoLink && More info; + const onClickInstall = () => install(item); + const installButton = item.installable && + ; + + const onSelectChange = (event: React.ChangeEvent) => { + const version = event.target.value; + if (version) { + onVersionChange(version); + } + } const versions = (() => { const { availableVersions } = item; - if (!!item.installedVersion || availableVersions.length === 0) { + if (availableVersions.length === 0) { return undefined; } else if (availableVersions.length === 1) { return } else { - return ; + return ; } })(); diff --git a/arduino-ide-extension/src/browser/components/component-list/component-list-item.tsx b/arduino-ide-extension/src/browser/components/component-list/component-list-item.tsx index ea92dfc1..a9bd967c 100644 --- a/arduino-ide-extension/src/browser/components/component-list/component-list-item.tsx +++ b/arduino-ide-extension/src/browser/components/component-list/component-list-item.tsx @@ -1,25 +1,45 @@ import * as React from 'react'; +import { Installable } from '../../../common/protocol/installable'; +import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { ListItemRenderer } from './list-item-renderer'; -export class ComponentListItem extends React.Component> { +export class ComponentListItem extends React.Component, ComponentListItem.State> { + + constructor(props: ComponentListItem.Props) { + super(props); + if (props.item.installable) { + const version = props.item.availableVersions.filter(version => version !== props.item.installedVersion)[0]; + this.state = { + selectedVersion: version + }; + } + } protected async install(item: T): Promise { - await this.props.install(item); + await this.props.install(item, this.state.selectedVersion); + } + + protected onVersionChange(version: Installable.Version) { + this.setState({ selectedVersion: version }); } render(): React.ReactNode { - const { item, itemRenderer, install } = this.props; - return itemRenderer.renderItem(item, install.bind(this)); + const { item, itemRenderer } = this.props; + return itemRenderer.renderItem(Object.assign(this.state, { item }), this.install.bind(this), this.onVersionChange.bind(this)); } } export namespace ComponentListItem { - export interface Props { + export interface Props { readonly item: T; - readonly install: (item: T) => Promise; + readonly install: (item: T, version?: Installable.Version) => Promise; readonly itemRenderer: ListItemRenderer; } + export interface State { + selectedVersion?: Installable.Version; + } + } diff --git a/arduino-ide-extension/src/browser/components/component-list/component-list.tsx b/arduino-ide-extension/src/browser/components/component-list/component-list.tsx index 0fe2b2c5..d2ea87d5 100644 --- a/arduino-ide-extension/src/browser/components/component-list/component-list.tsx +++ b/arduino-ide-extension/src/browser/components/component-list/component-list.tsx @@ -1,8 +1,10 @@ import * as React from 'react'; +import { Installable } from '../../../common/protocol/installable'; +import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { ComponentListItem } from './component-list-item'; import { ListItemRenderer } from './list-item-renderer'; -export class ComponentList extends React.Component> { +export class ComponentList extends React.Component> { protected container?: HTMLElement; @@ -36,11 +38,11 @@ export class ComponentList extends React.Component> { export namespace ComponentList { - export interface Props { + export interface Props { readonly items: T[]; readonly itemLabel: (item: T) => string; readonly itemRenderer: ListItemRenderer; - readonly install: (item: T) => Promise; + readonly install: (item: T, version?: Installable.Version) => Promise; readonly resolveContainer: (element: HTMLElement) => void; } diff --git a/arduino-ide-extension/src/browser/components/component-list/filterable-list-container.tsx b/arduino-ide-extension/src/browser/components/component-list/filterable-list-container.tsx index 1211720f..bcd3a478 100644 --- a/arduino-ide-extension/src/browser/components/component-list/filterable-list-container.tsx +++ b/arduino-ide-extension/src/browser/components/component-list/filterable-list-container.tsx @@ -3,13 +3,14 @@ import debounce = require('lodash.debounce'); import { Event } from '@theia/core/lib/common/event'; import { Searchable } from '../../../common/protocol/searchable'; import { Installable } from '../../../common/protocol/installable'; +import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { InstallationProgressDialog } from '../installation-progress-dialog'; import { SearchBar } from './search-bar'; import { ListWidget } from './list-widget'; import { ComponentList } from './component-list'; import { ListItemRenderer } from './list-item-renderer'; -export class FilterableListContainer extends React.Component, FilterableListContainer.State> { +export class FilterableListContainer extends React.Component, FilterableListContainer.State> { constructor(props: Readonly>) { super(props); @@ -77,12 +78,12 @@ export class FilterableListContainer extends React.Component itemLabel(left).localeCompare(itemLabel(right))); } - protected async install(item: T): Promise { + protected async install(item: T, version: Installable.Version): Promise { const { installable, searchable, itemLabel } = this.props; - const dialog = new InstallationProgressDialog(itemLabel(item)); + const dialog = new InstallationProgressDialog(itemLabel(item), version); dialog.open(); try { - await installable.install(item); + await installable.install({ item, version }); const { items } = await searchable.search({ query: this.state.filterText }); this.setState({ items: this.sort(items) }); } finally { @@ -94,7 +95,7 @@ export class FilterableListContainer extends React.Component { + export interface Props { readonly container: ListWidget; readonly installable: Installable; readonly searchable: Searchable; diff --git a/arduino-ide-extension/src/browser/components/component-list/list-item-renderer.tsx b/arduino-ide-extension/src/browser/components/component-list/list-item-renderer.tsx index 11b32915..c7e3188a 100644 --- a/arduino-ide-extension/src/browser/components/component-list/list-item-renderer.tsx +++ b/arduino-ide-extension/src/browser/components/component-list/list-item-renderer.tsx @@ -1,14 +1,17 @@ import * as React from 'react'; import { inject, injectable } from 'inversify'; import { WindowService } from '@theia/core/lib/browser/window/window-service'; +import { Installable } from '../../../common/protocol/installable'; +import { ArduinoComponent } from '../../../common/protocol/arduino-component'; +import { ComponentListItem } from './component-list-item'; @injectable() -export abstract class ListItemRenderer { +export abstract class ListItemRenderer { @inject(WindowService) protected windowService: WindowService; - protected onClick = (event: React.SyntheticEvent) => { + protected onMoreInfoClick = (event: React.SyntheticEvent) => { const { target } = event.nativeEvent; if (target instanceof HTMLAnchorElement) { this.windowService.openNewWindow(target.href, { external: true }); @@ -16,6 +19,10 @@ export abstract class ListItemRenderer { } } - abstract renderItem(item: T, install: (item: T) => Promise): React.ReactNode; + abstract renderItem( + input: ComponentListItem.State & { item: T }, + install: (item: T) => Promise, + onVersionChange: (version: Installable.Version) => void + ): React.ReactNode; } \ No newline at end of file diff --git a/arduino-ide-extension/src/browser/components/component-list/list-widget-frontend-contribution.ts b/arduino-ide-extension/src/browser/components/component-list/list-widget-frontend-contribution.ts index 448f8070..f6f0c816 100644 --- a/arduino-ide-extension/src/browser/components/component-list/list-widget-frontend-contribution.ts +++ b/arduino-ide-extension/src/browser/components/component-list/list-widget-frontend-contribution.ts @@ -1,10 +1,11 @@ import { injectable } from 'inversify'; import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application'; import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution'; +import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { ListWidget } from './list-widget'; @injectable() -export abstract class ListWidgetFrontendContribution extends AbstractViewContribution> implements FrontendApplicationContribution { +export abstract class ListWidgetFrontendContribution extends AbstractViewContribution> implements FrontendApplicationContribution { async initializeLayout(): Promise { } diff --git a/arduino-ide-extension/src/browser/components/component-list/list-widget.tsx b/arduino-ide-extension/src/browser/components/component-list/list-widget.tsx index adeecb04..5af897e0 100644 --- a/arduino-ide-extension/src/browser/components/component-list/list-widget.tsx +++ b/arduino-ide-extension/src/browser/components/component-list/list-widget.tsx @@ -7,11 +7,12 @@ import { MaybePromise } from '@theia/core/lib/common/types'; import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget'; import { Installable } from '../../../common/protocol/installable'; import { Searchable } from '../../../common/protocol/searchable'; +import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { FilterableListContainer } from './filterable-list-container'; import { ListItemRenderer } from './list-item-renderer'; @injectable() -export abstract class ListWidget extends ReactWidget { +export abstract class ListWidget extends ReactWidget { /** * Do not touch or use it. It is for setting the focus on the `input` after the widget activation. @@ -78,7 +79,7 @@ export abstract class ListWidget extends ReactWidget { } export namespace ListWidget { - export interface Options { + export interface Options { readonly id: string; readonly label: string; readonly iconClass: string; diff --git a/arduino-ide-extension/src/browser/components/installation-progress-dialog.tsx b/arduino-ide-extension/src/browser/components/installation-progress-dialog.tsx index aefa3940..a59c49f4 100644 --- a/arduino-ide-extension/src/browser/components/installation-progress-dialog.tsx +++ b/arduino-ide-extension/src/browser/components/installation-progress-dialog.tsx @@ -4,9 +4,9 @@ export class InstallationProgressDialog extends AbstractDialog { readonly value = undefined; - constructor(componentName: string) { + constructor(componentName: string, version: string) { super({ title: 'Installation in progress' }); - this.contentNode.textContent = `Installing ${componentName}. Please wait.`; + this.contentNode.textContent = `Installing ${componentName} [${version}]. Please wait...`; } } diff --git a/arduino-ide-extension/src/browser/library/library-item-renderer.tsx b/arduino-ide-extension/src/browser/library/library-item-renderer.tsx index cb504273..67590624 100644 --- a/arduino-ide-extension/src/browser/library/library-item-renderer.tsx +++ b/arduino-ide-extension/src/browser/library/library-item-renderer.tsx @@ -1,12 +1,18 @@ import * as React from 'react'; import { injectable } from 'inversify'; import { Library } from '../../common/protocol/library-service'; +import { Installable } from '../../common/protocol/installable'; import { ListItemRenderer } from '../components/component-list/list-item-renderer'; +import { ComponentListItem } from '../components/component-list/component-list-item'; @injectable() export class LibraryItemRenderer extends ListItemRenderer { - renderItem(item: Library, install: (item: Library) => Promise): React.ReactNode { + renderItem( + input: ComponentListItem.State & { item: Library }, + install: (item: Library, version: Installable.Version) => Promise): React.ReactNode { + + const { item } = input; const name = {item.name}; const author = by {item.author}; const installedVersion = !!item.installedVersion &&
@@ -16,7 +22,7 @@ export class LibraryItemRenderer extends ListItemRenderer { const summary =
{item.summary}
; - const moreInfo = !!item.moreInfoLink && More info; + const moreInfo = !!item.moreInfoLink && More info; const installButton = item.installable && !item.installedVersion && ; diff --git a/arduino-ide-extension/src/common/protocol/arduino-component.ts b/arduino-ide-extension/src/common/protocol/arduino-component.ts index 1c16841a..ca6b37f1 100644 --- a/arduino-ide-extension/src/common/protocol/arduino-component.ts +++ b/arduino-ide-extension/src/common/protocol/arduino-component.ts @@ -1,3 +1,4 @@ +import { Installable } from './installable'; export interface ArduinoComponent { readonly name: string; @@ -6,8 +7,8 @@ export interface ArduinoComponent { readonly description: string; readonly moreInfoLink?: string; - readonly availableVersions: string[]; + readonly availableVersions: Installable.Version[]; readonly installable: boolean; - readonly installedVersion?: string; + readonly installedVersion?: Installable.Version; } diff --git a/arduino-ide-extension/src/common/protocol/boards-service.ts b/arduino-ide-extension/src/common/protocol/boards-service.ts index 5c0a662c..ad195c60 100644 --- a/arduino-ide-extension/src/common/protocol/boards-service.ts +++ b/arduino-ide-extension/src/common/protocol/boards-service.ts @@ -170,6 +170,12 @@ export interface BoardPackage extends ArduinoComponent { id: string; boards: Board[]; } +export namespace BoardPackage { + /** + * Most recent version comes first, then the previous versions. (`1.8.1`, `1.6.3`, `1.6.2`, `1.6.1` and so on.) + */ + export const VERSION_COMPARATOR = (left: string, right: string) => naturalCompare(right, left); +} export interface Board { name: string diff --git a/arduino-ide-extension/src/common/protocol/installable.ts b/arduino-ide-extension/src/common/protocol/installable.ts index f9d1887f..8032bed5 100644 --- a/arduino-ide-extension/src/common/protocol/installable.ts +++ b/arduino-ide-extension/src/common/protocol/installable.ts @@ -1,3 +1,11 @@ -export interface Installable { - install(item: T): Promise; -} \ No newline at end of file +import { ArduinoComponent } from './arduino-component'; + +export interface Installable { + /** + * If `options.version` is specified, that will be installed. Otherwise, `item.availableVersions[0]`. + */ + install(options: { item: T, version?: Installable.Version }): Promise; +} +export namespace Installable { + export type Version = string; +} diff --git a/arduino-ide-extension/src/common/protocol/library-service.ts b/arduino-ide-extension/src/common/protocol/library-service.ts index 67f463f7..a89705b4 100644 --- a/arduino-ide-extension/src/common/protocol/library-service.ts +++ b/arduino-ide-extension/src/common/protocol/library-service.ts @@ -5,14 +5,9 @@ import { ArduinoComponent } from './arduino-component'; export const LibraryServicePath = '/services/library-service'; export const LibraryService = Symbol('LibraryService'); export interface LibraryService extends Installable, Searchable { - install(library: Library): Promise; + install(options: { item: Library, version?: Installable.Version }): Promise; } export interface Library extends ArduinoComponent { readonly builtIn?: boolean; } - -export namespace Library { - // TODO: figure out whether we need a dedicated `version` type. - export type Version = string; -} \ No newline at end of file diff --git a/arduino-ide-extension/src/node/boards-service-impl.ts b/arduino-ide-extension/src/node/boards-service-impl.ts index ade97c54..ef265a37 100644 --- a/arduino-ide-extension/src/node/boards-service-impl.ts +++ b/arduino-ide-extension/src/node/boards-service-impl.ts @@ -2,10 +2,11 @@ import * as PQueue from 'p-queue'; import { injectable, inject, postConstruct, named } from 'inversify'; import { ILogger } from '@theia/core/lib/common/logger'; import { BoardsService, AttachedSerialBoard, BoardPackage, Board, AttachedNetworkBoard, BoardsServiceClient, Port } from '../common/protocol/boards-service'; -import { PlatformSearchReq, PlatformSearchResp, PlatformInstallReq, PlatformInstallResp, PlatformListReq, PlatformListResp } from './cli-protocol/commands/core_pb'; +import { PlatformSearchReq, PlatformSearchResp, PlatformInstallReq, PlatformInstallResp, PlatformListReq, PlatformListResp, Platform } from './cli-protocol/commands/core_pb'; import { CoreClientProvider } from './core-client-provider'; import { BoardListReq, BoardListResp } from './cli-protocol/commands/board_pb'; import { ToolOutputServiceServer } from '../common/protocol/tool-output-service'; +import { Installable } from '../common/protocol/installable'; @injectable() export class BoardsServiceImpl implements BoardsService { @@ -214,35 +215,47 @@ export class BoardsServiceImpl implements BoardsService { const req = new PlatformSearchReq(); req.setSearchArgs(options.query || ""); + req.setAllVersions(true); req.setInstance(instance); const resp = await new Promise((resolve, reject) => client.platformSearch(req, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp))); - - let items = resp.getSearchOutputList().map(item => { + const packages = new Map(); + const toPackage = (platform: Platform) => { let installedVersion: string | undefined; - const matchingPlatform = installedPlatforms.find(ip => ip.getId() === item.getId()); + const matchingPlatform = installedPlatforms.find(ip => ip.getId() === platform.getId()); if (!!matchingPlatform) { installedVersion = matchingPlatform.getInstalled(); } - - const result: BoardPackage = { - id: item.getId(), - name: item.getName(), - author: item.getMaintainer(), - availableVersions: [item.getLatest()], - description: item.getBoardsList().map(b => b.getName()).join(", "), + return { + id: platform.getId(), + name: platform.getName(), + author: platform.getMaintainer(), + availableVersions: [platform.getLatest()], + description: platform.getBoardsList().map(b => b.getName()).join(", "), installable: true, summary: "Boards included in this package:", installedVersion, - boards: item.getBoardsList().map(b => { name: b.getName(), fqbn: b.getFqbn() }), - moreInfoLink: item.getWebsite() + boards: platform.getBoardsList().map(b => { name: b.getName(), fqbn: b.getFqbn() }), + moreInfoLink: platform.getWebsite() } - return result; - }); + } - return { items }; + for (const platform of resp.getSearchOutputList()) { + const id = platform.getId(); + const pkg = packages.get(id); + if (pkg) { + pkg.availableVersions.push(platform.getLatest()); + pkg.availableVersions.sort(BoardPackage.VERSION_COMPARATOR); + } else { + packages.set(id, toPackage(platform)); + } + } + + return { items: [...packages.values()] }; } - async install(pkg: BoardPackage): Promise { + async install(options: { item: BoardPackage, version?: Installable.Version }): Promise { + const pkg = options.item; + const version = !!options.version ? options.version : pkg.availableVersions[0]; const coreClient = await this.coreClientProvider.getClient(); if (!coreClient) { return; @@ -255,7 +268,7 @@ export class BoardsServiceImpl implements BoardsService { req.setInstance(instance); req.setArchitecture(boardName); req.setPlatformPackage(platform); - req.setVersion(pkg.availableVersions[0]); + req.setVersion(version); console.info("Starting board installation", pkg); const resp = client.platformInstall(req); diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts index e78525fe..36ca1c93 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/board.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; import * as commands_common_pb from "../commands/common_pb"; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts index 678aed9c..14f0f46d 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/commands.proto /* tslint:disable */ +/* eslint-disable */ import * as grpc from "@grpc/grpc-js"; import * as commands_commands_pb from "../commands/commands_pb"; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/commands_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/commands_pb.d.ts index c484de35..f012e4c6 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/commands_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/commands_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/commands.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; import * as commands_common_pb from "../commands/common_pb"; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/common_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/common_pb.d.ts index ef8a08db..3dd0a50c 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/common_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/common_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/common.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/compile_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/compile_pb.d.ts index 39959cd0..3045037d 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/compile_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/compile_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/compile.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; import * as commands_common_pb from "../commands/common_pb"; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.d.ts index a62a8182..60eb973b 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/core.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; import * as commands_common_pb from "../commands/common_pb"; @@ -262,6 +263,9 @@ export class PlatformSearchReq extends jspb.Message { getSearchArgs(): string; setSearchArgs(value: string): void; + getAllVersions(): boolean; + setAllVersions(value: boolean): void; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): PlatformSearchReq.AsObject; @@ -277,6 +281,7 @@ export namespace PlatformSearchReq { export type AsObject = { instance?: commands_common_pb.Instance.AsObject, searchArgs: string, + allVersions: boolean, } } diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.js b/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.js index d1cb104a..24f93c12 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.js +++ b/arduino-ide-extension/src/node/cli-protocol/commands/core_pb.js @@ -1705,7 +1705,8 @@ proto.cc.arduino.cli.commands.PlatformSearchReq.prototype.toObject = function(op proto.cc.arduino.cli.commands.PlatformSearchReq.toObject = function(includeInstance, msg) { var f, obj = { instance: (f = msg.getInstance()) && commands_common_pb.Instance.toObject(includeInstance, f), - searchArgs: jspb.Message.getFieldWithDefault(msg, 2, "") + searchArgs: jspb.Message.getFieldWithDefault(msg, 2, ""), + allVersions: jspb.Message.getFieldWithDefault(msg, 3, false) }; if (includeInstance) { @@ -1751,6 +1752,10 @@ proto.cc.arduino.cli.commands.PlatformSearchReq.deserializeBinaryFromReader = fu var value = /** @type {string} */ (reader.readString()); msg.setSearchArgs(value); break; + case 3: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setAllVersions(value); + break; default: reader.skipField(); break; @@ -1795,6 +1800,13 @@ proto.cc.arduino.cli.commands.PlatformSearchReq.serializeBinaryToWriter = functi f ); } + f = message.getAllVersions(); + if (f) { + writer.writeBool( + 3, + f + ); + } }; @@ -1843,6 +1855,23 @@ proto.cc.arduino.cli.commands.PlatformSearchReq.prototype.setSearchArgs = functi }; +/** + * optional bool all_versions = 3; + * Note that Boolean fields may be set to 0/1 when serialized from a Java server. + * You should avoid comparisons like {@code val === true/false} in those cases. + * @return {boolean} + */ +proto.cc.arduino.cli.commands.PlatformSearchReq.prototype.getAllVersions = function() { + return /** @type {boolean} */ (jspb.Message.getFieldWithDefault(this, 3, false)); +}; + + +/** @param {boolean} value */ +proto.cc.arduino.cli.commands.PlatformSearchReq.prototype.setAllVersions = function(value) { + jspb.Message.setProto3BooleanField(this, 3, value); +}; + + /** * Generated by JsPbCodeGenerator. diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts index 25357ead..0b66c05b 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/lib.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; import * as commands_common_pb from "../commands/common_pb"; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/upload_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/upload_pb.d.ts index 1748edac..07241de7 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/upload_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/upload_pb.d.ts @@ -2,6 +2,7 @@ // file: commands/upload.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; import * as commands_common_pb from "../commands/common_pb"; diff --git a/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_grpc_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_grpc_pb.d.ts index 39438d7f..ae5bb0e8 100644 --- a/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_grpc_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_grpc_pb.d.ts @@ -2,6 +2,7 @@ // file: monitor/monitor.proto /* tslint:disable */ +/* eslint-disable */ import * as grpc from "@grpc/grpc-js"; import * as monitor_monitor_pb from "../monitor/monitor_pb"; diff --git a/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_pb.d.ts index e1ecf48f..beb2fcd1 100644 --- a/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/monitor/monitor_pb.d.ts @@ -2,6 +2,7 @@ // file: monitor/monitor.proto /* tslint:disable */ +/* eslint-disable */ import * as jspb from "google-protobuf"; import * as google_protobuf_struct_pb from "google-protobuf/google/protobuf/struct_pb"; diff --git a/arduino-ide-extension/src/node/library-service-impl.ts b/arduino-ide-extension/src/node/library-service-impl.ts index 93a9cc42..f44587b3 100644 --- a/arduino-ide-extension/src/node/library-service-impl.ts +++ b/arduino-ide-extension/src/node/library-service-impl.ts @@ -4,6 +4,7 @@ import { CoreClientProvider } from './core-client-provider'; import { LibrarySearchReq, LibrarySearchResp, LibraryListReq, LibraryListResp, LibraryRelease, InstalledLibrary, LibraryInstallReq, LibraryInstallResp } from './cli-protocol/commands/lib_pb'; import { ToolOutputServiceServer } from '../common/protocol/tool-output-service'; +import { Installable } from '../common/protocol/installable'; @injectable() export class LibraryServiceImpl implements LibraryService { @@ -58,7 +59,9 @@ export class LibraryServiceImpl implements LibraryService { return { items }; } - async install(library: Library): Promise { + async install(options: { item: Library, version?: Installable.Version }): Promise { + const library = options.item; + const version = !!options.version ? options.version : library.availableVersions[0]; const coreClient = await this.coreClientProvider.getClient(); if (!coreClient) { return; @@ -68,7 +71,7 @@ export class LibraryServiceImpl implements LibraryService { const req = new LibraryInstallReq(); req.setInstance(instance); req.setName(library.name); - req.setVersion(library.availableVersions[0]); + req.setVersion(version); const resp = client.libraryInstall(req); resp.on('data', (r: LibraryInstallResp) => {