@openfn/cli 0.0.26 → 0.0.28
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/README.md +37 -1
- package/dist/index.js +12 -2
- package/dist/process/runner.js +188 -61
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -50,7 +50,9 @@ If output.json and state.json are not passed, the CLI will look for them next to
|
|
|
50
50
|
|
|
51
51
|
The CLI can auto-install language adaptors to its own privately maintained repo. Run `openfn repo list` to see where the repo is, and what's in it. Set the `OPENFN_REPO_DIR` env var to specify the repo folder. When autoinstalling, the CLI will check to see if a matching version is found in the repo.
|
|
52
52
|
|
|
53
|
-
You can specify adaptors with a shorthand (`http`) or use the full package name (`@openfn/language-http`). You can add a specific version like `http@2.0.0`. You can pass a path to a locally installed adaptor like `http=/repo/openfn/adaptors/my-http-build`.
|
|
53
|
+
You can specify adaptors with a shorthand (`http`) or use the full package name (`@openfn/language-http`). You can add a specific version like `http@2.0.0`. You can pass a path to a locally installed adaptor like `http=/repo/openfn/adaptors/my-http-build`.
|
|
54
|
+
|
|
55
|
+
If you have the adaptors monorepo set up on your machine, you can also run from that. Pass the `-m` flag to load from the monorepo. Set the monorepo location by setting the OPENFN_ADAPTORS_REPO env var to a valid path. This runs from the built package, so remember to build an adaptor before running!
|
|
54
56
|
|
|
55
57
|
You can pass `--log info` to get more feedback about what's happening, or `--log debug` for more details than you could ever use.
|
|
56
58
|
|
|
@@ -68,6 +70,40 @@ If no command is specified, execute will run.
|
|
|
68
70
|
|
|
69
71
|
To get more information about a command, including usage examples, run `openfn <command> help`, ie, `openfn compile help`.
|
|
70
72
|
|
|
73
|
+
## Logging
|
|
74
|
+
|
|
75
|
+
The CLI is actually a collection of packages, each of which will log with slightly different rules. To help understand where logs are coming from, each package prints a namespace or prefix at the start of its log.
|
|
76
|
+
|
|
77
|
+
* [CLI] - the CLI itself, responsible for parsing and validating user input, reading and writing to disk, and executing the correct functionality.
|
|
78
|
+
* [CMP] - the Compiler will parse openfn jobs into executable Javascript, changing your code
|
|
79
|
+
* [R/T] - the Runtime executes your job code in a secure sandboxed environment, one operation at a time
|
|
80
|
+
* [JOB] - the actual job code that your wrote. Any console.log statements in your job will appear under this namespace.
|
|
81
|
+
|
|
82
|
+
The CLI will log information at three different levels of verbosity: `default`, `info` and `debug` (`none` is also supported).
|
|
83
|
+
|
|
84
|
+
To set the log level, pass `--log info` into your command. You can configure this for individual packages, ie `--log cmp=debug` will run the compiler with debug logging but leave everything else at default.
|
|
85
|
+
|
|
86
|
+
Note that, unless explicitly overriden, jobs will always report at debug verbosity (meaning job logging will always be shown).
|
|
87
|
+
|
|
88
|
+
If something unexpected happens during a command, your first step should be to re-run with info-level logging.
|
|
89
|
+
|
|
90
|
+
`default` logging is designed to give high-level feedback about what you absolutely need to know. It will show any errors or warnings, as well as high-level reporting about what the command has actually done.
|
|
91
|
+
|
|
92
|
+
`info` level logging is suitable for most developers. It is more verbose than default but still aims to provide high-level information about a command. It includes version numbers, key paths, and simple reporting about how the compiler changes your code (see below).
|
|
93
|
+
|
|
94
|
+
`debug` level logging is highly verbose and aims to tell you everything that's going on under-the hood. This is aimed mostly at CLI/runtime developers and can be very useful for debugging problems.
|
|
95
|
+
|
|
96
|
+
## Structred/JSON logging
|
|
97
|
+
|
|
98
|
+
By default all logs will be printed as human-readable strings.
|
|
99
|
+
|
|
100
|
+
For a more structured output, you can emit logs as JSON objects with `level`, `name` and `message` properties:
|
|
101
|
+
```
|
|
102
|
+
{ level: 'info', name: 'CLI', message: ['Loaded adaptor'] }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Pass `--log-json` to the CLI to do this. You can also set the OPENFN_LOG_JSON env var (and use `--no-log-json` to disable).
|
|
106
|
+
|
|
71
107
|
## Compilation
|
|
72
108
|
|
|
73
109
|
The CLI will attempt to compile your job code into normalized Javascript. It will do a number of things to make your code robust and portable:
|
package/dist/index.js
CHANGED
|
@@ -95,6 +95,10 @@ var executeCommand = {
|
|
|
95
95
|
return applyExecuteOptions(yargs2).option("immutable", {
|
|
96
96
|
boolean: true,
|
|
97
97
|
description: "Treat state as immutable"
|
|
98
|
+
}).option("use-adaptors-monorepo", {
|
|
99
|
+
alias: "m",
|
|
100
|
+
boolean: true,
|
|
101
|
+
description: "Load adaptors from the monorepo. The OPENFN_ADAPTORS_REPO env var must be set to a valid path"
|
|
98
102
|
}).option("autoinstall", {
|
|
99
103
|
alias: "i",
|
|
100
104
|
boolean: true,
|
|
@@ -105,6 +109,9 @@ var executeCommand = {
|
|
|
105
109
|
}).option("state-stdin", {
|
|
106
110
|
alias: "S",
|
|
107
111
|
description: "Read state from stdin (instead of a file)"
|
|
112
|
+
}).option("skip-adaptor-validation", {
|
|
113
|
+
boolean: true,
|
|
114
|
+
description: "Skip adaptor validation warnings"
|
|
108
115
|
}).option("timeout", {
|
|
109
116
|
alias: "-t",
|
|
110
117
|
description: "Set the timeout duration in MS"
|
|
@@ -113,7 +120,7 @@ var executeCommand = {
|
|
|
113
120
|
description: "Skip compilation"
|
|
114
121
|
}).option("no-strict-output", {
|
|
115
122
|
boolean: true,
|
|
116
|
-
description: "Allow properties other than data to be returned in the output
|
|
123
|
+
description: "Allow properties other than data to be returned in the output"
|
|
117
124
|
}).example(
|
|
118
125
|
"openfn foo/job.js",
|
|
119
126
|
"Reads foo/job.js, looks for state and output in foo"
|
|
@@ -138,7 +145,7 @@ var applyExecuteOptions = (yargs2) => yargs2.positional("path", {
|
|
|
138
145
|
description: "Print output to stdout (instead of a file)"
|
|
139
146
|
}).option("adaptors", {
|
|
140
147
|
alias: ["a", "adaptor"],
|
|
141
|
-
description: "A language adaptor to use for the job. Short-form names are allowed. Can include an explicit path to a local adaptor build
|
|
148
|
+
description: "A language adaptor to use for the job. Short-form names are allowed. Can include an explicit path to a local adaptor build",
|
|
142
149
|
array: true
|
|
143
150
|
}).option("no-expand", {
|
|
144
151
|
description: "Don attempt to auto-expand adaptor shorthand names",
|
|
@@ -206,6 +213,9 @@ var cmd = yargs(hideBin(process.argv)).command(command_default).command(command_
|
|
|
206
213
|
alias: ["l"],
|
|
207
214
|
description: "Set the default log level to none, default, info or debug",
|
|
208
215
|
array: true
|
|
216
|
+
}).option("log-json", {
|
|
217
|
+
description: "Output all logs as JSON objects",
|
|
218
|
+
boolean: true
|
|
209
219
|
}).example("openfn execute help", "Show documentation for the execute command").example(
|
|
210
220
|
"openfn docs @openfn/language-common each",
|
|
211
221
|
"Get more help on the common.each command"
|
package/dist/process/runner.js
CHANGED
|
@@ -12,8 +12,11 @@ var namespaces = {
|
|
|
12
12
|
[JOB]: "JOB"
|
|
13
13
|
};
|
|
14
14
|
var createLogger = (name = "", options) => {
|
|
15
|
-
const logOptions = options.log || {};
|
|
15
|
+
const logOptions = options.log || { json: true };
|
|
16
16
|
let level = logOptions[name] || logOptions.default || "default";
|
|
17
|
+
if (options.logJson) {
|
|
18
|
+
logOptions.json = true;
|
|
19
|
+
}
|
|
17
20
|
return actualCreateLogger(namespaces[name] || name, {
|
|
18
21
|
level,
|
|
19
22
|
...logOptions
|
|
@@ -78,22 +81,27 @@ function ensureOpts(basePath = ".", opts) {
|
|
|
78
81
|
adaptors: opts.adaptors || [],
|
|
79
82
|
autoinstall: opts.autoinstall,
|
|
80
83
|
command: opts.command,
|
|
84
|
+
expand: opts.expand !== false,
|
|
81
85
|
force: opts.force || false,
|
|
82
|
-
|
|
86
|
+
immutable: opts.immutable || false,
|
|
87
|
+
logJson: typeof opts.logJson == "boolean" ? opts.logJson : Boolean(process.env.OPENFN_LOG_JSON),
|
|
83
88
|
noCompile: Boolean(opts.noCompile),
|
|
84
|
-
expand: opts.expand !== false,
|
|
85
|
-
outputStdout: Boolean(opts.outputStdout),
|
|
86
89
|
operation: opts.operation,
|
|
90
|
+
outputStdout: Boolean(opts.outputStdout),
|
|
87
91
|
packages: opts.packages,
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
repoDir: opts.repoDir || process.env.OPENFN_REPO_DIR || DEFAULT_REPO_DIR,
|
|
93
|
+
skipAdaptorValidation: opts.skipAdaptorValidation ?? false,
|
|
90
94
|
specifier: opts.specifier,
|
|
95
|
+
stateStdin: opts.stateStdin,
|
|
91
96
|
strictOutput: opts.strictOutput ?? true,
|
|
92
|
-
|
|
97
|
+
timeout: opts.timeout
|
|
93
98
|
};
|
|
94
99
|
const set = (key, value) => {
|
|
95
100
|
newOpts[key] = opts.hasOwnProperty(key) ? opts[key] : value;
|
|
96
101
|
};
|
|
102
|
+
if (opts.useAdaptorsMonorepo) {
|
|
103
|
+
newOpts.monorepoPath = process.env.OPENFN_ADAPTORS_REPO || "ERR";
|
|
104
|
+
}
|
|
97
105
|
let baseDir = basePath;
|
|
98
106
|
if (basePath.endsWith(".js")) {
|
|
99
107
|
baseDir = path.dirname(basePath);
|
|
@@ -163,11 +171,11 @@ var execute_default = (code, state, opts) => {
|
|
|
163
171
|
function parseAdaptors(opts) {
|
|
164
172
|
const adaptors = {};
|
|
165
173
|
opts.adaptors.reduce((obj, exp) => {
|
|
166
|
-
const [module,
|
|
174
|
+
const [module, path4] = exp.split("=");
|
|
167
175
|
const { name, version } = getNameAndVersion(module);
|
|
168
176
|
const info = {};
|
|
169
|
-
if (
|
|
170
|
-
info.path =
|
|
177
|
+
if (path4) {
|
|
178
|
+
info.path = path4;
|
|
171
179
|
}
|
|
172
180
|
if (version) {
|
|
173
181
|
info.version = version;
|
|
@@ -209,10 +217,10 @@ var stripVersionSpecifier = (specifier) => {
|
|
|
209
217
|
return specifier;
|
|
210
218
|
};
|
|
211
219
|
var resolveSpecifierPath = async (pattern, repoDir, log) => {
|
|
212
|
-
const [specifier,
|
|
213
|
-
if (
|
|
214
|
-
log.debug(`Resolved ${specifier} to path: ${
|
|
215
|
-
return
|
|
220
|
+
const [specifier, path4] = pattern.split("=");
|
|
221
|
+
if (path4) {
|
|
222
|
+
log.debug(`Resolved ${specifier} to path: ${path4}`);
|
|
223
|
+
return path4;
|
|
216
224
|
}
|
|
217
225
|
const repoPath = await getModulePath(specifier, repoDir, log);
|
|
218
226
|
if (repoPath) {
|
|
@@ -229,15 +237,15 @@ var loadTransformOptions = async (opts, log) => {
|
|
|
229
237
|
const [pattern] = opts.adaptors;
|
|
230
238
|
const [specifier] = pattern.split("=");
|
|
231
239
|
log.debug(`Attempting to preload typedefs for ${specifier}`);
|
|
232
|
-
const
|
|
233
|
-
if (
|
|
240
|
+
const path4 = await resolveSpecifierPath(pattern, opts.repoDir, log);
|
|
241
|
+
if (path4) {
|
|
234
242
|
try {
|
|
235
|
-
exports = await preloadAdaptorExports(
|
|
243
|
+
exports = await preloadAdaptorExports(path4);
|
|
236
244
|
if (exports) {
|
|
237
245
|
log.info(`Loaded typedefs for ${specifier}`);
|
|
238
246
|
}
|
|
239
247
|
} catch (e) {
|
|
240
|
-
log.error(`Failed to load adaptor typedefs from path ${
|
|
248
|
+
log.error(`Failed to load adaptor typedefs from path ${path4}`);
|
|
241
249
|
log.error(e);
|
|
242
250
|
}
|
|
243
251
|
}
|
|
@@ -299,7 +307,7 @@ var expand_adaptors_default = (names, log = nullLogger) => names?.map((name) =>
|
|
|
299
307
|
return name;
|
|
300
308
|
}
|
|
301
309
|
const expanded = `@openfn/language-${name}`;
|
|
302
|
-
log.
|
|
310
|
+
log.debug(`Expanded adaptor ${name} to ${expanded}`);
|
|
303
311
|
return expanded;
|
|
304
312
|
});
|
|
305
313
|
|
|
@@ -370,20 +378,44 @@ var list = async (options, logger) => {
|
|
|
370
378
|
logger.success("Installed packages:\n\n" + treeify.asTree(output));
|
|
371
379
|
};
|
|
372
380
|
|
|
381
|
+
// src/util/validate-adaptors.ts
|
|
382
|
+
var validateAdaptors = async (options, logger) => {
|
|
383
|
+
if (options.skipAdaptorValidation) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (!options.adaptors || options.adaptors.length === 0) {
|
|
387
|
+
logger.warn("WARNING: No adaptor provided!");
|
|
388
|
+
logger.warn(
|
|
389
|
+
"This job will probably fail. Pass an adaptor with the -a flag, eg:"
|
|
390
|
+
);
|
|
391
|
+
logger.break();
|
|
392
|
+
logger.print(" openfn job.js -a common");
|
|
393
|
+
logger.break();
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
var validate_adaptors_default = validateAdaptors;
|
|
397
|
+
|
|
373
398
|
// src/execute/handler.ts
|
|
374
399
|
var getAutoinstallTargets = (options) => {
|
|
375
|
-
if (options.
|
|
400
|
+
if (options.adaptors) {
|
|
376
401
|
return options.adaptors?.filter((a) => !/=/.test(a));
|
|
377
402
|
}
|
|
378
403
|
return [];
|
|
379
404
|
};
|
|
380
405
|
var executeHandler = async (options, logger) => {
|
|
381
406
|
const start = new Date().getTime();
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
407
|
+
await validate_adaptors_default(options, logger);
|
|
408
|
+
const { repoDir, monorepoPath, autoinstall } = options;
|
|
409
|
+
if (autoinstall) {
|
|
410
|
+
if (monorepoPath) {
|
|
411
|
+
logger.warn("Skipping auto-install as monorepo is being used");
|
|
412
|
+
} else {
|
|
413
|
+
const autoInstallTargets = getAutoinstallTargets(options);
|
|
414
|
+
if (autoInstallTargets.length) {
|
|
415
|
+
logger.info("Auto-installing language adaptors");
|
|
416
|
+
await install({ packages: autoInstallTargets, repoDir }, logger);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
387
419
|
}
|
|
388
420
|
const state = await load_state_default(options, logger);
|
|
389
421
|
const code = await compile_default(options, logger);
|
|
@@ -447,20 +479,20 @@ var RETRY_COUNT = 20;
|
|
|
447
479
|
var TIMEOUT_MS = 1e3 * 60;
|
|
448
480
|
var actualDocGen = (specifier) => describePackage(specifier, {});
|
|
449
481
|
var ensurePath = (filePath) => mkdirSync(path2.dirname(filePath), { recursive: true });
|
|
450
|
-
var generatePlaceholder = (
|
|
451
|
-
writeFileSync(
|
|
482
|
+
var generatePlaceholder = (path4) => {
|
|
483
|
+
writeFileSync(path4, `{ "loading": true, "timestamp": ${Date.now()}}`);
|
|
452
484
|
};
|
|
453
485
|
var finish = (logger, resultPath) => {
|
|
454
486
|
logger.success("Done! Docs can be found at:\n");
|
|
455
487
|
logger.print(` ${path2.resolve(resultPath)}`);
|
|
456
488
|
};
|
|
457
|
-
var generateDocs = async (specifier,
|
|
489
|
+
var generateDocs = async (specifier, path4, docgen, logger) => {
|
|
458
490
|
const result = await docgen(specifier);
|
|
459
|
-
await writeFile3(
|
|
460
|
-
finish(logger,
|
|
461
|
-
return
|
|
491
|
+
await writeFile3(path4, JSON.stringify(result, null, 2));
|
|
492
|
+
finish(logger, path4);
|
|
493
|
+
return path4;
|
|
462
494
|
};
|
|
463
|
-
var waitForDocs = async (docs,
|
|
495
|
+
var waitForDocs = async (docs, path4, logger, retryDuration = RETRY_DURATION) => {
|
|
464
496
|
try {
|
|
465
497
|
if (docs.hasOwnProperty("loading")) {
|
|
466
498
|
logger.info("Docs are being loaded by another process. Waiting.");
|
|
@@ -472,19 +504,19 @@ var waitForDocs = async (docs, path3, logger, retryDuration = RETRY_DURATION) =>
|
|
|
472
504
|
clearInterval(i);
|
|
473
505
|
reject(new Error("Timed out waiting for docs to load"));
|
|
474
506
|
}
|
|
475
|
-
const updated = JSON.parse(readFileSync(
|
|
507
|
+
const updated = JSON.parse(readFileSync(path4, "utf8"));
|
|
476
508
|
if (!updated.hasOwnProperty("loading")) {
|
|
477
509
|
logger.info("Docs found!");
|
|
478
510
|
clearInterval(i);
|
|
479
|
-
resolve(
|
|
511
|
+
resolve(path4);
|
|
480
512
|
}
|
|
481
513
|
count++;
|
|
482
514
|
}, retryDuration);
|
|
483
515
|
});
|
|
484
516
|
} else {
|
|
485
|
-
logger.info(`Docs already written to cache at ${
|
|
486
|
-
finish(logger,
|
|
487
|
-
return
|
|
517
|
+
logger.info(`Docs already written to cache at ${path4}`);
|
|
518
|
+
finish(logger, path4);
|
|
519
|
+
return path4;
|
|
488
520
|
}
|
|
489
521
|
} catch (e) {
|
|
490
522
|
logger.error("Existing doc JSON corrupt. Aborting");
|
|
@@ -501,28 +533,28 @@ var docgenHandler = (options, logger, docgen = actualDocGen, retryDuration = RET
|
|
|
501
533
|
process.exit(9);
|
|
502
534
|
}
|
|
503
535
|
logger.success(`Generating docs for ${specifier}`);
|
|
504
|
-
const
|
|
505
|
-
ensurePath(
|
|
536
|
+
const path4 = `${repoDir}/docs/${specifier}.json`;
|
|
537
|
+
ensurePath(path4);
|
|
506
538
|
const handleError = () => {
|
|
507
539
|
logger.info("Removing placeholder");
|
|
508
|
-
rmSync(
|
|
540
|
+
rmSync(path4);
|
|
509
541
|
};
|
|
510
542
|
try {
|
|
511
|
-
const existing = readFileSync(
|
|
543
|
+
const existing = readFileSync(path4, "utf8");
|
|
512
544
|
const json = JSON.parse(existing);
|
|
513
545
|
if (json && json.timeout && Date.now() - json.timeout >= TIMEOUT_MS) {
|
|
514
546
|
logger.info(`Expired placeholder found. Removing.`);
|
|
515
|
-
rmSync(
|
|
547
|
+
rmSync(path4);
|
|
516
548
|
throw new Error("TIMEOUT");
|
|
517
549
|
}
|
|
518
|
-
return waitForDocs(json,
|
|
550
|
+
return waitForDocs(json, path4, logger, retryDuration);
|
|
519
551
|
} catch (e) {
|
|
520
552
|
if (e.message !== "TIMEOUT") {
|
|
521
|
-
logger.info(`Docs JSON not found at ${
|
|
553
|
+
logger.info(`Docs JSON not found at ${path4}`);
|
|
522
554
|
}
|
|
523
555
|
logger.debug("Generating placeholder");
|
|
524
|
-
generatePlaceholder(
|
|
525
|
-
return generateDocs(specifier,
|
|
556
|
+
generatePlaceholder(path4);
|
|
557
|
+
return generateDocs(specifier, path4, docgen, logger).catch((e2) => {
|
|
526
558
|
logger.error("Error generating documentation");
|
|
527
559
|
logger.error(e2);
|
|
528
560
|
handleError();
|
|
@@ -570,15 +602,15 @@ var docsHandler = async (options, logger) => {
|
|
|
570
602
|
logger.success(`Showing docs for ${adaptorName} v${version}`);
|
|
571
603
|
}
|
|
572
604
|
logger.info("Generating/loading documentation...");
|
|
573
|
-
const
|
|
605
|
+
const path4 = await handler_default4(
|
|
574
606
|
{
|
|
575
607
|
specifier: `${name}@${version}`,
|
|
576
608
|
repoDir
|
|
577
609
|
},
|
|
578
610
|
createNullLogger()
|
|
579
611
|
);
|
|
580
|
-
if (
|
|
581
|
-
const source = await readFile(
|
|
612
|
+
if (path4) {
|
|
613
|
+
const source = await readFile(path4, "utf8");
|
|
582
614
|
const data = JSON.parse(source);
|
|
583
615
|
let desc;
|
|
584
616
|
if (operation) {
|
|
@@ -599,19 +631,91 @@ var docsHandler = async (options, logger) => {
|
|
|
599
631
|
};
|
|
600
632
|
var handler_default5 = docsHandler;
|
|
601
633
|
|
|
634
|
+
// src/util/use-adaptors-repo.ts
|
|
635
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
636
|
+
import path3 from "node:path";
|
|
637
|
+
import assert from "node:assert";
|
|
638
|
+
import { getNameAndVersion as getNameAndVersion4 } from "@openfn/runtime";
|
|
639
|
+
var validateMonoRepo = async (repoPath, log) => {
|
|
640
|
+
try {
|
|
641
|
+
const raw = await readFile2(`${repoPath}/package.json`, "utf8");
|
|
642
|
+
const pkg = JSON.parse(raw);
|
|
643
|
+
assert(pkg.name === "adaptors");
|
|
644
|
+
} catch (e) {
|
|
645
|
+
log.error(`ERROR: Adaptors Monorepo not found at ${repoPath}`);
|
|
646
|
+
process.exit(9);
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
var updatePath = (adaptor, repoPath, log) => {
|
|
650
|
+
if (adaptor.match("=")) {
|
|
651
|
+
return adaptor;
|
|
652
|
+
}
|
|
653
|
+
const { name, version } = getNameAndVersion4(adaptor);
|
|
654
|
+
if (version) {
|
|
655
|
+
log.warn(
|
|
656
|
+
`Warning: Ignoring version specifier on ${adaptor} as loading from the adaptors monorepo`
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
const shortName = name.replace("@openfn/language-", "");
|
|
660
|
+
const abspath = path3.resolve(repoPath, "packages", shortName);
|
|
661
|
+
return `${name}=${abspath}`;
|
|
662
|
+
};
|
|
663
|
+
var useAdaptorsRepo = async (adaptors, repoPath, log) => {
|
|
664
|
+
await validateMonoRepo(repoPath, log);
|
|
665
|
+
log.success(`Loading adaptors from monorepo at ${repoPath}`);
|
|
666
|
+
const updatedAdaptors = adaptors.map((a) => {
|
|
667
|
+
const p = updatePath(a, repoPath, log);
|
|
668
|
+
log.info(`Mapped adaptor ${a} to monorepo: ${p.split("=")[1]}`);
|
|
669
|
+
return p;
|
|
670
|
+
});
|
|
671
|
+
return updatedAdaptors;
|
|
672
|
+
};
|
|
673
|
+
var use_adaptors_repo_default = useAdaptorsRepo;
|
|
674
|
+
|
|
602
675
|
// src/util/print-versions.ts
|
|
603
676
|
import { mainSymbols } from "figures";
|
|
677
|
+
import { getNameAndVersion as getNameAndVersion5 } from "@openfn/runtime";
|
|
604
678
|
var { triangleRightSmall: t } = mainSymbols;
|
|
605
|
-
var printVersions = async (logger) => {
|
|
679
|
+
var printVersions = async (logger, options = {}) => {
|
|
680
|
+
const prefix = (str) => ` ${t} ${str.padEnd(options.adaptors ? 16 : 8, " ")}`;
|
|
606
681
|
const pkg = await import("../../package.json", { assert: { type: "json" } });
|
|
607
682
|
const { version, dependencies } = pkg.default;
|
|
608
683
|
const compilerVersion = dependencies["@openfn/compiler"];
|
|
609
684
|
const runtimeVersion = dependencies["@openfn/runtime"];
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
685
|
+
const { adaptors } = options;
|
|
686
|
+
let adaptorName, adaptorVersion;
|
|
687
|
+
if (adaptors && adaptors.length === 1) {
|
|
688
|
+
const [a] = adaptors;
|
|
689
|
+
const { name, version: version2 } = getNameAndVersion5(a);
|
|
690
|
+
adaptorName = name.replace(/^@openfn\/language-/, "");
|
|
691
|
+
adaptorVersion = version2 || "latest";
|
|
692
|
+
}
|
|
693
|
+
let output;
|
|
694
|
+
if (options.logJson) {
|
|
695
|
+
output = {
|
|
696
|
+
versions: {
|
|
697
|
+
"node.js": process.version.substring(1),
|
|
698
|
+
cli: version,
|
|
699
|
+
runtime: runtimeVersion,
|
|
700
|
+
compiler: compilerVersion
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
if (adaptorName) {
|
|
704
|
+
output.versions.adaptor = {
|
|
705
|
+
name: adaptorName,
|
|
706
|
+
version: adaptorVersion
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
} else {
|
|
710
|
+
const adaptorVersionString = adaptorName ? `
|
|
711
|
+
${prefix("adaptor " + adaptorName)}${adaptorVersion}` : "";
|
|
712
|
+
output = `Versions:
|
|
713
|
+
${prefix("node.js")}${process.version.substring(1)}
|
|
714
|
+
${prefix("cli")}${version}
|
|
715
|
+
${prefix("runtime")}${runtimeVersion}
|
|
716
|
+
${prefix("compiler")}${compilerVersion}${adaptorVersionString}`;
|
|
717
|
+
}
|
|
718
|
+
logger.info(output);
|
|
615
719
|
};
|
|
616
720
|
var print_versions_default = printVersions;
|
|
617
721
|
|
|
@@ -626,15 +730,28 @@ var handlers = {
|
|
|
626
730
|
["repo-install"]: install,
|
|
627
731
|
["repo-pwd"]: pwd,
|
|
628
732
|
["repo-list"]: list,
|
|
629
|
-
version: async (
|
|
733
|
+
version: async (opts, logger) => print_versions_default(logger, opts)
|
|
630
734
|
};
|
|
631
735
|
var parse = async (basePath, options, log) => {
|
|
632
736
|
const opts = ensureOpts(basePath, options);
|
|
633
737
|
const logger = log || logger_default(CLI, opts);
|
|
634
738
|
if (opts.command === "execute" || opts.command === "test") {
|
|
635
|
-
await print_versions_default(logger);
|
|
636
|
-
}
|
|
637
|
-
if (opts.
|
|
739
|
+
await print_versions_default(logger, opts);
|
|
740
|
+
}
|
|
741
|
+
if (opts.monorepoPath) {
|
|
742
|
+
if (opts.monorepoPath === "ERR") {
|
|
743
|
+
logger.error(
|
|
744
|
+
"ERROR: --use-adaptors-monorepo was passed, but OPENFN_ADAPTORS_REPO env var is undefined"
|
|
745
|
+
);
|
|
746
|
+
logger.error("Set OPENFN_ADAPTORS_REPO to a path pointing to the repo");
|
|
747
|
+
process.exit(9);
|
|
748
|
+
}
|
|
749
|
+
opts.adaptors = await use_adaptors_repo_default(
|
|
750
|
+
opts.adaptors,
|
|
751
|
+
opts.monorepoPath,
|
|
752
|
+
logger
|
|
753
|
+
);
|
|
754
|
+
} else if (opts.adaptors && opts.expand) {
|
|
638
755
|
opts.adaptors = expand_adaptors_default(opts.adaptors, logger);
|
|
639
756
|
}
|
|
640
757
|
if (/^(test|version)$/.test(opts.command) && !opts.repoDir) {
|
|
@@ -650,10 +767,20 @@ var parse = async (basePath, options, log) => {
|
|
|
650
767
|
assertPath(basePath);
|
|
651
768
|
}
|
|
652
769
|
if (!handler) {
|
|
653
|
-
logger.error(`
|
|
770
|
+
logger.error(`Unrecognised command: ${options.command}`);
|
|
654
771
|
process.exit(1);
|
|
655
772
|
}
|
|
656
|
-
|
|
773
|
+
try {
|
|
774
|
+
const result = await handler(opts, logger);
|
|
775
|
+
return result;
|
|
776
|
+
} catch (e) {
|
|
777
|
+
if (!process.exitCode) {
|
|
778
|
+
process.exitCode = e.exitCode || 1;
|
|
779
|
+
}
|
|
780
|
+
logger.break();
|
|
781
|
+
logger.error("Command failed!");
|
|
782
|
+
logger.error(e);
|
|
783
|
+
}
|
|
657
784
|
};
|
|
658
785
|
var commands_default = parse;
|
|
659
786
|
var assertPath = (basePath) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"description": "CLI devtools for the openfn toolchain.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"typescript": "^4.7.4"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@openfn/compiler": "0.0.
|
|
39
|
+
"@openfn/compiler": "0.0.24",
|
|
40
40
|
"@openfn/describe-package": "0.0.14",
|
|
41
|
-
"@openfn/logger": "0.0.
|
|
42
|
-
"@openfn/runtime": "0.0.
|
|
41
|
+
"@openfn/logger": "0.0.9",
|
|
42
|
+
"@openfn/runtime": "0.0.18",
|
|
43
43
|
"fast-safe-stringify": "^2.1.1",
|
|
44
44
|
"figures": "^5.0.0",
|
|
45
45
|
"rimraf": "^3.0.2",
|