Skip to content

Commit 22997db

Browse files
committed
Add support for updating system zephyr version
Signed-off-by: paulober <[email protected]>
1 parent 4e15847 commit 22997db

File tree

12 files changed

+467
-137
lines changed

12 files changed

+467
-137
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"--extensionDevelopmentPath=${workspaceFolder}"
1414
],
1515
"outFiles": [
16-
"${workspaceFolder}/dist/**/*.js"
16+
"${workspaceFolder}/dist/extension.js"
1717
],
1818
"preLaunchTask": "${defaultBuildTask}"
1919
}

src/commands/getPaths.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ export class GetZephyrSDKPathCommand extends CommandWithResult<
631631
try {
632632
await workspace.fs.stat(workspaceUri);
633633
const contents = await workspace.fs.readDirectory(workspaceUri);
634+
// TODO: get zephr version form west manifest and sdk_version from zephyr directory
634635
const sdksDirectories = contents
635636
.filter(
636637
entry =>

src/commands/switchSDK.mts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import {
55
window,
66
workspace,
77
commands,
8+
type WorkspaceFolder,
89
} from "vscode";
910
import type UI from "../ui.mjs";
1011
import { updateVSCodeStaticConfigs } from "../utils/vscodeConfigUtil.mjs";
1112
import {
1213
getCmakeReleases,
1314
getNinjaReleases,
1415
getSDKReleases,
16+
getZephyrReleases,
1517
} from "../utils/githubREST.mjs";
1618
import {
1719
downloadAndInstallCmake,
@@ -39,6 +41,9 @@ import Logger from "../logger.mjs";
3941
import type { Progress as GotProgress } from "got";
4042
import { SWITCH_SDK } from "./cmdIds.mjs";
4143
import { SDK_REPOSITORY_URL } from "../utils/sharedConstants.mjs";
44+
import State from "../state.mjs";
45+
import { compare, compareGe } from "../utils/semverUtil.mjs";
46+
import { updateZephyrVersion } from "../utils/setupZephyr.mjs";
4247

4348
const DEFAULT_PICOTOOL_VERSION = "2.2.0-a4";
4449

@@ -392,6 +397,60 @@ export default class SwitchSDKCommand extends Command {
392397
};
393398
}
394399

400+
private async switchZephyr(): Promise<void> {
401+
const releases = await getZephyrReleases();
402+
if (releases.length === 0) {
403+
void window.showErrorMessage(
404+
"Failed to get Zephyr releases. " +
405+
"Make sure you are connected to the internet."
406+
);
407+
408+
return;
409+
}
410+
411+
// sort releases and filter out anything older than v4.2.0
412+
const core = (v: string): string => v.replace(/^v/, "").split("-")[0];
413+
const filtered = releases.filter(v => compareGe(core(v), "4.2.0"));
414+
415+
// sort DESC newest first
416+
const sorted = filtered.sort((a, b) => {
417+
const byCore = compare(core(b), core(a)); // flip for descending
418+
if (byCore !== 0) {
419+
return byCore;
420+
}
421+
const aPre = a.includes("-");
422+
const bPre = b.includes("-");
423+
if (aPre !== bPre) {
424+
return aPre ? 1 : -1;
425+
} // stable before prerelease
426+
427+
return 0;
428+
});
429+
430+
const selectedVersion = await window.showQuickPick(
431+
[{ label: "main" }, ...sorted.map(v => ({ label: v }))],
432+
{
433+
placeHolder: "Select Zephyr version",
434+
}
435+
);
436+
437+
if (selectedVersion === undefined) {
438+
return;
439+
}
440+
441+
const result = await updateZephyrVersion(selectedVersion.label);
442+
if (result) {
443+
this._ui.updateSDKVersion(selectedVersion.label.replace("v", ""));
444+
// for reload the window
445+
void commands.executeCommand("workbench.action.reloadWindow");
446+
} else {
447+
void window.showErrorMessage(
448+
`Failed to switch to Zephyr version ${selectedVersion.label}. ` +
449+
"Make sure all requirements are met."
450+
);
451+
}
452+
}
453+
395454
async execute(): Promise<void> {
396455
if (
397456
workspace.workspaceFolders === undefined ||
@@ -404,6 +463,11 @@ export default class SwitchSDKCommand extends Command {
404463

405464
const workspaceFolder = workspace.workspaceFolders[0];
406465

466+
const isZephyrProject = State.getInstance().isZephyrProject;
467+
if (isZephyrProject) {
468+
return this.switchZephyr();
469+
}
470+
407471
const selectedSDK = await SwitchSDKCommand.askSDKVersion(
408472
this._versionBundlesLoader
409473
);

src/extension.mts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ import VersionBundlesLoader from "./utils/versionBundles.mjs";
109109
import { unknownErrorToString } from "./utils/errorHelper.mjs";
110110
import {
111111
getBoardFromZephyrProject,
112+
getZephyrVersion,
112113
setupZephyr,
114+
updateZephyrCompilerPath,
113115
} from "./utils/setupZephyr.mjs";
114116
import { IMPORT_PROJECT } from "./commands/cmdIds.mjs";
115117
import {
@@ -438,6 +440,27 @@ export async function activate(context: ExtensionContext): Promise<void> {
438440
State.getInstance().isZephyrProject = true;
439441

440442
ui.showStatusBarItems(false, true);
443+
const selectedZephyrVersion = await getZephyrVersion();
444+
if (selectedZephyrVersion === undefined) {
445+
Logger.error(
446+
LoggerSource.extension,
447+
"Failed to get selected system Zephyr version. Defaulting to main."
448+
);
449+
}
450+
ui.updateSDKVersion(selectedZephyrVersion ?? "main");
451+
452+
const cppCompilerUpdated = await updateZephyrCompilerPath(
453+
workspaceFolder.uri,
454+
selectedZephyrVersion ?? "main"
455+
);
456+
457+
if (!cppCompilerUpdated) {
458+
void window.showErrorMessage(
459+
"Failed to update C++ compiler path in c_cpp_properties.json"
460+
);
461+
462+
// TODO: maybe cancel activation
463+
}
441464

442465
// Update the board info if it can be found in tasks.json
443466
const tasksJsonFilePath = join(

src/ui.mts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ const STATUS_BAR_ITEMS: {
2121
[key: string]: {
2222
text: string;
2323
rustText?: string;
24+
zephyrText?: string;
2425
command: string;
2526
tooltip: string;
27+
zephyrTooltip?: string;
2628
rustSupport: boolean;
2729
zephyrSupport: boolean;
2830
};
@@ -45,15 +47,16 @@ const STATUS_BAR_ITEMS: {
4547
},
4648
[StatusBarItemKey.picoSDKQuickPick]: {
4749
text: "Pico SDK: <version>",
50+
zephyrText: "Zephyr version: <version>",
4851
command: `${extensionName}.${SWITCH_SDK}`,
4952
tooltip: "Select Pico SDK",
53+
zephyrTooltip: "Select system wide installed zephyr version",
5054
rustSupport: false,
51-
zephyrSupport: false,
55+
zephyrSupport: true,
5256
},
5357
[StatusBarItemKey.picoBoardQuickPick]: {
5458
text: "Board: <board>",
5559
rustText: "Chip: <chip>",
56-
// TODO: zephyrCommand option to zwphyr switch borad command or merge them that better
5760
command: `${extensionName}.${SWITCH_BOARD}`,
5861
tooltip: "Select Chip",
5962
rustSupport: true,
@@ -91,13 +94,32 @@ export default class UI {
9194
.filter(
9295
item => !isZephyrProject || STATUS_BAR_ITEMS[item.id].zephyrSupport
9396
)
94-
.forEach(item => item.show());
97+
.forEach(item => {
98+
if (isZephyrProject) {
99+
if (STATUS_BAR_ITEMS[item.id].zephyrText) {
100+
item.text = STATUS_BAR_ITEMS[item.id].zephyrText!;
101+
}
102+
if (STATUS_BAR_ITEMS[item.id].zephyrTooltip) {
103+
item.tooltip = STATUS_BAR_ITEMS[item.id].zephyrTooltip;
104+
}
105+
}
106+
item.show();
107+
});
95108
}
96109

97110
public updateSDKVersion(version: string): void {
98-
this._items[StatusBarItemKey.picoSDKQuickPick].text = STATUS_BAR_ITEMS[
99-
StatusBarItemKey.picoSDKQuickPick
100-
].text.replace("<version>", version);
111+
const isZephyrProject = State.getInstance().isZephyrProject;
112+
let template = STATUS_BAR_ITEMS[StatusBarItemKey.picoSDKQuickPick].text;
113+
114+
if (isZephyrProject) {
115+
template =
116+
STATUS_BAR_ITEMS[StatusBarItemKey.picoSDKQuickPick].zephyrText!;
117+
}
118+
119+
this._items[StatusBarItemKey.picoSDKQuickPick].text = template.replace(
120+
"<version>",
121+
version
122+
);
101123
this._activityBarProvider.refreshSDK(version);
102124
}
103125

src/utils/cmakeToolsUtil.mts

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { commands, extensions, window, ProgressLocation } from "vscode";
22
import Logger, { LoggerSource } from "../logger.mjs";
33

4-
54
export async function cmakeToolsForcePicoKit(): Promise<void> {
65
// Check if the CMake Tools extension is installed and active
76
let foundCmakeToolsExtension = false;
87
for (let i = 0; i < 2; i++) {
9-
const cmakeToolsExtension =
10-
extensions.getExtension("ms-vscode.cmake-tools");
8+
const cmakeToolsExtension = extensions.getExtension(
9+
"ms-vscode.cmake-tools"
10+
);
1111
if (cmakeToolsExtension !== undefined) {
1212
Logger.debug(
1313
LoggerSource.cmake,
@@ -21,11 +21,11 @@ export async function cmakeToolsForcePicoKit(): Promise<void> {
2121

2222
// Attempt to activate the extension
2323
const onActivate = cmakeToolsExtension.activate();
24-
const onTimeout = new Promise<string>((resolve) => {
24+
const onTimeout = new Promise<string>(resolve => {
2525
setTimeout(resolve, 2000, "timeout");
2626
});
2727

28-
await Promise.race([onActivate, onTimeout]).then((value) => {
28+
await Promise.race([onActivate, onTimeout]).then(value => {
2929
if (value === "timeout") {
3030
Logger.warn(
3131
LoggerSource.cmake,
@@ -38,65 +38,58 @@ export async function cmakeToolsForcePicoKit(): Promise<void> {
3838
});
3939
} else {
4040
// Undefined if not installed/disabled
41-
Logger.debug(
42-
LoggerSource.cmake,
43-
`cmakeToolsExtension: undefined`
44-
);
41+
Logger.debug(LoggerSource.cmake, `cmakeToolsExtension: undefined`);
4542
break;
4643
}
4744
await new Promise(resolve => setTimeout(resolve, 1000));
4845
}
4946

5047
if (!foundCmakeToolsExtension) {
5148
// Give up and return, as this function is non-essential
52-
Logger.warn(
53-
LoggerSource.cmake,
54-
"cmakeToolsExtension not available yet"
55-
);
49+
Logger.warn(LoggerSource.cmake, "cmakeToolsExtension not available yet");
5650

5751
return;
5852
}
5953

60-
let cmakeToolsKit = await commands.executeCommand(
61-
"cmake.buildKit"
62-
);
54+
let cmakeToolsKit = await commands.executeCommand("cmake.buildKit");
6355
if (cmakeToolsKit === "Pico") {
6456
return;
6557
}
6658

67-
await window.withProgress({
68-
location: ProgressLocation.Notification,
69-
title: "Select the Pico kit in the dialog at the top of the window",
70-
cancellable: false,
71-
}, async progress => {
72-
let i = 0;
73-
while (cmakeToolsKit !== "Pico") {
74-
if (i >= 2) {
75-
const result = await window.showErrorMessage(
76-
"You did not select the Pico kit - " +
77-
"you must select the Pico kit in the dialog, " +
78-
"else this extension will not work",
79-
"Try again",
80-
"Cancel"
81-
);
59+
await window.withProgress(
60+
{
61+
location: ProgressLocation.Notification,
62+
title: "Select the Pico kit in the dialog at the top of the window",
63+
cancellable: false,
64+
},
65+
async progress => {
66+
let i = 0;
67+
while (cmakeToolsKit !== "Pico") {
68+
if (i >= 2) {
69+
const result = await window.showErrorMessage(
70+
"You did not select the Pico kit - " +
71+
"you must select the Pico kit in the dialog, " +
72+
"else this extension will not work",
73+
"Try again",
74+
"Cancel"
75+
);
8276

83-
if (result === "Try again") {
84-
i = 0;
85-
continue;
86-
}
77+
if (result === "Try again") {
78+
i = 0;
79+
continue;
80+
}
8781

88-
progress.report({increment: 100});
82+
progress.report({ increment: 100 });
8983

90-
return;
84+
return;
85+
}
86+
await commands.executeCommand("cmake.selectKit");
87+
cmakeToolsKit = await commands.executeCommand("cmake.buildKit");
88+
i++;
9189
}
92-
await commands.executeCommand("cmake.selectKit");
93-
cmakeToolsKit = await commands.executeCommand(
94-
"cmake.buildKit"
95-
);
96-
i++;
97-
}
98-
progress.report({increment: 100});
90+
progress.report({ increment: 100 });
9991

100-
return;
101-
});
92+
return;
93+
}
94+
);
10295
}

src/utils/githubREST.mts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ async function getReleases(repository: GithubRepository): Promise<string[]> {
239239
}
240240
}
241241

242+
export async function getZephyrReleases(): Promise<string[]> {
243+
return getReleases(GithubRepository.zephyr);
244+
}
245+
242246
export async function getSDKReleases(): Promise<string[]> {
243247
return getReleases(GithubRepository.picoSDK);
244248
}

0 commit comments

Comments
 (0)