@nordicsemiconductor/pc-nrfconnect-shared 212.0.0 → 214.0.0

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.
Files changed (101) hide show
  1. package/Changelog.md +27 -0
  2. package/nrfutil/collectingResultParser.ts +82 -0
  3. package/nrfutil/common.ts +41 -0
  4. package/nrfutil/device/batch.ts +25 -62
  5. package/nrfutil/device/batchTypes.ts +8 -46
  6. package/nrfutil/device/boardController.ts +2 -2
  7. package/nrfutil/device/common.ts +6 -10
  8. package/nrfutil/device/deviceInfo.ts +4 -3
  9. package/nrfutil/device/erase.ts +4 -3
  10. package/nrfutil/device/getBoardControllerConfig.ts +2 -2
  11. package/nrfutil/device/getBoardControllerVersion.ts +2 -2
  12. package/nrfutil/device/getCoreInfo.ts +4 -3
  13. package/nrfutil/device/getFwInfo.ts +4 -3
  14. package/nrfutil/device/getProtectionStatus.ts +4 -3
  15. package/nrfutil/device/list.ts +5 -10
  16. package/nrfutil/device/logLibVersions.ts +8 -69
  17. package/nrfutil/device/program.ts +60 -66
  18. package/nrfutil/device/recover.ts +4 -3
  19. package/nrfutil/device/reset.ts +7 -13
  20. package/nrfutil/device/setMcuState.ts +2 -2
  21. package/nrfutil/device/setProtectionStatus.ts +4 -3
  22. package/nrfutil/device/xRead.ts +26 -28
  23. package/nrfutil/index.ts +2 -3
  24. package/nrfutil/modules.ts +10 -15
  25. package/nrfutil/sandbox.ts +162 -327
  26. package/nrfutil/sandboxTypes.ts +4 -43
  27. package/nrfutil/{jlinkVersion.test.ts → version/jlinkVersion.test.ts} +1 -1
  28. package/nrfutil/{jlinkVersion.ts → version/jlinkVersion.ts} +2 -2
  29. package/nrfutil/{moduleVersion.ts → version/moduleVersion.ts} +44 -7
  30. package/package.json +1 -1
  31. package/scripts/nordic-publish.js +4 -2
  32. package/scripts/nordic-publish.ts +44 -7
  33. package/src/logging/index.ts +2 -10
  34. package/src/utils/systemReport.ts +4 -1
  35. package/typings/generated/nrfutil/collectingResultParser.d.ts +19 -0
  36. package/typings/generated/nrfutil/collectingResultParser.d.ts.map +1 -0
  37. package/typings/generated/nrfutil/common.d.ts +6 -0
  38. package/typings/generated/nrfutil/common.d.ts.map +1 -0
  39. package/typings/generated/nrfutil/device/__mocks__/device.d.ts +1 -1
  40. package/typings/generated/nrfutil/device/batch.d.ts +6 -4
  41. package/typings/generated/nrfutil/device/batch.d.ts.map +1 -1
  42. package/typings/generated/nrfutil/device/batchTypes.d.ts +8 -30
  43. package/typings/generated/nrfutil/device/batchTypes.d.ts.map +1 -1
  44. package/typings/generated/nrfutil/device/boardController.d.ts +2 -2
  45. package/typings/generated/nrfutil/device/boardController.d.ts.map +1 -1
  46. package/typings/generated/nrfutil/device/common.d.ts +4 -3
  47. package/typings/generated/nrfutil/device/common.d.ts.map +1 -1
  48. package/typings/generated/nrfutil/device/device.d.ts +14 -14
  49. package/typings/generated/nrfutil/device/deviceInfo.d.ts +2 -2
  50. package/typings/generated/nrfutil/device/deviceInfo.d.ts.map +1 -1
  51. package/typings/generated/nrfutil/device/erase.d.ts +2 -2
  52. package/typings/generated/nrfutil/device/erase.d.ts.map +1 -1
  53. package/typings/generated/nrfutil/device/getBoardControllerConfig.d.ts +2 -2
  54. package/typings/generated/nrfutil/device/getBoardControllerConfig.d.ts.map +1 -1
  55. package/typings/generated/nrfutil/device/getBoardControllerVersion.d.ts +2 -2
  56. package/typings/generated/nrfutil/device/getBoardControllerVersion.d.ts.map +1 -1
  57. package/typings/generated/nrfutil/device/getCoreInfo.d.ts +2 -2
  58. package/typings/generated/nrfutil/device/getCoreInfo.d.ts.map +1 -1
  59. package/typings/generated/nrfutil/device/getFwInfo.d.ts +2 -2
  60. package/typings/generated/nrfutil/device/getFwInfo.d.ts.map +1 -1
  61. package/typings/generated/nrfutil/device/getProtectionStatus.d.ts +2 -2
  62. package/typings/generated/nrfutil/device/getProtectionStatus.d.ts.map +1 -1
  63. package/typings/generated/nrfutil/device/list.d.ts.map +1 -1
  64. package/typings/generated/nrfutil/device/logLibVersions.d.ts +2 -2
  65. package/typings/generated/nrfutil/device/logLibVersions.d.ts.map +1 -1
  66. package/typings/generated/nrfutil/device/program.d.ts +13 -13
  67. package/typings/generated/nrfutil/device/program.d.ts.map +1 -1
  68. package/typings/generated/nrfutil/device/recover.d.ts +2 -2
  69. package/typings/generated/nrfutil/device/recover.d.ts.map +1 -1
  70. package/typings/generated/nrfutil/device/reset.d.ts +2 -2
  71. package/typings/generated/nrfutil/device/reset.d.ts.map +1 -1
  72. package/typings/generated/nrfutil/device/setMcuState.d.ts +2 -2
  73. package/typings/generated/nrfutil/device/setMcuState.d.ts.map +1 -1
  74. package/typings/generated/nrfutil/device/setProtectionStatus.d.ts +2 -2
  75. package/typings/generated/nrfutil/device/setProtectionStatus.d.ts.map +1 -1
  76. package/typings/generated/nrfutil/device/xRead.d.ts +9 -2
  77. package/typings/generated/nrfutil/device/xRead.d.ts.map +1 -1
  78. package/typings/generated/nrfutil/index.d.ts +2 -3
  79. package/typings/generated/nrfutil/index.d.ts.map +1 -1
  80. package/typings/generated/nrfutil/modules.d.ts +1 -1
  81. package/typings/generated/nrfutil/modules.d.ts.map +1 -1
  82. package/typings/generated/nrfutil/sandbox.d.ts +27 -35
  83. package/typings/generated/nrfutil/sandbox.d.ts.map +1 -1
  84. package/typings/generated/nrfutil/sandboxTypes.d.ts +4 -29
  85. package/typings/generated/nrfutil/sandboxTypes.d.ts.map +1 -1
  86. package/typings/generated/nrfutil/{jlinkVersion.d.ts → version/jlinkVersion.d.ts} +1 -1
  87. package/typings/generated/nrfutil/version/jlinkVersion.d.ts.map +1 -0
  88. package/typings/generated/nrfutil/version/jlinkVersion.test.d.ts.map +1 -0
  89. package/typings/generated/nrfutil/version/moduleVersion.d.ts +40 -0
  90. package/typings/generated/nrfutil/version/moduleVersion.d.ts.map +1 -0
  91. package/typings/generated/nrfutil/version/version.d.ts.map +1 -0
  92. package/typings/generated/src/logging/index.d.ts.map +1 -1
  93. package/typings/generated/src/utils/systemReport.d.ts.map +1 -1
  94. package/typings/generated/nrfutil/jlinkVersion.d.ts.map +0 -1
  95. package/typings/generated/nrfutil/jlinkVersion.test.d.ts.map +0 -1
  96. package/typings/generated/nrfutil/moduleVersion.d.ts +0 -12
  97. package/typings/generated/nrfutil/moduleVersion.d.ts.map +0 -1
  98. package/typings/generated/nrfutil/version.d.ts.map +0 -1
  99. /package/nrfutil/{version.ts → version/version.ts} +0 -0
  100. /package/typings/generated/nrfutil/{jlinkVersion.test.d.ts → version/jlinkVersion.test.d.ts} +0 -0
  101. /package/typings/generated/nrfutil/{version.d.ts → version/version.d.ts} +0 -0
