Skip to content

Commit db01efe

Browse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
fix: expand boards if available on detected port
moved the board inference logic from UI to model Closes #2175 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent 5a76be3 commit db01efe

File tree

5 files changed

+166
-52
lines changed

5 files changed

+166
-52
lines changed

arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-component.tsx

+4-13
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { nls } from '@theia/core/lib/common/nls';
22
import React from '@theia/core/shared/react';
33
import Tippy from '@tippyjs/react';
4-
import {
5-
BoardList,
6-
isInferredBoardListItem,
7-
} from '../../../common/protocol/board-list';
4+
import type { BoardList } from '../../../common/protocol/board-list';
85
import {
96
boardIdentifierEquals,
107
portIdentifierEquals,
@@ -50,9 +47,7 @@ export const CertificateUploaderComponent = ({
5047
if (!selectedItem) {
5148
return;
5249
}
53-
const board = isInferredBoardListItem(selectedItem)
54-
? selectedItem.inferredBoard
55-
: selectedItem.board;
50+
const board = selectedItem.board;
5651
if (!board.fqbn) {
5752
return;
5853
}
@@ -76,13 +71,9 @@ export const CertificateUploaderComponent = ({
7671
if (!item) {
7772
return;
7873
}
79-
const board = isInferredBoardListItem(item)
80-
? item.inferredBoard
81-
: item.board;
82-
const selectedBoard = isInferredBoardListItem(selectedItem)
83-
? selectedItem.inferredBoard
84-
: selectedItem?.board;
74+
const board = item.board;
8575
const port = item.port;
76+
const selectedBoard = selectedItem?.board;
8677
const selectedPort = selectedItem?.port;
8778

8879
if (

arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx

+6-16
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import { nls } from '@theia/core/lib/common';
22
import React from '@theia/core/shared/react';
3-
import {
3+
import type {
44
BoardList,
55
BoardListItemWithBoard,
6-
InferredBoardListItem,
7-
isInferredBoardListItem,
86
} from '../../../common/protocol/board-list';
97
import { ArduinoSelect } from '../../widgets/arduino-select';
108

11-
export type BoardOptionValue = BoardListItemWithBoard | InferredBoardListItem;
9+
export type BoardOptionValue = BoardListItemWithBoard;
1210
type BoardOption = { value: BoardOptionValue | undefined; label: string };
1311

1412
export const SelectBoardComponent = ({
@@ -46,9 +44,7 @@ export const SelectBoardComponent = ({
4644
'Select a board...'
4745
);
4846
const updatableBoards = boardList.boards.filter((item) => {
49-
const fqbn = (
50-
isInferredBoardListItem(item) ? item.inferredBoard : item.board
51-
).fqbn;
47+
const fqbn = item.board.fqbn;
5248
return fqbn && updatableFqbns.includes(fqbn);
5349
});
5450
let selBoard = -1;
@@ -57,15 +53,12 @@ export const SelectBoardComponent = ({
5753
if (selectedItem === item) {
5854
selBoard = i;
5955
}
60-
const board = isInferredBoardListItem(item)
61-
? item.inferredBoard
62-
: item.board;
6356
return {
6457
label: nls.localize(
6558
'arduino/certificate/boardAtPort',
6659
'{0} at {1}',
67-
board.name,
68-
item.port?.address ?? ''
60+
item.board.name,
61+
item.port.address ?? ''
6962
),
7063
value: item,
7164
};
@@ -100,10 +93,7 @@ export const SelectBoardComponent = ({
10093
label: nls.localize(
10194
'arduino/certificate/boardAtPort',
10295
'{0} at {1}',
103-
(isInferredBoardListItem(selectedItem)
104-
? selectedItem.inferredBoard
105-
: selectedItem.board
106-
).name,
96+
selectedItem.board.name,
10797
selectedItem.port.address ?? ''
10898
),
10999
}) ||

arduino-ide-extension/src/browser/dialogs/firmware-uploader/firmware-uploader-component.tsx

+10-14
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ import {
99
ArduinoFirmwareUploader,
1010
FirmwareInfo,
1111
} from '../../../common/protocol/arduino-firmware-uploader';
12-
import {
12+
import type {
1313
BoardList,
1414
BoardListItemWithBoard,
15-
isInferredBoardListItem,
1615
} from '../../../common/protocol/board-list';
1716
import { ArduinoSelect } from '../../widgets/arduino-select';
1817
import { SelectBoardComponent } from '../certificate-uploader/select-board-components';
@@ -63,9 +62,7 @@ export const FirmwareUploaderComponent = ({
6362
}
6463

6564
// fetch the firmwares for the selected board
66-
const board = isInferredBoardListItem(selectedItem)
67-
? selectedItem.inferredBoard
68-
: selectedItem.board;
65+
const board = selectedItem.board;
6966
const firmwaresForFqbn = await firmwareUploader.availableFirmwares(
7067
board.fqbn || ''
7168
);
@@ -89,11 +86,14 @@ export const FirmwareUploaderComponent = ({
8986
(firmware) => firmware.firmware_version === selectedFirmware?.value
9087
);
9188

89+
const selectedBoard = selectedItem?.board;
90+
const selectedPort = selectedItem?.port;
9291
try {
9392
const installStatus =
94-
!!firmwareToFlash &&
95-
!!selectedItem?.board &&
96-
(await flashFirmware(firmwareToFlash, selectedItem?.port));
93+
firmwareToFlash &&
94+
selectedBoard &&
95+
selectedPort &&
96+
(await flashFirmware(firmwareToFlash, selectedPort));
9797

9898
setInstallFeedback((installStatus && 'ok') || 'fail');
9999
} catch {
@@ -106,13 +106,9 @@ export const FirmwareUploaderComponent = ({
106106
if (!item) {
107107
return;
108108
}
109-
const board = isInferredBoardListItem(item)
110-
? item.inferredBoard
111-
: item.board;
112-
const selectedBoard = isInferredBoardListItem(selectedItem)
113-
? selectedItem.inferredBoard
114-
: selectedItem?.board;
109+
const board = item.board;
115110
const port = item.port;
111+
const selectedBoard = selectedItem?.board;
116112
const selectedPort = selectedItem?.port;
117113

118114
if (

arduino-ide-extension/src/common/protocol/board-list.ts

+22-9
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,12 @@ export interface BoardList {
362362
readonly selectedIndex: number;
363363

364364
/**
365-
* Contains all boards recognized from the detected port, and an optional unrecognized one that is derived from the detected port and the `initParam#selectedBoard`.
365+
* Contains all the following board+port pairs:
366+
* - one discovered board on a detected board (`1`),
367+
* - manually selected or overridden board for a detected port (`1`),
368+
* - multiple discovered boards on detected port (`1..*`)
366369
*/
367-
readonly boards: readonly (BoardListItemWithBoard | InferredBoardListItem)[];
370+
readonly boards: readonly BoardListItemWithBoard[];
368371

369372
/**
370373
* If `predicate` is not defined, no ports are filtered.
@@ -511,17 +514,27 @@ function collectPorts(
511514

512515
function collectBoards(
513516
items: readonly BoardListItem[]
514-
): readonly (BoardListItemWithBoard | InferredBoardListItem)[] {
515-
const boards: (BoardListItemWithBoard | InferredBoardListItem)[] = [];
517+
): readonly BoardListItemWithBoard[] {
518+
const result: BoardListItemWithBoard[] = [];
516519
for (let i = 0; i < items.length; i++) {
520+
const boards: BoardListItemWithBoard[] = [];
517521
const item = items[i];
518-
if (isInferredBoardListItem(item)) {
519-
boards.push(item);
520-
} else if (item.board?.fqbn) {
521-
boards.push(<Required<BoardListItem>>item);
522+
const { port } = item;
523+
const board = getInferredBoardOrBoard(item);
524+
if (board) {
525+
boards.push({ board, port });
522526
}
527+
if (isMultiBoardsBoardListItem(item)) {
528+
for (const otherBoard of item.boards) {
529+
if (!boardIdentifierEquals(board, otherBoard)) {
530+
boards.push({ board: otherBoard, port });
531+
}
532+
}
533+
}
534+
boards.sort(boardListItemComparator);
535+
result.push(...boards);
523536
}
524-
return boards;
537+
return result;
525538
}
526539

527540
function findSelectedIndex(

arduino-ide-extension/src/test/common/board-list.test.ts

+124
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,130 @@ describe('board-list', () => {
328328
expect(items[0].labels.boardLabel).to.be.equal(Unknown);
329329
});
330330

331+
describe('boards', () => {
332+
it('should include discovered boards on detected ports', () => {
333+
const { boards } = createBoardList({
334+
...detectedPort(unoSerialPort, uno),
335+
...detectedPort(mkr1000SerialPort, mkr1000),
336+
...detectedPort(undiscoveredSerialPort),
337+
});
338+
expect(boards).to.deep.equal([
339+
{
340+
port: mkr1000SerialPort,
341+
board: mkr1000,
342+
},
343+
{
344+
port: unoSerialPort,
345+
board: uno,
346+
},
347+
]);
348+
});
349+
350+
it('should include manually selected boards on detected ports', () => {
351+
const { boards } = createBoardList({
352+
...detectedPort(unoSerialPort, uno),
353+
...detectedPort(undiscoveredSerialPort, uno),
354+
...detectedPort(undiscoveredUsbToUARTSerialPort),
355+
});
356+
expect(boards).to.deep.equal([
357+
{
358+
port: unoSerialPort,
359+
board: uno,
360+
},
361+
{
362+
port: undiscoveredSerialPort,
363+
board: uno,
364+
},
365+
]);
366+
});
367+
368+
it('should include manually overridden boards on detected ports', () => {
369+
const { boards } = createBoardList(
370+
{
371+
...detectedPort(unoSerialPort, uno),
372+
...detectedPort(mkr1000SerialPort, mkr1000),
373+
},
374+
emptyBoardsConfig(),
375+
{
376+
...history(unoSerialPort, mkr1000),
377+
}
378+
);
379+
expect(boards).to.deep.equal([
380+
{
381+
port: mkr1000SerialPort,
382+
board: mkr1000,
383+
},
384+
{
385+
port: unoSerialPort,
386+
board: mkr1000,
387+
},
388+
]);
389+
});
390+
391+
it('should include all boards discovered on a port', () => {
392+
const { boards } = createBoardList({
393+
...detectedPort(
394+
nanoEsp32SerialPort,
395+
arduinoNanoEsp32,
396+
esp32NanoEsp32
397+
),
398+
...detectedPort(
399+
nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
400+
esp32S3DevModule,
401+
esp32S3Box
402+
),
403+
});
404+
expect(boards).to.deep.equal([
405+
{
406+
port: nanoEsp32SerialPort,
407+
board: arduinoNanoEsp32,
408+
},
409+
{
410+
port: nanoEsp32SerialPort,
411+
board: esp32NanoEsp32,
412+
},
413+
{
414+
port: nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
415+
board: esp32S3Box,
416+
},
417+
{
418+
port: nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
419+
board: esp32S3DevModule,
420+
},
421+
]);
422+
});
423+
424+
it('should include all boards discovered on a port (handle manual select)', () => {
425+
const { boards } = createBoardList(
426+
{
427+
...detectedPort(
428+
nanoEsp32SerialPort,
429+
arduinoNanoEsp32,
430+
esp32NanoEsp32
431+
),
432+
},
433+
emptyBoardsConfig(),
434+
{
435+
...history(nanoEsp32SerialPort, esp32S3DevModule),
436+
}
437+
);
438+
expect(boards).to.deep.equal([
439+
{
440+
port: nanoEsp32SerialPort,
441+
board: arduinoNanoEsp32,
442+
},
443+
{
444+
port: nanoEsp32SerialPort,
445+
board: esp32NanoEsp32,
446+
},
447+
{
448+
port: nanoEsp32SerialPort,
449+
board: esp32S3DevModule,
450+
},
451+
]);
452+
});
453+
});
454+
331455
describe('defaultAction', () => {
332456
it("'select' should be the default action for identifier boards", () => {
333457
const { items } = createBoardList({

0 commit comments

Comments
 (0)