From b4bf9f18ad46a71bc82a06871c78b2db00970527 Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Sat, 19 Aug 2023 12:36:43 +0200 Subject: [PATCH 1/2] fix: expand boards if available on detected port moved the board inference logic from UI to model Closes #2175 Signed-off-by: Akos Kitta --- .../certificate-uploader-component.tsx | 17 +-- .../select-board-components.tsx | 22 +--- .../firmware-uploader-component.tsx | 24 ++-- .../src/common/protocol/board-list.ts | 31 +++-- .../src/test/common/board-list.test.ts | 124 ++++++++++++++++++ 5 files changed, 166 insertions(+), 52 deletions(-) diff --git a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-component.tsx b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-component.tsx index 21f8f2406..91e8126af 100644 --- a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-component.tsx +++ b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-component.tsx @@ -1,10 +1,7 @@ import { nls } from '@theia/core/lib/common/nls'; import React from '@theia/core/shared/react'; import Tippy from '@tippyjs/react'; -import { - BoardList, - isInferredBoardListItem, -} from '../../../common/protocol/board-list'; +import type { BoardList } from '../../../common/protocol/board-list'; import { boardIdentifierEquals, portIdentifierEquals, @@ -50,9 +47,7 @@ export const CertificateUploaderComponent = ({ if (!selectedItem) { return; } - const board = isInferredBoardListItem(selectedItem) - ? selectedItem.inferredBoard - : selectedItem.board; + const board = selectedItem.board; if (!board.fqbn) { return; } @@ -76,13 +71,9 @@ export const CertificateUploaderComponent = ({ if (!item) { return; } - const board = isInferredBoardListItem(item) - ? item.inferredBoard - : item.board; - const selectedBoard = isInferredBoardListItem(selectedItem) - ? selectedItem.inferredBoard - : selectedItem?.board; + const board = item.board; const port = item.port; + const selectedBoard = selectedItem?.board; const selectedPort = selectedItem?.port; if ( diff --git a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx index 49aa5617d..1f59b5239 100644 --- a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx +++ b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx @@ -1,14 +1,12 @@ import { nls } from '@theia/core/lib/common'; import React from '@theia/core/shared/react'; -import { +import type { BoardList, BoardListItemWithBoard, - InferredBoardListItem, - isInferredBoardListItem, } from '../../../common/protocol/board-list'; import { ArduinoSelect } from '../../widgets/arduino-select'; -export type BoardOptionValue = BoardListItemWithBoard | InferredBoardListItem; +export type BoardOptionValue = BoardListItemWithBoard; type BoardOption = { value: BoardOptionValue | undefined; label: string }; export const SelectBoardComponent = ({ @@ -46,9 +44,7 @@ export const SelectBoardComponent = ({ 'Select a board...' ); const updatableBoards = boardList.boards.filter((item) => { - const fqbn = ( - isInferredBoardListItem(item) ? item.inferredBoard : item.board - ).fqbn; + const fqbn = item.board.fqbn; return fqbn && updatableFqbns.includes(fqbn); }); let selBoard = -1; @@ -57,15 +53,12 @@ export const SelectBoardComponent = ({ if (selectedItem === item) { selBoard = i; } - const board = isInferredBoardListItem(item) - ? item.inferredBoard - : item.board; return { label: nls.localize( 'arduino/certificate/boardAtPort', '{0} at {1}', - board.name, - item.port?.address ?? '' + item.board.name, + item.port.address ?? '' ), value: item, }; @@ -100,10 +93,7 @@ export const SelectBoardComponent = ({ label: nls.localize( 'arduino/certificate/boardAtPort', '{0} at {1}', - (isInferredBoardListItem(selectedItem) - ? selectedItem.inferredBoard - : selectedItem.board - ).name, + selectedItem.board.name, selectedItem.port.address ?? '' ), }) || diff --git a/arduino-ide-extension/src/browser/dialogs/firmware-uploader/firmware-uploader-component.tsx b/arduino-ide-extension/src/browser/dialogs/firmware-uploader/firmware-uploader-component.tsx index 774645ae4..d7ba26803 100644 --- a/arduino-ide-extension/src/browser/dialogs/firmware-uploader/firmware-uploader-component.tsx +++ b/arduino-ide-extension/src/browser/dialogs/firmware-uploader/firmware-uploader-component.tsx @@ -9,10 +9,9 @@ import { ArduinoFirmwareUploader, FirmwareInfo, } from '../../../common/protocol/arduino-firmware-uploader'; -import { +import type { BoardList, BoardListItemWithBoard, - isInferredBoardListItem, } from '../../../common/protocol/board-list'; import { ArduinoSelect } from '../../widgets/arduino-select'; import { SelectBoardComponent } from '../certificate-uploader/select-board-components'; @@ -63,9 +62,7 @@ export const FirmwareUploaderComponent = ({ } // fetch the firmwares for the selected board - const board = isInferredBoardListItem(selectedItem) - ? selectedItem.inferredBoard - : selectedItem.board; + const board = selectedItem.board; const firmwaresForFqbn = await firmwareUploader.availableFirmwares( board.fqbn || '' ); @@ -89,11 +86,14 @@ export const FirmwareUploaderComponent = ({ (firmware) => firmware.firmware_version === selectedFirmware?.value ); + const selectedBoard = selectedItem?.board; + const selectedPort = selectedItem?.port; try { const installStatus = - !!firmwareToFlash && - !!selectedItem?.board && - (await flashFirmware(firmwareToFlash, selectedItem?.port)); + firmwareToFlash && + selectedBoard && + selectedPort && + (await flashFirmware(firmwareToFlash, selectedPort)); setInstallFeedback((installStatus && 'ok') || 'fail'); } catch { @@ -106,13 +106,9 @@ export const FirmwareUploaderComponent = ({ if (!item) { return; } - const board = isInferredBoardListItem(item) - ? item.inferredBoard - : item.board; - const selectedBoard = isInferredBoardListItem(selectedItem) - ? selectedItem.inferredBoard - : selectedItem?.board; + const board = item.board; const port = item.port; + const selectedBoard = selectedItem?.board; const selectedPort = selectedItem?.port; if ( diff --git a/arduino-ide-extension/src/common/protocol/board-list.ts b/arduino-ide-extension/src/common/protocol/board-list.ts index ee2c0448f..f17bf0600 100644 --- a/arduino-ide-extension/src/common/protocol/board-list.ts +++ b/arduino-ide-extension/src/common/protocol/board-list.ts @@ -362,9 +362,12 @@ export interface BoardList { readonly selectedIndex: number; /** - * Contains all boards recognized from the detected port, and an optional unrecognized one that is derived from the detected port and the `initParam#selectedBoard`. + * Contains all the following board+port pairs: + * - one discovered board on a detected board (`1`), + * - manually selected or overridden board for a detected port (`1`), + * - multiple discovered boards on detected port (`1..*`) */ - readonly boards: readonly (BoardListItemWithBoard | InferredBoardListItem)[]; + readonly boards: readonly BoardListItemWithBoard[]; /** * If `predicate` is not defined, no ports are filtered. @@ -511,17 +514,27 @@ function collectPorts( function collectBoards( items: readonly BoardListItem[] -): readonly (BoardListItemWithBoard | InferredBoardListItem)[] { - const boards: (BoardListItemWithBoard | InferredBoardListItem)[] = []; +): readonly BoardListItemWithBoard[] { + const result: BoardListItemWithBoard[] = []; for (let i = 0; i < items.length; i++) { + const boards: BoardListItemWithBoard[] = []; const item = items[i]; - if (isInferredBoardListItem(item)) { - boards.push(item); - } else if (item.board?.fqbn) { - boards.push(>item); + const { port } = item; + const board = getInferredBoardOrBoard(item); + if (board) { + boards.push({ board, port }); } + if (isMultiBoardsBoardListItem(item)) { + for (const otherBoard of item.boards) { + if (!boardIdentifierEquals(board, otherBoard)) { + boards.push({ board: otherBoard, port }); + } + } + } + boards.sort(boardListItemComparator); + result.push(...boards); } - return boards; + return result; } function findSelectedIndex( diff --git a/arduino-ide-extension/src/test/common/board-list.test.ts b/arduino-ide-extension/src/test/common/board-list.test.ts index a9c5248b9..fe02fa4a1 100644 --- a/arduino-ide-extension/src/test/common/board-list.test.ts +++ b/arduino-ide-extension/src/test/common/board-list.test.ts @@ -328,6 +328,130 @@ describe('board-list', () => { expect(items[0].labels.boardLabel).to.be.equal(Unknown); }); + describe('boards', () => { + it('should include discovered boards on detected ports', () => { + const { boards } = createBoardList({ + ...detectedPort(unoSerialPort, uno), + ...detectedPort(mkr1000SerialPort, mkr1000), + ...detectedPort(undiscoveredSerialPort), + }); + expect(boards).to.deep.equal([ + { + port: mkr1000SerialPort, + board: mkr1000, + }, + { + port: unoSerialPort, + board: uno, + }, + ]); + }); + + it('should include manually selected boards on detected ports', () => { + const { boards } = createBoardList({ + ...detectedPort(unoSerialPort, uno), + ...detectedPort(undiscoveredSerialPort, uno), + ...detectedPort(undiscoveredUsbToUARTSerialPort), + }); + expect(boards).to.deep.equal([ + { + port: unoSerialPort, + board: uno, + }, + { + port: undiscoveredSerialPort, + board: uno, + }, + ]); + }); + + it('should include manually overridden boards on detected ports', () => { + const { boards } = createBoardList( + { + ...detectedPort(unoSerialPort, uno), + ...detectedPort(mkr1000SerialPort, mkr1000), + }, + emptyBoardsConfig(), + { + ...history(unoSerialPort, mkr1000), + } + ); + expect(boards).to.deep.equal([ + { + port: mkr1000SerialPort, + board: mkr1000, + }, + { + port: unoSerialPort, + board: mkr1000, + }, + ]); + }); + + it('should include all boards discovered on a port', () => { + const { boards } = createBoardList({ + ...detectedPort( + nanoEsp32SerialPort, + arduinoNanoEsp32, + esp32NanoEsp32 + ), + ...detectedPort( + nanoEsp32DetectsMultipleEsp32BoardsSerialPort, + esp32S3DevModule, + esp32S3Box + ), + }); + expect(boards).to.deep.equal([ + { + port: nanoEsp32SerialPort, + board: arduinoNanoEsp32, + }, + { + port: nanoEsp32SerialPort, + board: esp32NanoEsp32, + }, + { + port: nanoEsp32DetectsMultipleEsp32BoardsSerialPort, + board: esp32S3Box, + }, + { + port: nanoEsp32DetectsMultipleEsp32BoardsSerialPort, + board: esp32S3DevModule, + }, + ]); + }); + + it('should include all boards discovered on a port (handle manual select)', () => { + const { boards } = createBoardList( + { + ...detectedPort( + nanoEsp32SerialPort, + arduinoNanoEsp32, + esp32NanoEsp32 + ), + }, + emptyBoardsConfig(), + { + ...history(nanoEsp32SerialPort, esp32S3DevModule), + } + ); + expect(boards).to.deep.equal([ + { + port: nanoEsp32SerialPort, + board: arduinoNanoEsp32, + }, + { + port: nanoEsp32SerialPort, + board: esp32NanoEsp32, + }, + { + port: nanoEsp32SerialPort, + board: esp32S3DevModule, + }, + ]); + }); + }); + describe('defaultAction', () => { it("'select' should be the default action for identifier boards", () => { const { items } = createBoardList({ From 46ffb047fc4843dc70d4ad6243cca8e6637029f1 Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Sat, 19 Aug 2023 12:56:15 +0200 Subject: [PATCH 2/2] chore(cli): pin version to `0.34.0-rc.1` Signed-off-by: Akos Kitta --- arduino-ide-extension/package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arduino-ide-extension/package.json b/arduino-ide-extension/package.json index 2dde27623..4c013b1d8 100644 --- a/arduino-ide-extension/package.json +++ b/arduino-ide-extension/package.json @@ -172,11 +172,7 @@ ], "arduino": { "arduino-cli": { - "version": { - "owner": "arduino", - "repo": "arduino-cli", - "commitish": "38479dc" - } + "version": "0.34.0-rc.1" }, "arduino-fwuploader": { "version": "2.3.0"