@@ -13,161 +13,107 @@ import treeKill from 'tree-kill';
13
13
  import describeError from '../src/logging/describeError';
14
14
  import telemetry from '../src/telemetry/telemetry';
15
15
  import { isDevelopment } from '../src/utils/environment';
16
- import { coreVersionsToInstall, versionToInstall } from './moduleVersion';
17
- import { getNrfutilLogger } from './nrfutilLogger';
16
+ import CollectingResultParser from './collectingResultParser';
18
17
  import {
18
+ collectErrorMessages,
19
+ convertNrfutilProgress,
20
+ parseJsonBuffers,
21
+ } from './common';
22
+ import { getNrfutilLogger } from './nrfutilLogger';
23
+ import type {
19
24
  BackgroundTask,
20
25
  LogLevel,
21
26
  LogMessage,
22
- ModuleVersion,
23
27
  NrfutilJson,
24
- NrfutilProgress,
25
- Progress,
26
- Task,
27
- TaskBegin,
28
- TaskEnd,
28
+ OnProgress,
29
+ OnTaskBegin,
30
+ OnTaskEnd,
29
31
  } from './sandboxTypes';
32
+ import {
33
+ coreVersionsToInstall,
34
+ type ModuleVersion,
35
+ versionToInstall,
36
+ } from './version/moduleVersion';
30
37
 
