@altronix/cli 0.6.10 → 0.7.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.
- package/bin/{atx → atx-workspace} +0 -0
- package/build/build.d.ts +2 -0
- package/build/build.js +240 -0
- package/build/build.js.map +1 -0
- package/build/index.d.ts +1 -1
- package/build/index.js +39 -86
- package/build/index.js.map +1 -1
- package/build/seedle.d.ts +2 -0
- package/build/seedle.js +41 -0
- package/build/seedle.js.map +1 -0
- package/package.json +21 -21
- package/src/build.ts +354 -0
- package/src/index.ts +25 -86
- package/src/seedle.ts +39 -0
- package/tsconfig.json +1 -1
- package/tsconfig.lib.tsbuildinfo +1 -1
- package/build/about.d.ts +0 -3
- package/build/about.js +0 -38
- package/build/about.js.map +0 -1
- package/build/cloud.d.ts +0 -2
- package/build/cloud.js +0 -42
- package/build/cloud.js.map +0 -1
- package/build/common.d.ts +0 -5
- package/build/common.js +0 -49
- package/build/common.js.map +0 -1
- package/build/confirmDevice.d.ts +0 -5
- package/build/confirmDevice.js +0 -36
- package/build/confirmDevice.js.map +0 -1
- package/build/context.d.ts +0 -8
- package/build/context.js +0 -23
- package/build/context.js.map +0 -1
- package/build/dhcp.d.ts +0 -1
- package/build/dhcp.js +0 -10
- package/build/dhcp.js.map +0 -1
- package/build/exe.d.ts +0 -4
- package/build/exe.js +0 -43
- package/build/exe.js.map +0 -1
- package/build/ip.d.ts +0 -2
- package/build/ip.js +0 -18
- package/build/ip.js.map +0 -1
- package/build/linq.d.ts +0 -1
- package/build/linq.js +0 -3
- package/build/linq.js.map +0 -1
- package/build/listen.d.ts +0 -1
- package/build/listen.js +0 -24
- package/build/listen.js.map +0 -1
- package/build/net.d.ts +0 -3
- package/build/net.js +0 -47
- package/build/net.js.map +0 -1
- package/build/poe.d.ts +0 -1
- package/build/poe.js +0 -3
- package/build/poe.js.map +0 -1
- package/build/reboot.d.ts +0 -1
- package/build/reboot.js +0 -16
- package/build/reboot.js.map +0 -1
- package/build/site.d.ts +0 -2
- package/build/site.js +0 -19
- package/build/site.js.map +0 -1
- package/build/stress.d.ts +0 -1
- package/build/stress.js +0 -30
- package/build/stress.js.map +0 -1
- package/build/unix.d.ts +0 -1
- package/build/unix.js +0 -14
- package/build/unix.js.map +0 -1
- package/build/update.d.ts +0 -1
- package/build/update.js +0 -60
- package/build/update.js.map +0 -1
- package/build/west.d.ts +0 -1
- package/build/west.js +0 -3
- package/build/west.js.map +0 -1
- package/src/about.ts +0 -47
- package/src/cloud.ts +0 -55
- package/src/exe.ts +0 -54
- package/src/listen.ts +0 -23
- package/src/net.ts +0 -68
- package/src/poe.ts +0 -1
- package/src/stress.ts +0 -37
- package/src/update.ts +0 -84
- package/src/update.ts.bak +0 -98
package/src/build.ts
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
import { Ajv, JSONSchemaType } from "ajv";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import cp from "node:child_process";
|
|
7
|
+
import {
|
|
8
|
+
concat,
|
|
9
|
+
from,
|
|
10
|
+
lastValueFrom,
|
|
11
|
+
merge,
|
|
12
|
+
mergeMap,
|
|
13
|
+
Observable,
|
|
14
|
+
OperatorFunction,
|
|
15
|
+
} from "rxjs";
|
|
16
|
+
|
|
17
|
+
interface AtxConfig {
|
|
18
|
+
configs?: string[];
|
|
19
|
+
overlays?: string[];
|
|
20
|
+
}
|
|
21
|
+
interface AtxBoard {
|
|
22
|
+
[key: string]: AtxConfig;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface AtxBuild {
|
|
26
|
+
sourceDir: string;
|
|
27
|
+
binaryDir: string;
|
|
28
|
+
installDir: string;
|
|
29
|
+
boards: { [key: string]: AtxBoard };
|
|
30
|
+
}
|
|
31
|
+
interface AtxWorkspace {
|
|
32
|
+
applications: { [key: string]: AtxBuild };
|
|
33
|
+
bootloaders: { [key: string]: AtxBuild };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const ajv = new Ajv({ allErrors: true, verbose: true });
|
|
37
|
+
const schemaBuild: JSONSchemaType<{ [key: string]: AtxBuild }> = {
|
|
38
|
+
type: "object",
|
|
39
|
+
required: [],
|
|
40
|
+
patternProperties: {
|
|
41
|
+
".*": {
|
|
42
|
+
type: "object",
|
|
43
|
+
required: ["sourceDir", "binaryDir", "installDir", "boards"],
|
|
44
|
+
properties: {
|
|
45
|
+
sourceDir: { type: "string" },
|
|
46
|
+
binaryDir: { type: "string" },
|
|
47
|
+
installDir: { type: "string" },
|
|
48
|
+
boards: {
|
|
49
|
+
type: "object",
|
|
50
|
+
required: [],
|
|
51
|
+
patternProperties: {
|
|
52
|
+
".*": {
|
|
53
|
+
type: "object",
|
|
54
|
+
required: [],
|
|
55
|
+
patternProperties: {
|
|
56
|
+
".*": {
|
|
57
|
+
type: "object",
|
|
58
|
+
properties: {
|
|
59
|
+
configs: {
|
|
60
|
+
type: "array",
|
|
61
|
+
items: { type: "string" },
|
|
62
|
+
nullable: true,
|
|
63
|
+
},
|
|
64
|
+
overlays: {
|
|
65
|
+
type: "array",
|
|
66
|
+
items: { type: "string" },
|
|
67
|
+
nullable: true,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const schema: JSONSchemaType<AtxWorkspace> = {
|
|
80
|
+
type: "object",
|
|
81
|
+
required: ["applications", "bootloaders"],
|
|
82
|
+
additionalProperties: false,
|
|
83
|
+
properties: {
|
|
84
|
+
applications: schemaBuild,
|
|
85
|
+
bootloaders: schemaBuild,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
const validate = ajv.compile(schema);
|
|
89
|
+
|
|
90
|
+
interface Version {
|
|
91
|
+
major: number;
|
|
92
|
+
minor: number;
|
|
93
|
+
patch: number;
|
|
94
|
+
tweak: number;
|
|
95
|
+
extra: string;
|
|
96
|
+
}
|
|
97
|
+
async function parseAppVersion(v: string): Promise<Version> {
|
|
98
|
+
const data = await fs.promises.readFile(v, "ascii");
|
|
99
|
+
const reMajor = data.matchAll(/^VERSION_MAJOR = ([0-9]+)/gm).next();
|
|
100
|
+
const reMinor = data.matchAll(/^VERSION_MINOR = ([0-9]+)/gm).next();
|
|
101
|
+
const rePatch = data.matchAll(/^PATCHLEVEL = ([0-9]+)/gm).next();
|
|
102
|
+
const reTweak = data.matchAll(/^VERSION_TWEAK = ([0-9]+)/gm).next();
|
|
103
|
+
const reExtra = data.matchAll(/^EXTRAVERSION = ([.a-zA-Z-]+)/gm).next();
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
major: reMajor.value ? parseInt(reMajor.value[1]) : 0,
|
|
107
|
+
minor: reMinor.value ? parseInt(reMinor.value[1]) : 0,
|
|
108
|
+
patch: rePatch.value ? parseInt(rePatch.value[1]) : 0,
|
|
109
|
+
tweak: reTweak.value ? parseInt(reTweak.value[1]) : 0,
|
|
110
|
+
extra: reExtra.value ? reExtra.value[1] : "",
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function formatVersion(ver: Version): string {
|
|
115
|
+
const { major, minor, patch, tweak, extra } = ver;
|
|
116
|
+
return extra.length
|
|
117
|
+
? `${major}-${minor}-${patch}-${tweak}-${extra}`
|
|
118
|
+
: `${major}-${minor}-${patch}-${tweak}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
interface WestOptions {
|
|
122
|
+
cwd: string;
|
|
123
|
+
name: string;
|
|
124
|
+
board: string;
|
|
125
|
+
config: string;
|
|
126
|
+
version: string;
|
|
127
|
+
sourceDir: string;
|
|
128
|
+
binaryDir: string;
|
|
129
|
+
installDir: string;
|
|
130
|
+
outputFile: string;
|
|
131
|
+
errorFile: string;
|
|
132
|
+
confs: string[];
|
|
133
|
+
overlays: string[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function normalizeWestOptions(
|
|
137
|
+
appName: string,
|
|
138
|
+
boardName: string,
|
|
139
|
+
configName: string,
|
|
140
|
+
app: AtxBuild,
|
|
141
|
+
cwd: string
|
|
142
|
+
) {
|
|
143
|
+
const resolve = (dir: string, from?: string) =>
|
|
144
|
+
path.isAbsolute(dir) ? dir : path.resolve(from || cwd, dir);
|
|
145
|
+
const sourceDir = resolve(app.sourceDir);
|
|
146
|
+
const binaryDir = path.join(resolve(app.binaryDir), boardName, configName);
|
|
147
|
+
const installDir = resolve(app.installDir);
|
|
148
|
+
const confs = app.boards[boardName][configName].configs || [];
|
|
149
|
+
const versionFile = path.join(sourceDir, "VERSION");
|
|
150
|
+
const version = formatVersion(await parseAppVersion(versionFile));
|
|
151
|
+
const overlays = [];
|
|
152
|
+
return {
|
|
153
|
+
name: appName,
|
|
154
|
+
board: boardName,
|
|
155
|
+
config: configName,
|
|
156
|
+
cwd,
|
|
157
|
+
version,
|
|
158
|
+
sourceDir,
|
|
159
|
+
binaryDir,
|
|
160
|
+
installDir,
|
|
161
|
+
outputFile: path.join(binaryDir, "build.log"),
|
|
162
|
+
errorFile: path.join(binaryDir, "build.err"),
|
|
163
|
+
confs,
|
|
164
|
+
overlays,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function extraApplicationConfs(extraConfs: string): Observable<void> {
|
|
169
|
+
const key = process.env["ALTRONIX_RELEASE_KEY"];
|
|
170
|
+
if (!key) throw new Error("missing ALTRONIX_RELEASE_KEY from environment");
|
|
171
|
+
const extraConfsData = [
|
|
172
|
+
`CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="${key}"`,
|
|
173
|
+
`CONFIG_BOOTLOADER_MCUBOOT=y`,
|
|
174
|
+
`CONFIG_ATX_UPDATE_ENABLE=y`,
|
|
175
|
+
].join("\r\n");
|
|
176
|
+
return from(fs.promises.writeFile(extraConfs, extraConfsData));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function emulateBytePages(board: string) {
|
|
180
|
+
return (
|
|
181
|
+
board.startsWith("atsame54_xpro") ||
|
|
182
|
+
board.startsWith("netway4e1bt") ||
|
|
183
|
+
board.startsWith("netway4eb") ||
|
|
184
|
+
board.startsWith("netway5pq") ||
|
|
185
|
+
board.startsWith("oa2b")
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function extraBootloaderConfs(
|
|
190
|
+
board: string,
|
|
191
|
+
extraConfs: string
|
|
192
|
+
): Observable<void> {
|
|
193
|
+
const key = process.env["ALTRONIX_RELEASE_KEY"];
|
|
194
|
+
if (!key) throw new Error("missing ALTRONIX_RELEASE_KEY from environment");
|
|
195
|
+
const extraConfsData = [`CONFIG_BOOT_SIGNATURE_KEY_FILE="${key}"`];
|
|
196
|
+
if (emulateBytePages(board)) {
|
|
197
|
+
extraConfsData.push(`CONFIG_SOC_FLASH_SAM0_EMULATE_BYTE_PAGES=y`);
|
|
198
|
+
}
|
|
199
|
+
return from(fs.promises.writeFile(extraConfs, extraConfsData.join("\r\n")));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function west(args: WestOptions): Observable<void> {
|
|
203
|
+
const { cwd, board, sourceDir, binaryDir, confs, overlays } = args;
|
|
204
|
+
const westArgs = [
|
|
205
|
+
`build`,
|
|
206
|
+
`-b ${board}`,
|
|
207
|
+
`-s ${sourceDir}`,
|
|
208
|
+
`-d ${binaryDir}`,
|
|
209
|
+
`--`,
|
|
210
|
+
`-DEXTRA_CONF_FILE="${[...confs].join(";")}"`,
|
|
211
|
+
`-DEXTRA_DTC_OVERLAY_FILE="${[...overlays].join(";")}"`,
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
return new Observable((subscriber) => {
|
|
215
|
+
const west = cp.spawn("west", westArgs, { cwd, shell: true });
|
|
216
|
+
const fout = fs.createWriteStream(args.outputFile);
|
|
217
|
+
const ferr = fs.createWriteStream(args.errorFile);
|
|
218
|
+
west.stdout.pipe(fout);
|
|
219
|
+
west.stderr.pipe(ferr);
|
|
220
|
+
west.on("error", (e) => {
|
|
221
|
+
subscriber.error(e);
|
|
222
|
+
fout.close();
|
|
223
|
+
ferr.close();
|
|
224
|
+
});
|
|
225
|
+
west.on("exit", () => {
|
|
226
|
+
fout.close();
|
|
227
|
+
ferr.close();
|
|
228
|
+
subscriber.next();
|
|
229
|
+
subscriber.complete();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function installSignedBin(args: WestOptions): Observable<void> {
|
|
235
|
+
const { name, config, version, board, binaryDir, installDir: dir } = args;
|
|
236
|
+
const src = path.join(binaryDir, "zephyr", "zephyr.signed.bin");
|
|
237
|
+
const dst = path.join(
|
|
238
|
+
dir,
|
|
239
|
+
`${board}-${name}-${config}-${version}.signed.bin`
|
|
240
|
+
);
|
|
241
|
+
return new Observable((subscriber) => {
|
|
242
|
+
fs.promises
|
|
243
|
+
.copyFile(src, dst)
|
|
244
|
+
.then(() => subscriber.next())
|
|
245
|
+
.catch((e) => subscriber.error(e))
|
|
246
|
+
.finally(() => subscriber.complete());
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function installBin(args: WestOptions): Observable<void> {
|
|
251
|
+
const { name, config, version, board, binaryDir, installDir: dir } = args;
|
|
252
|
+
const src = path.join(binaryDir, "zephyr", "zephyr.bin");
|
|
253
|
+
const dst = path.join(dir, `${board}-${name}-${config}-${version}.bin`);
|
|
254
|
+
return new Observable((subscriber) => {
|
|
255
|
+
fs.promises
|
|
256
|
+
.copyFile(src, dst)
|
|
257
|
+
.then(() => subscriber.next())
|
|
258
|
+
.catch((e) => subscriber.error(e))
|
|
259
|
+
.finally(() => subscriber.complete());
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function mkdir(): OperatorFunction<string, void> {
|
|
264
|
+
return (obs$) =>
|
|
265
|
+
obs$.pipe(
|
|
266
|
+
mergeMap(
|
|
267
|
+
(dir) =>
|
|
268
|
+
new Observable<void>((subscriber) => {
|
|
269
|
+
fs.promises
|
|
270
|
+
.mkdir(dir, { recursive: true })
|
|
271
|
+
.then(() => subscriber.next())
|
|
272
|
+
.catch((e) => subscriber.error(e))
|
|
273
|
+
.finally(() => subscriber.complete());
|
|
274
|
+
})
|
|
275
|
+
)
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
interface RunBuildOptions {
|
|
280
|
+
install$: Observable<void>;
|
|
281
|
+
config$: Observable<void>;
|
|
282
|
+
}
|
|
283
|
+
function runBuild({
|
|
284
|
+
install$,
|
|
285
|
+
config$,
|
|
286
|
+
}: RunBuildOptions): OperatorFunction<WestOptions, void> {
|
|
287
|
+
return (obs$) => {
|
|
288
|
+
// Create all the directories for our build
|
|
289
|
+
const dirs$ = obs$.pipe(
|
|
290
|
+
mergeMap(({ binaryDir, installDir }) => from([binaryDir, installDir])),
|
|
291
|
+
mkdir()
|
|
292
|
+
);
|
|
293
|
+
// Run west commands
|
|
294
|
+
const build$ = obs$.pipe(mergeMap((opts) => west(opts)));
|
|
295
|
+
return concat(dirs$, config$, build$, install$);
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export async function build(this: Command): Promise<void> {
|
|
300
|
+
const config = this.opts().config || path.resolve("./", "atx.json");
|
|
301
|
+
const cwd = path.resolve(path.dirname(config));
|
|
302
|
+
const data = await fs.promises.readFile(config, "ascii");
|
|
303
|
+
const atx: AtxWorkspace = JSON.parse(data);
|
|
304
|
+
const extraAppConfFile = "application.conf";
|
|
305
|
+
const extraBootConfFile = "bootloader.conf";
|
|
306
|
+
if (!validate(atx)) throw validate.errors;
|
|
307
|
+
const env = path.resolve(cwd, ".env");
|
|
308
|
+
dotenv.config({ path: env });
|
|
309
|
+
const apps = Object.keys(atx.applications).flatMap((app) => {
|
|
310
|
+
return Object.keys(atx.applications[app].boards).flatMap((board) => {
|
|
311
|
+
return Object.keys(atx.applications[app].boards[board]).map((config) =>
|
|
312
|
+
normalizeWestOptions(app, board, config, atx.applications[app], cwd)
|
|
313
|
+
);
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
const bootloaders = Object.keys(atx.bootloaders).flatMap((app) => {
|
|
318
|
+
return Object.keys(atx.bootloaders[app].boards).flatMap((board) => {
|
|
319
|
+
return Object.keys(atx.bootloaders[app].boards[board]).map((config) =>
|
|
320
|
+
normalizeWestOptions(app, board, config, atx.bootloaders[app], cwd)
|
|
321
|
+
);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const apps$ = from(await Promise.all(apps));
|
|
326
|
+
const bootloaders$ = from(await Promise.all(bootloaders));
|
|
327
|
+
return lastValueFrom(
|
|
328
|
+
merge(
|
|
329
|
+
bootloaders$.pipe(
|
|
330
|
+
runBuild({
|
|
331
|
+
install$: bootloaders$.pipe(mergeMap((opts) => installBin(opts))),
|
|
332
|
+
config$: bootloaders$.pipe(
|
|
333
|
+
mergeMap(({ board, binaryDir }) =>
|
|
334
|
+
extraBootloaderConfs(
|
|
335
|
+
board,
|
|
336
|
+
path.join(binaryDir, extraBootConfFile)
|
|
337
|
+
)
|
|
338
|
+
)
|
|
339
|
+
),
|
|
340
|
+
})
|
|
341
|
+
),
|
|
342
|
+
apps$.pipe(
|
|
343
|
+
runBuild({
|
|
344
|
+
install$: apps$.pipe(mergeMap((opts) => installSignedBin(opts))),
|
|
345
|
+
config$: apps$.pipe(
|
|
346
|
+
mergeMap(({ binaryDir }) =>
|
|
347
|
+
extraApplicationConfs(path.join(binaryDir, extraAppConfFile))
|
|
348
|
+
)
|
|
349
|
+
),
|
|
350
|
+
})
|
|
351
|
+
)
|
|
352
|
+
)
|
|
353
|
+
);
|
|
354
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,101 +1,40 @@
|
|
|
1
|
-
import { log } from "@altronix/device";
|
|
2
1
|
import { program } from "commander";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import { update } from "./update";
|
|
8
|
-
import { stress } from "./stress";
|
|
9
|
-
import { listen } from "./listen";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import * as seedle from "./seedle";
|
|
5
|
+
import { build } from "./build";
|
|
10
6
|
|
|
11
7
|
(async function main() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
program
|
|
17
|
-
.command("get-about")
|
|
18
|
-
.description("get about data on the device")
|
|
19
|
-
.action(getAbout);
|
|
20
|
-
|
|
21
|
-
program
|
|
22
|
-
.command("get-site")
|
|
23
|
-
.description("get site id from the device")
|
|
24
|
-
.action(getSite);
|
|
25
|
-
|
|
26
|
-
program
|
|
27
|
-
.command("set-site")
|
|
28
|
-
.description("set site id from the device")
|
|
29
|
-
.argument("<site>", "new site id")
|
|
30
|
-
.action(setSite);
|
|
31
|
-
|
|
32
|
-
program
|
|
33
|
-
.command("get-net")
|
|
34
|
-
.description("get network configuration from the device")
|
|
35
|
-
.action(getNet);
|
|
36
|
-
|
|
37
|
-
program
|
|
38
|
-
.command("set-net")
|
|
39
|
-
.description("set network interface into static ip mode")
|
|
40
|
-
.argument("<ip>", "the new IP address")
|
|
41
|
-
.argument("<sn>", "the new SUBNET mask")
|
|
42
|
-
.argument("<gw>", "the new GATEWAY address")
|
|
43
|
-
.action(setNet);
|
|
44
|
-
|
|
45
|
-
program
|
|
46
|
-
.command("set-dhcp")
|
|
47
|
-
.description("set network interface into DHCP mode")
|
|
48
|
-
.action(setDhcp);
|
|
49
|
-
|
|
50
|
-
program
|
|
51
|
-
.command("get-cloud")
|
|
52
|
-
.description("get cloud endpoint on the device")
|
|
53
|
-
.action(getCloud);
|
|
54
|
-
|
|
55
|
-
program
|
|
56
|
-
.command("set-cloud")
|
|
57
|
-
.description("set cloud endpoint on the device")
|
|
58
|
-
.argument("<endpoint>", "cloud service location")
|
|
59
|
-
.action(setCloud);
|
|
60
|
-
|
|
61
|
-
program
|
|
62
|
-
.command("save")
|
|
63
|
-
.description("save data to persistant storage")
|
|
64
|
-
.action(save);
|
|
65
|
-
|
|
66
|
-
program
|
|
67
|
-
.command("save-reboot")
|
|
68
|
-
.description("save data to persistant storage and reboot the device")
|
|
69
|
-
.action(saveAndReboot);
|
|
70
|
-
|
|
71
|
-
program.command("reboot").description("reboot the device").action(reboot);
|
|
72
|
-
|
|
73
|
-
program
|
|
74
|
-
.command("erase")
|
|
75
|
-
.description("erase customer settings")
|
|
76
|
-
.action(reboot);
|
|
8
|
+
// Parse package.json to get version
|
|
9
|
+
const pkg = path.resolve(__dirname, "..", "package.json");
|
|
10
|
+
const ver = JSON.parse(await fs.promises.readFile(pkg, "ascii")).version;
|
|
11
|
+
const cwd = path.resolve("./");
|
|
77
12
|
|
|
78
13
|
program
|
|
79
|
-
.
|
|
80
|
-
.description("
|
|
81
|
-
.
|
|
82
|
-
.action(stress);
|
|
14
|
+
.name("atx")
|
|
15
|
+
.description("build atx zdk projects")
|
|
16
|
+
.version(ver);
|
|
83
17
|
|
|
18
|
+
// Scan command
|
|
19
|
+
const ignore = "node_modules;target;build;.git";
|
|
84
20
|
program
|
|
85
|
-
.command("
|
|
86
|
-
.description("
|
|
87
|
-
.
|
|
88
|
-
.
|
|
21
|
+
.command("scan")
|
|
22
|
+
.description("scan for *.cddl files")
|
|
23
|
+
.option("-p, --path <PATH>", "root directory to start scan", cwd)
|
|
24
|
+
.option("-m, --matches <REGEX>", "match expression", ".*cddl$")
|
|
25
|
+
.option("-i, --ignores <REGEX>", "ignore directories", ignore)
|
|
26
|
+
.action(seedle.scan);
|
|
89
27
|
|
|
28
|
+
// Build command
|
|
90
29
|
program
|
|
91
|
-
.command("
|
|
92
|
-
.description("
|
|
93
|
-
.
|
|
94
|
-
.action(
|
|
30
|
+
.command("build")
|
|
31
|
+
.description("build atx zdk application")
|
|
32
|
+
.option("-c, --config <CONFIG>", "workspace config file")
|
|
33
|
+
.action(build);
|
|
95
34
|
|
|
96
35
|
try {
|
|
97
36
|
await program.parseAsync();
|
|
98
37
|
} catch (e) {
|
|
99
|
-
|
|
38
|
+
console.error(e);
|
|
100
39
|
}
|
|
101
40
|
})();
|
package/src/seedle.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import dotenv from "dotenv";
|
|
5
|
+
|
|
6
|
+
export async function scan(this: Command) {
|
|
7
|
+
// parse matches
|
|
8
|
+
const matches = this.opts()
|
|
9
|
+
.matches.split(";")
|
|
10
|
+
.map((s: string) => new RegExp(s, "g"));
|
|
11
|
+
|
|
12
|
+
// parse ignores
|
|
13
|
+
const ignores = this.opts()
|
|
14
|
+
.ignores.split(";")
|
|
15
|
+
.map((s: string) => new RegExp(s, "g"));
|
|
16
|
+
|
|
17
|
+
// parse start directory and load env.
|
|
18
|
+
const start = this.opts().path;
|
|
19
|
+
const env = path.join(start, ".env");
|
|
20
|
+
dotenv.config({ path: env });
|
|
21
|
+
|
|
22
|
+
// Log out matches
|
|
23
|
+
for await (const f of walk(start, matches, ignores)) {
|
|
24
|
+
console.log(f);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function* walk(dir: string, matches: RegExp[], ignores: RegExp[]) {
|
|
29
|
+
for await (const d of await fs.promises.opendir(dir)) {
|
|
30
|
+
const entry = path.join(dir, d.name);
|
|
31
|
+
if (d.isDirectory()) {
|
|
32
|
+
const i = ignores.map((i) => entry.match(i)).filter((r) => r);
|
|
33
|
+
if (i.length == 0) yield* await walk(entry, matches, ignores);
|
|
34
|
+
} else if (d.isFile()) {
|
|
35
|
+
const m = matches.map((m) => entry.match(m)).filter((r) => r);
|
|
36
|
+
if (m.length > 0) yield entry;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|