-
-
Notifications
You must be signed in to change notification settings - Fork 436
/
Copy pathboards-auto-installer.ts
121 lines (110 loc) · 4.61 KB
/
boards-auto-installer.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
import { injectable, inject } from 'inversify';
import { MessageService } from '@theia/core/lib/common/message-service';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import {
BoardsService,
BoardsPackage,
Board,
} from '../../common/protocol/boards-service';
import { BoardsServiceProvider } from './boards-service-provider';
import { BoardsListWidgetFrontendContribution } from './boards-widget-frontend-contribution';
import { BoardsConfig } from './boards-config';
import { Installable } from '../../common/protocol';
import { ResponseServiceImpl } from '../response-service-impl';
/**
* Listens on `BoardsConfig.Config` changes, if a board is selected which does not
* have the corresponding core installed, it proposes the user to install the core.
*/
@injectable()
export class BoardsAutoInstaller implements FrontendApplicationContribution {
@inject(MessageService)
protected readonly messageService: MessageService;
@inject(BoardsService)
protected readonly boardsService: BoardsService;
@inject(BoardsServiceProvider)
protected readonly boardsServiceClient: BoardsServiceProvider;
@inject(ResponseServiceImpl)
protected readonly responseService: ResponseServiceImpl;
@inject(BoardsListWidgetFrontendContribution)
protected readonly boardsManagerFrontendContribution: BoardsListWidgetFrontendContribution;
// Workaround for https://github.com/eclipse-theia/theia/issues/9349
protected notifications: Board[] = [];
onStart(): void {
this.boardsServiceClient.onBoardsConfigChanged(
this.ensureCoreExists.bind(this)
);
this.ensureCoreExists(this.boardsServiceClient.boardsConfig);
}
protected ensureCoreExists(config: BoardsConfig.Config): void {
const { selectedBoard, selectedPort } = config;
if (
selectedBoard &&
selectedPort &&
!this.notifications.find((board) => Board.sameAs(board, selectedBoard))
) {
this.notifications.push(selectedBoard);
this.boardsService.search({}).then((packages) => {
// filter packagesForBoard selecting matches from the cli (installed packages)
// and matches based on the board name
// NOTE: this ensures the Deprecated & new packages are all in the array
// so that we can check if any of the valid packages is already installed
const packagesForBoard = packages.filter(
(pkg) =>
BoardsPackage.contains(selectedBoard, pkg) ||
pkg.boards.some((board) => board.name === selectedBoard.name)
);
// check if one of the packages for the board is already installed. if so, no hint
if (
packagesForBoard.some(({ installedVersion }) => !!installedVersion)
) {
return;
}
// filter the installable (not installed) packages,
// CLI returns the packages already sorted with the deprecated ones at the end of the list
// in order to ensure the new ones are preferred
const candidates = packagesForBoard.filter(
({ installable, installedVersion }) =>
installable && !installedVersion
);
const candidate = candidates[0];
if (candidate) {
const version = candidate.availableVersions[0]
? `[v ${candidate.availableVersions[0]}]`
: '';
// tslint:disable-next-line:max-line-length
this.messageService
.info(
`The \`"${candidate.name} ${version}"\` core has to be installed for the currently selected \`"${selectedBoard.name}"\` board. Do you want to install it now?`,
'Install Manually',
'Yes'
)
.then(async (answer) => {
const index = this.notifications.findIndex((board) =>
Board.sameAs(board, selectedBoard)
);
if (index !== -1) {
this.notifications.splice(index, 1);
}
if (answer === 'Yes') {
await Installable.installWithProgress({
installable: this.boardsService,
item: candidate,
messageService: this.messageService,
responseService: this.responseService,
version: candidate.availableVersions[0],
});
return;
}
if (answer) {
this.boardsManagerFrontendContribution
.openView({ reveal: true })
.then((widget) =>
widget.refresh(candidate.name.toLocaleLowerCase())
);
}
});
}
});
}
}
}