-
-
Notifications
You must be signed in to change notification settings - Fork 436
/
Copy pathauto-select-programmer.ts
123 lines (117 loc) · 4 KB
/
auto-select-programmer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import type { MaybePromise } from '@theia/core/lib/common/types';
import { inject, injectable } from '@theia/core/shared/inversify';
import {
BoardDetails,
Programmer,
isBoardIdentifierChangeEvent,
} from '../../common/protocol';
import {
BoardsDataStore,
findDefaultProgrammer,
isEmptyData,
} from '../boards/boards-data-store';
import { BoardsServiceProvider } from '../boards/boards-service-provider';
import { Contribution } from './contribution';
/**
* Before CLI 0.35.0-rc.3, there was no `programmer#default` property in the `board details` response.
* This method does the programmer migration in the data store. If there is a programmer selected, it's a noop.
* If no programmer is selected, it forcefully reloads the details from the CLI and updates it in the local storage.
*/
@injectable()
export class AutoSelectProgrammer extends Contribution {
@inject(BoardsServiceProvider)
private readonly boardsServiceProvider: BoardsServiceProvider;
@inject(BoardsDataStore)
private readonly boardsDataStore: BoardsDataStore;
override onStart(): void {
this.boardsServiceProvider.onBoardsConfigDidChange((event) => {
if (isBoardIdentifierChangeEvent(event)) {
this.ensureProgrammerIsSelected();
}
});
}
override onReady(): void {
this.boardsServiceProvider.ready.then(() =>
this.ensureProgrammerIsSelected()
);
}
private async ensureProgrammerIsSelected(): Promise<boolean> {
return ensureProgrammerIsSelected({
fqbn: this.boardsServiceProvider.boardsConfig.selectedBoard?.fqbn,
getData: (fqbn) => this.boardsDataStore.getData(fqbn),
loadBoardDetails: (fqbn) => this.boardsDataStore.loadBoardDetails(fqbn),
selectProgrammer: (arg) => this.boardsDataStore.selectProgrammer(arg),
});
}
}
interface EnsureProgrammerIsSelectedParams {
fqbn: string | undefined;
getData: (fqbn: string | undefined) => MaybePromise<BoardsDataStore.Data>;
loadBoardDetails: (fqbn: string) => MaybePromise<BoardDetails | undefined>;
selectProgrammer(options: {
fqbn: string;
selectedProgrammer: Programmer;
}): MaybePromise<boolean>;
}
export async function ensureProgrammerIsSelected(
params: EnsureProgrammerIsSelectedParams
): Promise<boolean> {
const { fqbn, getData, loadBoardDetails, selectProgrammer } = params;
if (!fqbn) {
return false;
}
console.debug(`Ensuring a programmer is selected for ${fqbn}...`);
const data = await getData(fqbn);
if (isEmptyData(data)) {
// For example, the platform is not installed.
console.debug(`Skipping. No boards data is available for ${fqbn}.`);
return false;
}
if (data.selectedProgrammer) {
console.debug(
`A programmer is already selected for ${fqbn}: '${data.selectedProgrammer.id}'.`
);
return true;
}
let programmer = findDefaultProgrammer(data.programmers, data);
if (programmer) {
// select the programmer if the default info is available
const result = await selectProgrammer({
fqbn,
selectedProgrammer: programmer,
});
if (result) {
console.debug(`Selected '${programmer.id}' programmer for ${fqbn}.`);
return result;
}
}
console.debug(`Reloading board details for ${fqbn}...`);
const reloadedData = await loadBoardDetails(fqbn);
if (!reloadedData) {
console.debug(`Skipping. No board details found for ${fqbn}.`);
return false;
}
if (!reloadedData.programmers.length) {
console.debug(`Skipping. ${fqbn} does not have programmers.`);
return false;
}
programmer = findDefaultProgrammer(reloadedData.programmers, reloadedData);
if (!programmer) {
console.debug(
`Skipping. Could not find a default programmer for ${fqbn}. Programmers were: `
);
return false;
}
const result = await selectProgrammer({
fqbn,
selectedProgrammer: programmer,
});
if (result) {
console.debug(`Selected '${programmer.id}' programmer for ${fqbn}.`);
} else {
console.debug(
`Could not select '${programmer.id}' programmer for ${fqbn}.`
);
}
return result;
}