@typecad/framework-zephyr 1.0.0-alpha.15 → 1.0.0-alpha.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -21
- package/README.md +49 -87
- package/dist/as-built.d.ts +2 -2
- package/dist/as-built.js +2 -2
- package/dist/boardgen.d.ts +1 -9
- package/dist/boardgen.js +228 -45
- package/dist/chips/types.d.ts +1 -1
- package/dist/debug-codegen.js +1 -1
- package/dist/display/touch-adapter.js +1 -1
- package/dist/display/ui-adapter.js +549 -549
- package/dist/doctor.js +4 -4
- package/dist/dt-config/custom-board.js +2 -2
- package/dist/dt-config/kconfig.js +18 -12
- package/dist/dt-config/overlay.d.ts +2 -2
- package/dist/dt-config/overlay.js +2 -2
- package/dist/framework.manifest.d.ts +3 -3
- package/dist/framework.manifest.js +10 -7
- package/dist/index.js +5 -5
- package/dist/licenses.d.ts +2 -2
- package/dist/licenses.js +8 -8
- package/dist/lowering/fs.js +1 -1
- package/dist/lowering/gpio.js +0 -32
- package/dist/lowering/http.js +264 -32
- package/dist/lowering/i2c.js +0 -8
- package/dist/lowering/interrupts.js +6 -0
- package/dist/lowering/mqtt.js +110 -8
- package/dist/lowering/usb.js +11 -11
- package/dist/lowering/wdt.js +2 -29
- package/dist/sdk/board-catalog-sync.d.ts +1 -3
- package/dist/sdk/board-catalog-sync.js +4 -10
- package/dist/strategy.d.ts +22 -44
- package/dist/strategy.js +152 -155
- package/dist/tmp-probe.d.ts +2 -0
- package/dist/tmp-probe.js +9 -0
- package/dist/toolchain/debug-config.d.ts +50 -90
- package/dist/toolchain/debug-config.js +241 -502
- package/dist/toolchain/env-check.d.ts +1 -3
- package/dist/toolchain/env-check.js +2 -7
- package/dist/toolchain/index.d.ts +65 -2
- package/dist/toolchain/index.js +432 -55
- package/dist/toolchain/runners.d.ts +16 -0
- package/dist/toolchain/runners.js +75 -0
- package/dist/toolchain/scaffold.d.ts +1 -1
- package/dist/toolchain/scaffold.js +12 -12
- package/dist/toolchain/west-discover.d.ts +6 -0
- package/dist/toolchain/west-discover.js +36 -13
- package/dist/toolchain/west-spawn.js +8 -2
- package/installer/README.md +328 -328
- package/installer/install.sh +2 -2
- package/installer/templates/project/.typecad/activate-zephyr.ps1 +1 -1
- package/installer/templates/project/.typecad/activate-zephyr.sh +1 -1
- package/installer/templates/project/.vscode/settings.json +1 -1
- package/installer/templates/project/README.md +2 -2
- package/package.json +5 -5
- package/src/as-built.ts +206 -206
- package/src/boardgen.ts +214 -48
- package/src/chips/types.ts +567 -567
- package/src/display/touch-adapter.ts +204 -204
- package/src/display/ui-adapter.ts +781 -781
- package/src/doctor.ts +4 -4
- package/src/dt-config/custom-board.ts +2 -2
- package/src/dt-config/kconfig.ts +18 -12
- package/src/dt-config/overlay.ts +1058 -1058
- package/src/framework.manifest.ts +538 -535
- package/src/index.ts +5 -5
- package/src/licenses.ts +425 -425
- package/src/lowering/fs.ts +135 -135
- package/src/lowering/gpio.ts +0 -33
- package/src/lowering/http.ts +264 -32
- package/src/lowering/i2c.ts +0 -9
- package/src/lowering/interrupts.ts +6 -0
- package/src/lowering/mqtt.ts +109 -8
- package/src/lowering/usb.ts +221 -221
- package/src/lowering/wdt.ts +2 -25
- package/src/sdk/board-catalog-sync.ts +4 -25
- package/src/strategy.ts +2265 -2309
- package/src/toolchain/debug-config.ts +264 -514
- package/src/toolchain/env-check.ts +279 -285
- package/src/toolchain/index.ts +1703 -1286
- package/src/toolchain/runners.ts +80 -0
- package/src/toolchain/scaffold.ts +296 -296
- package/src/toolchain/west-discover.ts +35 -13
- package/src/toolchain/west-spawn.ts +174 -168
- package/dist/async/timer-polyfill.d.ts +0 -10
- package/dist/async/timer-polyfill.js +0 -95
- package/dist/chips/board-overrides.d.ts +0 -7
- package/dist/chips/board-overrides.js +0 -11
- package/dist/chips/esp32.d.ts +0 -2
- package/dist/chips/esp32.js +0 -71
- package/dist/chips/esp32s3.d.ts +0 -2
- package/dist/chips/esp32s3.js +0 -103
- package/dist/chips/soc/.d.ts +0 -2
- package/dist/chips/soc/.js +0 -129
- package/dist/chips/soc/esp32.d.ts +0 -2
- package/dist/chips/soc/esp32.js +0 -120
- package/dist/chips/soc/esp32c3.d.ts +0 -2
- package/dist/chips/soc/esp32c3.js +0 -90
- package/dist/chips/soc/esp32c6.d.ts +0 -2
- package/dist/chips/soc/esp32c6.js +0 -109
- package/dist/chips/soc/esp32s3.d.ts +0 -2
- package/dist/chips/soc/esp32s3.js +0 -189
- package/dist/chips/soc/index.d.ts +0 -2
- package/dist/chips/soc/index.js +0 -23
- package/dist/chips/soc/nrf52840.d.ts +0 -2
- package/dist/chips/soc/nrf52840.js +0 -130
- package/dist/chips/soc/rp2040.d.ts +0 -2
- package/dist/chips/soc/rp2040.js +0 -141
- package/dist/chips/soc/rp2350a.d.ts +0 -2
- package/dist/chips/soc/rp2350a.js +0 -145
- package/dist/chips/soc/samd21g18a.d.ts +0 -2
- package/dist/chips/soc/samd21g18a.js +0 -143
- package/dist/chips/soc/stm32f411xe.d.ts +0 -2
- package/dist/chips/soc/stm32f411xe.js +0 -251
- package/dist/chips/xiao-ble.d.ts +0 -2
- package/dist/chips/xiao-ble.js +0 -100
- package/dist/lowering/power.d.ts +0 -9
- package/dist/lowering/power.js +0 -60
- package/dist/lowering/pulse.d.ts +0 -7
- package/dist/lowering/pulse.js +0 -51
- package/dist/lowering/tone.d.ts +0 -10
- package/dist/lowering/tone.js +0 -63
- package/dist/lowering/worker-backing.d.ts +0 -14
- package/dist/lowering/worker-backing.js +0 -79
- package/dist/lowering/worker.d.ts +0 -6
- package/dist/lowering/worker.js +0 -14
- package/dist/sdk/board-data.generated.d.ts +0 -2
- package/dist/sdk/board-data.generated.js +0 -4
- package/dist/sdk/catalog-walker.d.ts +0 -90
- package/dist/sdk/catalog-walker.js +0 -682
- package/dist/sdk/dts-reader.d.ts +0 -83
- package/dist/sdk/dts-reader.js +0 -596
- package/src/debug-codegen.ts +0 -207
|
@@ -1,285 +1,279 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// Zephyr environment check — the shared detection behind `
|
|
3
|
-
//
|
|
4
|
-
// Zephyr environment check: gather the impure
|
|
5
|
-
// environment facts once (west presence + version, Zephyr version, board
|
|
6
|
-
// existence), then reduce them to a structured result the doctor (and, later,
|
|
7
|
-
// the build/test gates) can present uniformly. The check is side-effect-free
|
|
8
|
-
// and never throws — it never installs or mutates anything.
|
|
9
|
-
//
|
|
10
|
-
// Two checks (mirroring the doctor contract):
|
|
11
|
-
// 1. west (the Zephyr build tool) is discoverable + responsive — the direct
|
|
12
|
-
// toolchain presence. discoverWest() already confirms
|
|
13
|
-
// responsiveness via `west --version`; we additionally capture the version
|
|
14
|
-
// string to report it.
|
|
15
|
-
// 2. the configured board target exists in the Zephyr checkout
|
|
16
|
-
// ($ZEPHYR_BASE/boards/) — the analog of "the required core is installed".
|
|
17
|
-
//
|
|
18
|
-
// The existing compat-range check (compat.ts) is folded in as a third check so
|
|
19
|
-
// the doctor reports everything through one entry point.
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
import { spawnSync } from 'node:child_process';
|
|
23
|
-
import { existsSync, readdirSync } from 'node:fs';
|
|
24
|
-
import { join } from 'node:path';
|
|
25
|
-
|
|
26
|
-
import { type WestInstall, discoverWest
|
|
27
|
-
import { westSpawn } from './west-spawn.js';
|
|
28
|
-
import {
|
|
29
|
-
detectZephyrVersion,
|
|
30
|
-
checkZephyrCompat,
|
|
31
|
-
resolveBoardTarget,
|
|
32
|
-
type CompatStatus,
|
|
33
|
-
} from './compat.js';
|
|
34
|
-
|
|
35
|
-
// ---- probe data (impure facts, injectable for tests) -----------------------
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Raw west facts gathered from discovery + a `west --version` probe. Mirrors
|
|
39
|
-
* probe data: `westFound` is true when a usable west install was
|
|
40
|
-
* discovered (discovery itself probes responsiveness).
|
|
41
|
-
*/
|
|
42
|
-
export interface WestProbeData {
|
|
43
|
-
/** A usable west install was discovered. */
|
|
44
|
-
westFound: boolean;
|
|
45
|
-
/** west version string if the `--version` probe parsed one, e.g. "1.3.0". */
|
|
46
|
-
westVersion: string | undefined;
|
|
47
|
-
/** Which discovery strategy found west, for surfacing to the user. */
|
|
48
|
-
source: WestInstall['source'] | undefined;
|
|
49
|
-
/** Effective ZEPHYR_BASE (env var, else a base discovery surfaced). */
|
|
50
|
-
zephyrBase: string | undefined;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Test-injection seam for checkZephyrEnv. Mirrors the
|
|
55
|
-
* fakeProbe option so tests never spawn a real west/python.
|
|
56
|
-
*/
|
|
57
|
-
export interface CheckZephyrEnvOptions {
|
|
58
|
-
/** FOR TESTS ONLY: skip the real probe and use this data directly. */
|
|
59
|
-
fakeWestProbe?: WestProbeData;
|
|
60
|
-
/** FOR TESTS ONLY: override the board-existence lookup. */
|
|
61
|
-
fakeBoardExists?: (boardId: string, zephyrBase: string | undefined) => boolean | undefined;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ---- result types ------------------------------------------------------------
|
|
65
|
-
|
|
66
|
-
export interface ZephyrEnvCheck {
|
|
67
|
-
/** west (the Zephyr build tool) was discovered and responsive. */
|
|
68
|
-
westFound: boolean;
|
|
69
|
-
/** west version string if known, e.g. "1.3.0". */
|
|
70
|
-
westVersion: string | undefined;
|
|
71
|
-
/** Discovery strategy that found west, for display. */
|
|
72
|
-
westSource: WestInstall['source'] | undefined;
|
|
73
|
-
/** Effective ZEPHYR_BASE (env var, else a discovered base). */
|
|
74
|
-
zephyrBase: string | undefined;
|
|
75
|
-
/** Detected Zephyr RTOS version from $ZEPHYR_BASE/VERSION, if readable. */
|
|
76
|
-
zephyrVersion: string | undefined;
|
|
77
|
-
/** Declared supported range (manifest.compat.zephyr), if any. */
|
|
78
|
-
compatRange: string | undefined;
|
|
79
|
-
/** Result of the compat-range check against the detected version. */
|
|
80
|
-
compatStatus: CompatStatus;
|
|
81
|
-
/** Raw board target from
|
|
82
|
-
buildTarget: string | undefined;
|
|
83
|
-
/** buildTarget normalized for the installed Zephyr version (may equal it). */
|
|
84
|
-
resolvedBoardTarget: string | undefined;
|
|
85
|
-
/** Does the resolved board exist in the checkout? undefined = undetermined. */
|
|
86
|
-
boardTargetSupported: boolean | undefined;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export type ZephyrEnvOk = { ok: true; check: ZephyrEnvCheck };
|
|
90
|
-
|
|
91
|
-
export type ZephyrEnvFailure = {
|
|
92
|
-
ok: false;
|
|
93
|
-
reason: 'west-not-found' | 'zephyr-out-of-range' | 'board-not-supported';
|
|
94
|
-
check: ZephyrEnvCheck;
|
|
95
|
-
/** Human-readable lines ready to print. */
|
|
96
|
-
messages: string[];
|
|
97
|
-
/** Exact remediation hint, when applicable. */
|
|
98
|
-
fixCommand: string | undefined;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export type ZephyrEnvResult = ZephyrEnvOk | ZephyrEnvFailure;
|
|
102
|
-
|
|
103
|
-
// ---- west probe (impure; isolated + cached + overridable) ------------------
|
|
104
|
-
|
|
105
|
-
let cachedProbe: WestProbeData | undefined;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
encoding
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
):
|
|
215
|
-
const
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
fixCommand: 'west boards',
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return { ok: true, check };
|
|
285
|
-
}
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Zephyr environment check — the shared detection behind `typecad-hal doctor`.
|
|
3
|
+
//
|
|
4
|
+
// Zephyr environment check: gather the impure
|
|
5
|
+
// environment facts once (west presence + version, Zephyr version, board
|
|
6
|
+
// existence), then reduce them to a structured result the doctor (and, later,
|
|
7
|
+
// the build/test gates) can present uniformly. The check is side-effect-free
|
|
8
|
+
// and never throws — it never installs or mutates anything.
|
|
9
|
+
//
|
|
10
|
+
// Two checks (mirroring the doctor contract):
|
|
11
|
+
// 1. west (the Zephyr build tool) is discoverable + responsive — the direct
|
|
12
|
+
// toolchain presence. discoverWest() already confirms
|
|
13
|
+
// responsiveness via `west --version`; we additionally capture the version
|
|
14
|
+
// string to report it.
|
|
15
|
+
// 2. the configured board target exists in the Zephyr checkout
|
|
16
|
+
// ($ZEPHYR_BASE/boards/) — the analog of "the required core is installed".
|
|
17
|
+
//
|
|
18
|
+
// The existing compat-range check (compat.ts) is folded in as a third check so
|
|
19
|
+
// the doctor reports everything through one entry point.
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
import { spawnSync } from 'node:child_process';
|
|
23
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
24
|
+
import { join } from 'node:path';
|
|
25
|
+
|
|
26
|
+
import { type WestInstall, discoverWest } from './west-discover.js';
|
|
27
|
+
import { westSpawn } from './west-spawn.js';
|
|
28
|
+
import {
|
|
29
|
+
detectZephyrVersion,
|
|
30
|
+
checkZephyrCompat,
|
|
31
|
+
resolveBoardTarget,
|
|
32
|
+
type CompatStatus,
|
|
33
|
+
} from './compat.js';
|
|
34
|
+
|
|
35
|
+
// ---- probe data (impure facts, injectable for tests) -----------------------
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Raw west facts gathered from discovery + a `west --version` probe. Mirrors
|
|
39
|
+
* probe data: `westFound` is true when a usable west install was
|
|
40
|
+
* discovered (discovery itself probes responsiveness).
|
|
41
|
+
*/
|
|
42
|
+
export interface WestProbeData {
|
|
43
|
+
/** A usable west install was discovered. */
|
|
44
|
+
westFound: boolean;
|
|
45
|
+
/** west version string if the `--version` probe parsed one, e.g. "1.3.0". */
|
|
46
|
+
westVersion: string | undefined;
|
|
47
|
+
/** Which discovery strategy found west, for surfacing to the user. */
|
|
48
|
+
source: WestInstall['source'] | undefined;
|
|
49
|
+
/** Effective ZEPHYR_BASE (env var, else a base discovery surfaced). */
|
|
50
|
+
zephyrBase: string | undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Test-injection seam for checkZephyrEnv. Mirrors the
|
|
55
|
+
* fakeProbe option so tests never spawn a real west/python.
|
|
56
|
+
*/
|
|
57
|
+
export interface CheckZephyrEnvOptions {
|
|
58
|
+
/** FOR TESTS ONLY: skip the real probe and use this data directly. */
|
|
59
|
+
fakeWestProbe?: WestProbeData;
|
|
60
|
+
/** FOR TESTS ONLY: override the board-existence lookup. */
|
|
61
|
+
fakeBoardExists?: (boardId: string, zephyrBase: string | undefined) => boolean | undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ---- result types ------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
export interface ZephyrEnvCheck {
|
|
67
|
+
/** west (the Zephyr build tool) was discovered and responsive. */
|
|
68
|
+
westFound: boolean;
|
|
69
|
+
/** west version string if known, e.g. "1.3.0". */
|
|
70
|
+
westVersion: string | undefined;
|
|
71
|
+
/** Discovery strategy that found west, for display. */
|
|
72
|
+
westSource: WestInstall['source'] | undefined;
|
|
73
|
+
/** Effective ZEPHYR_BASE (env var, else a discovered base). */
|
|
74
|
+
zephyrBase: string | undefined;
|
|
75
|
+
/** Detected Zephyr RTOS version from $ZEPHYR_BASE/VERSION, if readable. */
|
|
76
|
+
zephyrVersion: string | undefined;
|
|
77
|
+
/** Declared supported range (manifest.compat.zephyr), if any. */
|
|
78
|
+
compatRange: string | undefined;
|
|
79
|
+
/** Result of the compat-range check against the detected version. */
|
|
80
|
+
compatStatus: CompatStatus;
|
|
81
|
+
/** Raw board target from typecad-hal.config.ts, if configured. */
|
|
82
|
+
buildTarget: string | undefined;
|
|
83
|
+
/** buildTarget normalized for the installed Zephyr version (may equal it). */
|
|
84
|
+
resolvedBoardTarget: string | undefined;
|
|
85
|
+
/** Does the resolved board exist in the checkout? undefined = undetermined. */
|
|
86
|
+
boardTargetSupported: boolean | undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type ZephyrEnvOk = { ok: true; check: ZephyrEnvCheck };
|
|
90
|
+
|
|
91
|
+
export type ZephyrEnvFailure = {
|
|
92
|
+
ok: false;
|
|
93
|
+
reason: 'west-not-found' | 'zephyr-out-of-range' | 'board-not-supported';
|
|
94
|
+
check: ZephyrEnvCheck;
|
|
95
|
+
/** Human-readable lines ready to print. */
|
|
96
|
+
messages: string[];
|
|
97
|
+
/** Exact remediation hint, when applicable. */
|
|
98
|
+
fixCommand: string | undefined;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export type ZephyrEnvResult = ZephyrEnvOk | ZephyrEnvFailure;
|
|
102
|
+
|
|
103
|
+
// ---- west probe (impure; isolated + cached + overridable) ------------------
|
|
104
|
+
|
|
105
|
+
let cachedProbe: WestProbeData | undefined;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Gather west facts: discover a usable install, then run `west --version`
|
|
109
|
+
* through it to capture the version. Memoized for the process lifetime (west
|
|
110
|
+
* installs don't move). Never throws — returns westFound:false on any failure.
|
|
111
|
+
*/
|
|
112
|
+
export function probeWestEnv(): WestProbeData {
|
|
113
|
+
if (cachedProbe) return cachedProbe;
|
|
114
|
+
|
|
115
|
+
const install = discoverWest();
|
|
116
|
+
const envBase = process.env.ZEPHYR_BASE || undefined;
|
|
117
|
+
if (!install) {
|
|
118
|
+
const data: WestProbeData = {
|
|
119
|
+
westFound: false,
|
|
120
|
+
westVersion: undefined,
|
|
121
|
+
source: undefined,
|
|
122
|
+
zephyrBase: envBase,
|
|
123
|
+
};
|
|
124
|
+
cachedProbe = data;
|
|
125
|
+
return data;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Run `west --version` through the discovered install to capture the version.
|
|
129
|
+
// discoverWest() already confirmed responsiveness, so a parse failure here is
|
|
130
|
+
// not "unresponsive" — it just means we couldn't read a version token.
|
|
131
|
+
let westVersion: string | undefined;
|
|
132
|
+
try {
|
|
133
|
+
const inv = westSpawn(['--version'], {
|
|
134
|
+
encoding: 'utf8',
|
|
135
|
+
timeout: 15_000,
|
|
136
|
+
windowsHide: true,
|
|
137
|
+
});
|
|
138
|
+
const r = spawnSync(inv.command, inv.args, inv.options);
|
|
139
|
+
if (r.status === 0) {
|
|
140
|
+
// inv.options is a generic SpawnSyncOptions (no encoding literal), so
|
|
141
|
+
// coerce stdout to a string before matching.
|
|
142
|
+
const out = typeof r.stdout === 'string' ? r.stdout : '';
|
|
143
|
+
const m = out.match(/v?(\d+\.\d+\.\d+)/);
|
|
144
|
+
westVersion = m ? m[1] : undefined;
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
// westSpawn throws only when discovery fails — but discovery already
|
|
148
|
+
// succeeded (install is non-null). Defensive: treat as no version read.
|
|
149
|
+
westVersion = undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const data: WestProbeData = {
|
|
153
|
+
westFound: true,
|
|
154
|
+
westVersion,
|
|
155
|
+
source: install.source,
|
|
156
|
+
zephyrBase: envBase ?? install.zephyrBase,
|
|
157
|
+
};
|
|
158
|
+
cachedProbe = data;
|
|
159
|
+
return data;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ---- board existence (pure-ish fs probe) -----------------------------------
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Does `boardId` exist as a board directory in the Zephyr checkout? Checks the
|
|
166
|
+
* HWMv2 vendor layout used by Zephyr 4.x: $ZEPHYR_BASE/boards/<vendor>/<boardId>.
|
|
167
|
+
* Returns true/false when determinable; undefined when the base is unknown or
|
|
168
|
+
* the boards/ tree can't be read (so callers never fail on an inconclusive
|
|
169
|
+
* lookup — they just skip the board check).
|
|
170
|
+
*/
|
|
171
|
+
export function boardExistsInCheckout(
|
|
172
|
+
boardId: string,
|
|
173
|
+
zephyrBase: string | undefined,
|
|
174
|
+
): boolean | undefined {
|
|
175
|
+
if (!zephyrBase) return undefined;
|
|
176
|
+
const boards = join(zephyrBase, 'boards');
|
|
177
|
+
try {
|
|
178
|
+
const entries = readdirSync(boards, { withFileTypes: true });
|
|
179
|
+
for (const entry of entries) {
|
|
180
|
+
if (entry.isDirectory() && existsSync(join(boards, entry.name, boardId))) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return false;
|
|
185
|
+
} catch {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ---- main entry point -------------------------------------------------------
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Verify the environment can build for `buildTarget`. Cheap and
|
|
194
|
+
* side-effect-free: discovers west, reads the Zephyr version, checks the compat
|
|
195
|
+
* range, and — when a target is configured — verifies the board exists in the
|
|
196
|
+
* checkout. Reports what (if anything) is wrong.
|
|
197
|
+
*
|
|
198
|
+
* - If `buildTarget` is undefined/empty, the board check is skipped (not a
|
|
199
|
+
* failure), mirroring the no-build-target path.
|
|
200
|
+
* - Never installs anything. Never mutates the user environment.
|
|
201
|
+
* - Never throws — always returns a result. Callers decide how to react.
|
|
202
|
+
*
|
|
203
|
+
* `options` is for-test only (injects fake probe data / board lookup).
|
|
204
|
+
*/
|
|
205
|
+
export function checkZephyrEnv(
|
|
206
|
+
buildTarget?: string,
|
|
207
|
+
options?: CheckZephyrEnvOptions,
|
|
208
|
+
): ZephyrEnvResult {
|
|
209
|
+
const probe = options?.fakeWestProbe ?? probeWestEnv();
|
|
210
|
+
const boardLookup = options?.fakeBoardExists ?? boardExistsInCheckout;
|
|
211
|
+
|
|
212
|
+
const zephyrVersion = detectZephyrVersion();
|
|
213
|
+
const compat = checkZephyrCompat(zephyrVersion);
|
|
214
|
+
const resolvedBoardTarget = buildTarget ? resolveBoardTarget(buildTarget, zephyrVersion) : undefined;
|
|
215
|
+
const boardId = resolvedBoardTarget ? resolvedBoardTarget.split('/')[0]! : undefined;
|
|
216
|
+
const boardTargetSupported =
|
|
217
|
+
boardId !== undefined ? boardLookup(boardId, probe.zephyrBase) : undefined;
|
|
218
|
+
|
|
219
|
+
const check: ZephyrEnvCheck = {
|
|
220
|
+
westFound: probe.westFound,
|
|
221
|
+
westVersion: probe.westVersion,
|
|
222
|
+
westSource: probe.source,
|
|
223
|
+
zephyrBase: probe.zephyrBase,
|
|
224
|
+
zephyrVersion,
|
|
225
|
+
compatRange: compat.range,
|
|
226
|
+
compatStatus: compat.status,
|
|
227
|
+
buildTarget,
|
|
228
|
+
resolvedBoardTarget,
|
|
229
|
+
boardTargetSupported,
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// 1. west (the build tool) missing entirely — nothing else can run.
|
|
233
|
+
if (!probe.westFound) {
|
|
234
|
+
return {
|
|
235
|
+
ok: false,
|
|
236
|
+
reason: 'west-not-found',
|
|
237
|
+
check,
|
|
238
|
+
messages: [
|
|
239
|
+
"west (the Zephyr build tool) was not found.",
|
|
240
|
+
" Run the typeCAD Zephyr installer, activate an existing Zephyr venv,",
|
|
241
|
+
" set ZEPHYR_BASE to a Zephyr SDK root, or `pip install west`.",
|
|
242
|
+
],
|
|
243
|
+
fixCommand: undefined,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// 2. west healthy but the Zephyr RTOS is outside the supported range.
|
|
248
|
+
if (compat.status === 'out-of-range') {
|
|
249
|
+
return {
|
|
250
|
+
ok: false,
|
|
251
|
+
reason: 'zephyr-out-of-range',
|
|
252
|
+
check,
|
|
253
|
+
messages: [
|
|
254
|
+
`Zephyr ${zephyrVersion} is outside the supported range (${compat.range}) for @typecad/framework-zephyr.`,
|
|
255
|
+
" Set ZEPHYR_BASE to a compatible Zephyr checkout, or or run the bundled Zephyr installer (npx --package @typecad/framework-zephyr zephyr-installer).",
|
|
256
|
+
],
|
|
257
|
+
fixCommand: undefined,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// 3. west + version OK — only check the board when a target is configured and
|
|
262
|
+
// the lookup was able to answer. A missing/absent target is not a board
|
|
263
|
+
// problem; an inconclusive lookup (no base) is reported as a skip, not a fail.
|
|
264
|
+
if (buildTarget && boardTargetSupported === false) {
|
|
265
|
+
return {
|
|
266
|
+
ok: false,
|
|
267
|
+
reason: 'board-not-supported',
|
|
268
|
+
check,
|
|
269
|
+
messages: [
|
|
270
|
+
`Board target '${resolvedBoardTarget}' was not found in this Zephyr checkout` +
|
|
271
|
+
(probe.zephyrBase ? ` (${join(probe.zephyrBase, 'boards')}).` : '.'),
|
|
272
|
+
" Check the board id, or run `west boards` to list boards in this checkout.",
|
|
273
|
+
],
|
|
274
|
+
fixCommand: 'west boards',
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return { ok: true, check };
|
|
279
|
+
}
|