31
- const parseJsonBuffers = <T>(data: Buffer): T[] | undefined => {
32
- const dataString = data.toString().trim();
33
- if (!dataString.endsWith('}')) {
34
- return undefined;
35
- }
36
- try {
37
- return JSON.parse(`[${dataString.replaceAll('}\n{', '}\n,{')}]`) ?? [];
38
- } catch {
39
- return undefined;
40
- }
41
- };
42
-
43
- const nrfutilSandboxPathSegments = (
44
- baseDir: string,
45
- module: string,
46
- version: string,
47
- coreVersion?: string
48
- ) => [
49
- baseDir,
50
- 'nrfutil-sandboxes',
51
- ...(process.platform === 'darwin' && process.arch !== 'x64'
52
- ? [process.arch]
53
- : []),
54
- ...(coreVersion != null ? [coreVersion] : []),
55
- module,
56
- version,
57
- ];
58
-
59
- const prepareEnv = (
60
- baseDir: string,
61
- module: string,
62
- version: string,
63
- coreVersion?: string
64
- ) => {
65
- const env = { ...process.env };
66
- env.NRFUTIL_HOME = path.join(
67
- ...nrfutilSandboxPathSegments(baseDir, module, version, coreVersion)
68
- );
69
- fs.mkdirSync(env.NRFUTIL_HOME, { recursive: true });
70
-
71
- env.NRFUTIL_EXEC_PATH = path.join(env.NRFUTIL_HOME, 'bin');
72
-
73
- if (
74
- process.env.NODE_ENV === 'production' &&
75
- !process.env.NRF_OVERRIDE_NRFUTIL_SETTINGS
38
+ const CORE_VERSION_FOR_LEGACY_APPS = '8.0.0';
39
+
40
+ export class NrfutilSandbox {
41
+ private readonly onLoggingHandlers: ((
42
+ logging: LogMessage,
43
+ pid?: number
44
+ ) => void)[] = [];
45
+ private logLevel: LogLevel = isDevelopment ? 'error' : 'off';
46
+
47
+ private readonly sandboxPath;
48
+ private readonly env;
49
+
50
+ public static async create(
51
+ baseDir: string,
52
+ module: string,
53
+ version?: string,
54
+ coreVersion?: string,
55
+ onProgress?: OnProgress
76
56
  ) {
77
- delete env.NRFUTIL_BOOTSTRAP_CONFIG_URL;
78
- delete env.NRFUTIL_BOOTSTRAP_TARBALL_PATH;
79
- delete env.NRFUTIL_DEVICE_PLUGINS_DIR_FORCE_NRFDL_LOCATION;
80
- delete env.NRFUTIL_DEVICE_PLUGINS_DIR_FORCE_NRFUTIL_LIBDIR;
81
- delete env.NRFUTIL_IGNORE_MISSING_SUBCOMMAND;
82
- delete env.NRFUTIL_LOG;
83
- delete env.NRFUTIL_PACKAGE_INDEX_URL;
84
- }
57
+ const sandbox = new NrfutilSandbox(
58
+ baseDir,
59
+ module,
60
+ versionToInstall(module, version),
61
+ coreVersionsToInstall(coreVersion)
62
+ );
85
63
 
86
- return env;
87
- };
88
-
89
- const commonParser = <Result>(
90
- data: Buffer,
91
- callbacks: {
92
- onProgress?: (progress: Progress, task?: Task) => void;
93
- onInfo?: (info: Result) => void;
94
- onTaskBegin?: (taskEnd: TaskBegin) => void;
95
- onTaskEnd?: (taskEnd: TaskEnd<Result>) => void;
96
- onLogging?: (logging: LogMessage, pid?: number) => void;
97
- },
98
- pid?: number
99
- ): Buffer | undefined => {
100
- const parsedData: NrfutilJson<Result>[] | undefined =
101
- parseJsonBuffers(data);
102
-
103
- if (!parsedData) {
104
- return data;
105
- }
64
+ onProgress?.(convertNrfutilProgress({ progressPercentage: 0 }));
106
65
 
107
- const processItem = (item: NrfutilJson<Result>) => {
108
- switch (item.type) {
109
- case 'task_progress':
110
- callbacks.onProgress?.(
111
- convertNrfutilProgress(item.data.progress),
112
- item.data.task
113
- );
114
- break;
115
- case 'task_begin':
116
- callbacks.onTaskBegin?.(item.data);
117
- break;
118
- case 'task_end':
119
- callbacks.onTaskEnd?.(item.data);
120
- break;
121
- case 'info':
122
- callbacks.onInfo?.(item.data);
123
- break;
124
- case 'log':
125
- callbacks.onLogging?.(item.data, pid);
126
- break;
127
- case 'batch_update':
128
- processItem(item.data.data);
129
- break;
66
+ if (!(await sandbox.isSandboxInstalled())) {
67
+ await sandbox.prepareSandbox(onProgress);
130
68
  }
131
- };
132
-
133
- parsedData.forEach(processItem);
134
- };
135
69
 
136
- export class NrfutilSandbox {
137
- baseDir: string;
138
- module: string;
139
- version: string;
140
- coreVersion: string | undefined; // Must only be undefined when the launcher creates a sandbox for a legacy app, which does not specify the required core version
141
- onLoggingHandlers: ((logging: LogMessage, pid?: number) => void)[] = [];
142
- logLevel: LogLevel = isDevelopment ? 'error' : 'off';
143
- env: ReturnType<typeof prepareEnv>;
70
+ onProgress?.(convertNrfutilProgress({ progressPercentage: 100 }));
144
71
 
145
- readonly CORE_VERSION_FOR_LEGACY_APPS = '8.0.0';
72
+ return sandbox;
73
+ }
146
74
 
147
- constructor(
148
- baseDir: string,
149
- module: string,
150
- version: string,
151
- coreVersion?: string
75
+ private constructor(
76
+ private readonly baseDir: string,
77
+ private readonly module: string,
78
+ private readonly version: string,
79
+ private readonly coreVersion?: string // Must only be undefined when the launcher creates a sandbox for a legacy app, which does not specify the required core version
152
80
  ) {
153
- this.baseDir = baseDir;
154
- this.module = module;
155
- this.version = version;
156
- this.coreVersion = coreVersion;
81
+ this.sandboxPath = path.join(
82
+ this.baseDir,
83
+ 'nrfutil-sandboxes',
84
+ ...(process.platform === 'darwin' && process.arch !== 'x64'
85
+ ? [process.arch]
86
+ : []),
87
+ ...(this.coreVersion != null ? [this.coreVersion] : []),
88
+ this.module,
89
+ this.version
90
+ );
157
91
 
158
- this.env = prepareEnv(baseDir, module, version, coreVersion);
92
+ this.env = this.prepareEnv();
159
93
  }
160
94
 
161
- private processLoggingData = (data: NrfutilJson, pid?: number) => {
162
- if (data.type === 'log') {
163
- this.onLoggingHandlers.forEach(onLogging =>
164
- onLogging(data.data, pid)
165
- );
166
- return true;
95
+ private prepareEnv() {
96
+ const env = { ...process.env };
97
+ env.NRFUTIL_HOME = this.sandboxPath;
98
+ fs.mkdirSync(env.NRFUTIL_HOME, { recursive: true });
99
+
100
+ env.NRFUTIL_EXEC_PATH = path.join(env.NRFUTIL_HOME, 'bin');
101
+
102
+ if (
103
+ process.env.NODE_ENV === 'production' &&
104
+ !process.env.NRF_OVERRIDE_NRFUTIL_SETTINGS
105
+ ) {
106
+ delete env.NRFUTIL_BOOTSTRAP_CONFIG_URL;
107
+ delete env.NRFUTIL_BOOTSTRAP_TARBALL_PATH;
108
+ delete env.NRFUTIL_DEVICE_PLUGINS_DIR_FORCE_NRFDL_LOCATION;
109
+ delete env.NRFUTIL_DEVICE_PLUGINS_DIR_FORCE_NRFUTIL_LIBDIR;
110
+ delete env.NRFUTIL_IGNORE_MISSING_SUBCOMMAND;
111
+ delete env.NRFUTIL_LOG;
112
+ delete env.NRFUTIL_PACKAGE_INDEX_URL;
167
113
  }
168
114
 
169
- return false;
170
- };
115
+ return env;
116
+ }
171
117
 
172
118
  public getModuleVersion = async () => {
173
119
  const results = await this.spawnNrfutil<ModuleVersion>(this.module, [
@@ -191,32 +137,31 @@ export class NrfutilSandbox {
191
137
  throw new Error('Unexpected result');
192
138
  };
193
139
 
194
- public isSandboxInstalled = async () => {
195
- if (
196
- fs.existsSync(
197
- path.join(
198
- ...nrfutilSandboxPathSegments(
199
- this.baseDir,
200
- this.module,
201
- this.version,
202
- this.coreVersion
203
- ),
204
- 'bin',
205
- `nrfutil-${this.module}${
206
- os.platform() === 'win32' ? '.exe' : ''
207
- }`
208
- )
140
+ public isSandboxInstalled = () =>
141
+ this.executableExists() && this.commandReportsCorrectVersion();
142
+
143
+ private log(message: LogMessage, pid: number | undefined) {
144
+ this.onLoggingHandlers.forEach(onLogging => onLogging(message, pid));
145
+ }
146
+
147
+ private executableExists() {
148
+ return fs.existsSync(
149
+ path.join(
150
+ this.sandboxPath,
151
+ 'bin',
152
+ `nrfutil-${this.module}${
153
+ os.platform() === 'win32' ? '.exe' : ''
154
+ }`
209
155
  )
210
- ) {
211
- const moduleVersion = await this.getModuleVersion();
212
- return moduleVersion.version === this.version;
213
- }
214
- return false;
215
- };
156
+ );
157
+ }
216
158
 
217
- public prepareSandbox = async (
218
- onProgress?: (progress: Progress, task?: Task) => void
219
- ) => {
159
+ private async commandReportsCorrectVersion() {
160
+ const moduleVersion = await this.getModuleVersion();
161
+ return moduleVersion.version === this.version;
162
+ }
163
+
164
+ public prepareSandbox = async (onProgress?: OnProgress) => {
220
165
  try {
221
166
  // Clean up any residual sandbox from before if any
222
167
  if (this.env.NRFUTIL_HOME && fs.existsSync(this.env.NRFUTIL_HOME)) {
@@ -239,12 +184,10 @@ export class NrfutilSandbox {
239
184
  }
240
185
  };
241
186
 
242
- private installNrfUtilCore = async (
243
- onProgress?: (progress: Progress, task?: Task) => void
244
- ) => {
187
+ private installNrfUtilCore = async (onProgress?: OnProgress) => {
245
188
  const currentCoreVersion = await this.getCoreVersion();
246
189
  const requestedCoreVersion =
247
- this.coreVersion ?? this.CORE_VERSION_FOR_LEGACY_APPS;
190
+ this.coreVersion ?? CORE_VERSION_FOR_LEGACY_APPS;
248
191
  if (currentCoreVersion.version === requestedCoreVersion) {
249
192
  getNrfutilLogger()?.debug(
250
193
  `Requested nrfutil core version ${requestedCoreVersion} is already installed.`
@@ -262,9 +205,7 @@ export class NrfutilSandbox {
262
205
  );
263
206
  };
264
207
 
265
- public installNrfUtilCommand = (
266
- onProgress?: (progress: Progress, task?: Task) => void
267
- ) =>
208
+ public installNrfUtilCommand = (onProgress?: OnProgress) =>
268
209
  this.install(
269
210
  this.module,
270
211
  this.version,
@@ -298,9 +239,9 @@ export class NrfutilSandbox {
298
239
  public spawnNrfutilSubcommand = <Result>(
299
240
  command: string,
300
241
  args: string[],
301
- onProgress?: (progress: Progress, task?: Task) => void,
302
- onTaskBegin?: (taskBegin: TaskBegin) => void,
303
- onTaskEnd?: (taskEnd: TaskEnd<Result>) => void,
242
+ onProgress?: OnProgress,
243
+ onTaskBegin?: OnTaskBegin,
244
+ onTaskEnd?: OnTaskEnd<Result>,
304
245
  controller?: AbortController,
305
246
  editEnv?: (env: NodeJS.ProcessEnv) => NodeJS.ProcessEnv
306
247
  ) =>
@@ -341,42 +282,27 @@ export class NrfutilSandbox {
341
282
  private spawnNrfutil = async <Result>(
342
283
  command: string,
343
284
  args: string[],
344
- onProgress?: (progress: Progress, task?: Task) => void,
345
- onTaskBegin?: (taskBegin: TaskBegin) => void,
346
- onTaskEnd?: (taskEnd: TaskEnd<Result>) => void,
285
+ onProgress?: OnProgress,
286
+ onTaskBegin?: OnTaskBegin,
287
+ onTaskEnd?: OnTaskEnd<Result>,
347
288
  controller?: AbortController,
348
289
  editEnv?: (env: NodeJS.ProcessEnv) => NodeJS.ProcessEnv
349
290
  ) => {
350
- const info: Result[] = [];
351
- const taskEnd: TaskEnd<Result>[] = [];
352
291
  let stdErr: string | undefined;
353
292
  let pid: number | undefined;
354
293
 
294
+ const parser = new CollectingResultParser(
295
+ this.log,
296
+ onProgress,
297
+ onTaskBegin,
298
+ onTaskEnd
299
+ );
300
+
355
301
  try {
356
302
  await this.spawnNrfutilCommand(
357
303
  command,
358
304
  args,
359
- (data, processId) =>
360
- commonParser<Result>(
361
- data,
362
- {
363
- onProgress,
364
- onTaskBegin,
365
- onTaskEnd: end => {
366
- taskEnd.push(end);
367
- onTaskEnd?.(end);
368
- },
369
- onInfo: i => {
370
- info.push(i);
371
- },
372
- onLogging: logging => {
373
- this.onLoggingHandlers.forEach(onLogging => {
374
- onLogging(logging, processId);
375
- });
376
- },
377
- },
378
- processId
379
- ),
305
+ parser.handleData,
380
306
  (data, processId) => {
381
307
  pid = processId;
382
308
  stdErr = (stdErr ?? '') + data.toString();
@@ -385,39 +311,20 @@ export class NrfutilSandbox {
385
311
  editEnv
386
312
  );
387
313
 
388
- if (
389
- stdErr ||
390
- taskEnd.filter(end => end.result === 'fail').length > 0
391
- )
392
- throw new Error('Task failed.');
314
+ if (stdErr || parser.hasFailures()) throw new Error('Task failed.');
393
315
 
394
- return { taskEnd, info };
316
+ return parser.result();
395
317
  } catch (e) {
396
318
  const error = e as Error;
397
319
 
398
- const addPunctuation = (str: string) =>
399
- str.endsWith('.') ? str.trim() : `${str.trim()}.`;
400
-
401
- if (stdErr) {
402
- error.message += `\n${addPunctuation(stdErr)}`;
403
- }
404
-
405
- const taskEndErrorMsg = taskEnd
406
- .filter(end => end.result === 'fail' && !!end.message)
407
- .map(end =>
408
- end.message ? `Message: ${addPunctuation(end.message)}` : ''
409
- )
410
- .join('\n');
411
-
412
- if (taskEndErrorMsg) {
413
- error.message += `\n${taskEndErrorMsg}`;
414
- }
320
+ error.message = collectErrorMessages(
321
+ error.message,
322
+ stdErr,
323
+ parser.errorMessage()
324
+ );
415
325
 
416
- error.message = error.message.replaceAll('Error: ', '');
417
326
  telemetry.sendErrorReport(
418
- `${
419
- pid && this.logLevel === 'trace' ? `[PID:${pid}] ` : ''
420
- }${describeError(error)}`
327
+ `${this.pidIfTraceLogging(pid)}${describeError(error)}`
421
328
  );
422
329
  throw error;
423
330
  }
@@ -508,9 +415,9 @@ export class NrfutilSandbox {
508
415
  public execNrfutilSubcommand = <Result>(
509
416
  command: string,
510
417
  args: string[],
511
- onProgress?: (progress: Progress, task?: Task) => void,
512
- onTaskBegin?: (taskBegin: TaskBegin) => void,
513
- onTaskEnd?: (taskEnd: TaskEnd<Result>) => void,
418
+ onProgress?: OnProgress,
419
+ onTaskBegin?: OnTaskBegin,
420
+ onTaskEnd?: OnTaskEnd<Result>,
514
421
  controller?: AbortController,
515
422
  editEnv?: (env: NodeJS.ProcessEnv) => NodeJS.ProcessEnv
516
423
  ) =>
@@ -527,42 +434,27 @@ export class NrfutilSandbox {
527
434
  private execNrfutilCommand = async <Result>(
528
435
  command: string,
529
436
  args: string[],
530
- onProgress?: (progress: Progress, task?: Task) => void,
531
- onTaskBegin?: (taskBegin: TaskBegin) => void,
532
- onTaskEnd?: (taskEnd: TaskEnd<Result>) => void,
437
+ onProgress?: OnProgress,
438
+ onTaskBegin?: OnTaskBegin,
439
+ onTaskEnd?: OnTaskEnd<Result>,
533
440
  controller?: AbortController,
534
441
  editEnv?: (env: NodeJS.ProcessEnv) => NodeJS.ProcessEnv
535
442
  ) => {
536
- const info: Result[] = [];
537
- const taskEnd: TaskEnd<Result>[] = [];
538
443
  let stdErr: string | undefined;
539
444
  let pid: number | undefined;
540
445
 
446
+ const parser = new CollectingResultParser(
447
+ this.log,
448
+ onProgress,
449
+ onTaskBegin,
450
+ onTaskEnd
451
+ );
452
+
541
453
  try {
542
454
  await this.execCommand(
543
455
  command,
544
456
  args,
545
- (data, processId) =>
546
- commonParser<Result>(
547
- data,
548
- {
549
- onProgress,
550
- onTaskBegin,
551
- onTaskEnd: end => {
552
- taskEnd.push(end);
553
- onTaskEnd?.(end);
554
- },
555
- onInfo: i => {
556
- info.push(i);
557
- },
558
- onLogging: logging => {
559
- this.onLoggingHandlers.forEach(onLogging => {
560
- onLogging(logging, processId);
561
- });
562
- },
563
- },
564
- processId
565
- ),
457
+ parser.handleData,
566
458
  (data, processId) => {
567
459
  pid = processId;
568
460
  stdErr = (stdErr ?? '') + data.toString();
@@ -571,39 +463,20 @@ export class NrfutilSandbox {
571
463
  editEnv
572
464
  );
573
465
 
574
- if (
575
- stdErr ||
576
- taskEnd.filter(end => end.result === 'fail').length > 0
577
- )
578
- throw new Error('Task failed.');
466
+ if (stdErr || parser.hasFailures()) throw new Error('Task failed.');
579
467
 
580
- return { taskEnd, info };
468
+ return parser.result();
581
469
  } catch (e) {
582
470
  const error = e as Error;
583
471
 
584
- const addPunctuation = (str: string) =>
585
- str.endsWith('.') ? str.trim() : `${str.trim()}.`;
586
-
587
- if (stdErr) {
588
- error.message += `\n${addPunctuation(stdErr)}`;
589
- }
590
-
591
- const taskEndErrorMsg = taskEnd
592
- .filter(end => end.result === 'fail' && !!end.message)
593
- .map(end =>
594
- end.message ? `Message: ${addPunctuation(end.message)}` : ''
595
- )
596
- .join('\n');
597
-
598
- if (taskEndErrorMsg) {
599
- error.message += `\n${taskEndErrorMsg}`;
600
- }
472
+ error.message = collectErrorMessages(
473
+ error.message,
474
+ stdErr,
475
+ parser.errorMessage()
476
+ );
601
477
 
602
- error.message = error.message.replaceAll('Error: ', '');
603
478
  telemetry.sendErrorReport(
604
- `${
605
- pid && this.logLevel === 'trace' ? `[PID:${pid}] ` : ''
606
- }${describeError(error)}`
479
+ `${this.pidIfTraceLogging(pid)}${describeError(error)}`
607
480
  );
608
481
  throw error;
609
482
  }
@@ -697,10 +570,12 @@ export class NrfutilSandbox {
697
570
  }
698
571
 
699
572
  parsedData.forEach(item => {
700
- if (!this.processLoggingData(item, pid)) {
701
- if (item.type === 'info') {
702
- processors.onData(item.data);
703
- }
573
+ if (item.type === 'log') {
574
+ this.log(item.data, pid);
575
+ }
576
+
577
+ if (item.type === 'info') {
578
+ processors.onData(item.data);
704
579
  }
705
580
  });
706
581
  },
@@ -739,7 +614,7 @@ export class NrfutilSandbox {
739
614
 
740
615
  public singleTaskEndOperationWithData = async <T>(
741
616
  command: string,
742
- onProgress?: (progress: Progress, task?: Task) => void,
617
+ onProgress?: OnProgress,
743
618
  controller?: AbortController,
744
619
  args: string[] = []
745
620
  ) => {
@@ -758,7 +633,7 @@ export class NrfutilSandbox {
758
633
 
759
634
  public singleTaskEndOperationOptionalData = async <T = void>(
760
635
  command: string,
761
- onProgress?: (progress: Progress, task?: Task) => void,
636
+ onProgress?: OnProgress,
762
637
  controller?: AbortController,
763
638
  args: string[] = []
764
639
  ) => {
@@ -809,50 +684,10 @@ export class NrfutilSandbox {
809
684
  );
810
685
  };
811
686
 
687
+ public pidIfTraceLogging = (pid?: number) =>
688
+ pid != null && this.logLevel === 'trace' ? `[PID:${pid}] ` : '';
689
+
812
690
  public setLogLevel = (level: LogLevel) => {
813
691
  this.logLevel = level;
814
692
  };
815
693
  }
816
-
817
- export default async (
818
- baseDir: string,
819
- module: string,
820
- version?: string,
821
- coreVersion?: string,
822
- onProgress?: (progress: Progress, task?: Task) => void
823
- ) => {
824
- const sandbox = new NrfutilSandbox(
825
- baseDir,
826
- module,
827
- versionToInstall(module, version),
828
- coreVersionsToInstall(coreVersion)
829
- );
830
-
831
- onProgress?.(convertNrfutilProgress({ progressPercentage: 0 }));
832
-
833
- if (!(await sandbox.isSandboxInstalled())) {
834
- await sandbox.prepareSandbox(onProgress);
835
- }
836
-
837
- onProgress?.(convertNrfutilProgress({ progressPercentage: 100 }));
838
- return sandbox;
839
- };
840
-
841
- const convertNrfutilProgress = (progress: NrfutilProgress): Progress => {
842
- const amountOfSteps = progress.amountOfSteps ?? 1;
843
- const step = progress.step ?? 1;
844
-
845
- const singleStepWeight = (1 / amountOfSteps) * 100;
846
-
847
- const totalProgressPercentage =
848
- singleStepWeight * (step - 1) +
849
- progress.progressPercentage / amountOfSteps;
850
-
851
- return {
852
- ...progress,
853
- stepProgressPercentage: progress.progressPercentage,
854
- totalProgressPercentage,
855
- amountOfSteps,
856
- step,
857
- };
858
- };