@galaxy-tool-util/cli 0.1.0 → 0.2.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/LICENSE +21 -0
- package/dist/bin/galaxy-tool-cache.js +15 -0
- package/dist/bin/galaxy-tool-cache.js.map +1 -1
- package/dist/bin/gxwf.d.ts +3 -0
- package/dist/bin/gxwf.d.ts.map +1 -0
- package/dist/bin/gxwf.js +126 -0
- package/dist/bin/gxwf.js.map +1 -0
- package/dist/commands/clean-tree.d.ts +23 -0
- package/dist/commands/clean-tree.d.ts.map +1 -0
- package/dist/commands/clean-tree.js +68 -0
- package/dist/commands/clean-tree.js.map +1 -0
- package/dist/commands/clean.d.ts +7 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +38 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/convert-tree.d.ts +31 -0
- package/dist/commands/convert-tree.d.ts.map +1 -0
- package/dist/commands/convert-tree.js +213 -0
- package/dist/commands/convert-tree.js.map +1 -0
- package/dist/commands/convert.d.ts +12 -0
- package/dist/commands/convert.d.ts.map +1 -0
- package/dist/commands/convert.js +119 -0
- package/dist/commands/convert.js.map +1 -0
- package/dist/commands/lint-tree.d.ts +27 -0
- package/dist/commands/lint-tree.d.ts.map +1 -0
- package/dist/commands/lint-tree.js +116 -0
- package/dist/commands/lint-tree.js.map +1 -0
- package/dist/commands/lint.d.ts +30 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +147 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/populate-workflow.d.ts +6 -0
- package/dist/commands/populate-workflow.d.ts.map +1 -0
- package/dist/commands/populate-workflow.js +55 -0
- package/dist/commands/populate-workflow.js.map +1 -0
- package/dist/commands/render-results.d.ts +11 -0
- package/dist/commands/render-results.d.ts.map +1 -0
- package/dist/commands/render-results.js +23 -0
- package/dist/commands/render-results.js.map +1 -0
- package/dist/commands/roundtrip-tree.d.ts +13 -0
- package/dist/commands/roundtrip-tree.d.ts.map +1 -0
- package/dist/commands/roundtrip-tree.js +116 -0
- package/dist/commands/roundtrip-tree.js.map +1 -0
- package/dist/commands/roundtrip.d.ts +30 -0
- package/dist/commands/roundtrip.d.ts.map +1 -0
- package/dist/commands/roundtrip.js +122 -0
- package/dist/commands/roundtrip.js.map +1 -0
- package/dist/commands/stateful-tool-inputs.d.ts +33 -0
- package/dist/commands/stateful-tool-inputs.d.ts.map +1 -0
- package/dist/commands/stateful-tool-inputs.js +73 -0
- package/dist/commands/stateful-tool-inputs.js.map +1 -0
- package/dist/commands/structural-schema.d.ts +6 -0
- package/dist/commands/structural-schema.d.ts.map +1 -0
- package/dist/commands/structural-schema.js +31 -0
- package/dist/commands/structural-schema.js.map +1 -0
- package/dist/commands/tree.d.ts +45 -0
- package/dist/commands/tree.d.ts.map +1 -0
- package/dist/commands/tree.js +155 -0
- package/dist/commands/tree.js.map +1 -0
- package/dist/commands/validate-tree.d.ts +29 -0
- package/dist/commands/validate-tree.d.ts.map +1 -0
- package/dist/commands/validate-tree.js +118 -0
- package/dist/commands/validate-tree.js.map +1 -0
- package/dist/commands/validate-workflow-json-schema.d.ts.map +1 -1
- package/dist/commands/validate-workflow-json-schema.js +49 -16
- package/dist/commands/validate-workflow-json-schema.js.map +1 -1
- package/dist/commands/validate-workflow.d.ts +1 -0
- package/dist/commands/validate-workflow.d.ts.map +1 -1
- package/dist/commands/validate-workflow.js +57 -56
- package/dist/commands/validate-workflow.js.map +1 -1
- package/dist/commands/workflow-io.d.ts +16 -0
- package/dist/commands/workflow-io.d.ts.map +1 -0
- package/dist/commands/workflow-io.js +47 -0
- package/dist/commands/workflow-io.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
- package/dist/bin/galaxy-workflow-validate.d.ts +0 -3
- package/dist/bin/galaxy-workflow-validate.d.ts.map +0 -1
- package/dist/bin/galaxy-workflow-validate.js +0 -17
- package/dist/bin/galaxy-workflow-validate.js.map +0 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `gxwf roundtrip-tree` — batch roundtrip validation across a directory.
|
|
3
|
+
* Mirrors the patterns in convert-tree.ts.
|
|
4
|
+
*/
|
|
5
|
+
import { ToolCache } from "@galaxy-tool-util/core";
|
|
6
|
+
import { roundtripValidate, } from "@galaxy-tool-util/schema";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
8
|
+
import { loadToolInputsForWorkflow } from "./stateful-tool-inputs.js";
|
|
9
|
+
import { createDefaultResolver } from "./url-resolver.js";
|
|
10
|
+
import { resolveFormat } from "./workflow-io.js";
|
|
11
|
+
import { collectTree, skipWorkflow } from "./tree.js";
|
|
12
|
+
import { countDiffs } from "./roundtrip.js";
|
|
13
|
+
export async function runRoundtripTree(dir, opts) {
|
|
14
|
+
const cache = new ToolCache({ cacheDir: opts.cacheDir });
|
|
15
|
+
await cache.index.load();
|
|
16
|
+
if (cache.index.listAll().length === 0) {
|
|
17
|
+
console.warn("Tool cache is empty — all steps will fall back (no roundtrip possible)");
|
|
18
|
+
}
|
|
19
|
+
// Only native workflows are eligible; format2 files are skipped.
|
|
20
|
+
const treeResult = await collectTree(dir, async (info, data) => {
|
|
21
|
+
const sourceFormat = resolveFormat(data, opts.format);
|
|
22
|
+
if (sourceFormat !== "native") {
|
|
23
|
+
skipWorkflow(`not a native workflow (${sourceFormat})`);
|
|
24
|
+
}
|
|
25
|
+
const expansionOpts = {
|
|
26
|
+
resolver: createDefaultResolver({
|
|
27
|
+
workflowDirectory: dirname(join(dir, info.relativePath)),
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
const { resolver, status: toolStatus } = await loadToolInputsForWorkflow(data, "native", cache, expansionOpts);
|
|
31
|
+
const failedLoads = toolStatus.filter((s) => !s.loaded);
|
|
32
|
+
const result = roundtripValidate(data, resolver);
|
|
33
|
+
return {
|
|
34
|
+
relativePath: info.relativePath,
|
|
35
|
+
result,
|
|
36
|
+
toolLoadErrors: failedLoads.length > 0 ? failedLoads : undefined,
|
|
37
|
+
};
|
|
38
|
+
}, false);
|
|
39
|
+
// Aggregate
|
|
40
|
+
let totalBenign = 0;
|
|
41
|
+
let totalErrors = 0;
|
|
42
|
+
let filesClean = 0;
|
|
43
|
+
let filesBenignOnly = 0;
|
|
44
|
+
let filesFailed = 0;
|
|
45
|
+
const fileResults = [];
|
|
46
|
+
for (const o of treeResult.outcomes) {
|
|
47
|
+
if (o.error || o.skipped || !o.result)
|
|
48
|
+
continue;
|
|
49
|
+
fileResults.push(o.result);
|
|
50
|
+
const counts = countDiffs(o.result.result);
|
|
51
|
+
totalBenign += counts.benign;
|
|
52
|
+
totalErrors += counts.error;
|
|
53
|
+
if (!o.result.result.success)
|
|
54
|
+
filesFailed++;
|
|
55
|
+
else if (o.result.result.clean)
|
|
56
|
+
filesClean++;
|
|
57
|
+
else
|
|
58
|
+
filesBenignOnly++;
|
|
59
|
+
}
|
|
60
|
+
if (opts.json) {
|
|
61
|
+
console.log(JSON.stringify({
|
|
62
|
+
root: treeResult.root,
|
|
63
|
+
files: fileResults,
|
|
64
|
+
summary: {
|
|
65
|
+
total: fileResults.length,
|
|
66
|
+
clean: filesClean,
|
|
67
|
+
benignOnly: filesBenignOnly,
|
|
68
|
+
failed: filesFailed,
|
|
69
|
+
benignDiffs: totalBenign,
|
|
70
|
+
errorDiffs: totalErrors,
|
|
71
|
+
},
|
|
72
|
+
}, null, 2));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
if (!opts.brief) {
|
|
76
|
+
for (const o of treeResult.outcomes) {
|
|
77
|
+
if (o.error) {
|
|
78
|
+
// File-level errors always shown unless --benign-only.
|
|
79
|
+
if (!opts.benignOnly) {
|
|
80
|
+
console.error(` ${o.info.relativePath}: ERROR (${o.error})`);
|
|
81
|
+
}
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (o.skipped)
|
|
85
|
+
continue;
|
|
86
|
+
const r = o.result;
|
|
87
|
+
const c = countDiffs(r.result);
|
|
88
|
+
const isFail = !r.result.success;
|
|
89
|
+
const isClean = r.result.clean;
|
|
90
|
+
const isBenign = !isFail && !isClean;
|
|
91
|
+
if (opts.errorsOnly && !isFail)
|
|
92
|
+
continue;
|
|
93
|
+
if (opts.benignOnly && !isBenign)
|
|
94
|
+
continue;
|
|
95
|
+
const status = isFail ? "FAIL" : isClean ? "clean" : "benign";
|
|
96
|
+
console.log(` ${r.relativePath}: ${status} (${c.benign} benign, ${c.error} real diff, ${c.failed} conversion failure)`);
|
|
97
|
+
if (r.toolLoadErrors) {
|
|
98
|
+
for (const t of r.toolLoadErrors) {
|
|
99
|
+
const ver = t.toolVersion ? `@${t.toolVersion}` : "";
|
|
100
|
+
console.error(` tool ${t.toolId}${ver}: ${t.error}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
console.log(`\nSummary: ${fileResults.length} file(s): ${filesClean} clean, ${filesBenignOnly} benign-only, ${filesFailed} failed`);
|
|
106
|
+
console.log(`Diffs: ${totalBenign} benign, ${totalErrors} real`);
|
|
107
|
+
}
|
|
108
|
+
// Exit code: 2 if any failure, 1 if benign-only, 0 if all clean
|
|
109
|
+
if (filesFailed > 0 || totalErrors > 0)
|
|
110
|
+
process.exitCode = 2;
|
|
111
|
+
else if (totalBenign > 0)
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
else
|
|
114
|
+
process.exitCode = 0;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=roundtrip-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roundtrip-tree.js","sourceRoot":"","sources":["../../src/commands/roundtrip-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type RoundtripResult } from "@galaxy-tool-util/schema";
|
|
2
|
+
export interface RoundtripOptions {
|
|
3
|
+
cacheDir?: string;
|
|
4
|
+
format?: string;
|
|
5
|
+
json?: boolean;
|
|
6
|
+
/** Only show steps with error-severity diffs. */
|
|
7
|
+
errorsOnly?: boolean;
|
|
8
|
+
/** Only show steps with benign diffs (suppress clean + real-error steps). */
|
|
9
|
+
benignOnly?: boolean;
|
|
10
|
+
/** Suppress the per-diff list; show only per-step counts and summary. */
|
|
11
|
+
brief?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function runRoundtrip(filePath: string, opts: RoundtripOptions): Promise<void>;
|
|
14
|
+
export interface ReportFilter {
|
|
15
|
+
errorsOnly?: boolean;
|
|
16
|
+
benignOnly?: boolean;
|
|
17
|
+
brief?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Exit code policy: 0 clean, 1 benign-only, 2 real diffs or errors.
|
|
21
|
+
* Exposed for reuse by the tree command.
|
|
22
|
+
*/
|
|
23
|
+
export declare function exitCodeFor(result: RoundtripResult): number;
|
|
24
|
+
/** Count diffs across a result by severity — reused by tree aggregation. */
|
|
25
|
+
export declare function countDiffs(result: RoundtripResult): {
|
|
26
|
+
benign: number;
|
|
27
|
+
error: number;
|
|
28
|
+
failed: number;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=roundtrip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roundtrip.d.ts","sourceRoot":"","sources":["../../src/commands/roundtrip.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C1F;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAmED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAI3D;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,GAAG;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAOA"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `gxwf roundtrip` — roundtrip-validate a native workflow through format2
|
|
3
|
+
* and back, reporting per-step diffs and classifying them as benign or real.
|
|
4
|
+
*
|
|
5
|
+
* Exit codes:
|
|
6
|
+
* 0 clean roundtrip (no diffs)
|
|
7
|
+
* 1 benign diffs only (type coercions, stale keys, connection moves)
|
|
8
|
+
* 2 real diffs or conversion errors
|
|
9
|
+
*/
|
|
10
|
+
import { ToolCache } from "@galaxy-tool-util/core";
|
|
11
|
+
import { roundtripValidate, } from "@galaxy-tool-util/schema";
|
|
12
|
+
import { dirname } from "node:path";
|
|
13
|
+
import { loadToolInputsForWorkflow } from "./stateful-tool-inputs.js";
|
|
14
|
+
import { createDefaultResolver } from "./url-resolver.js";
|
|
15
|
+
import { readWorkflowFile, resolveFormat } from "./workflow-io.js";
|
|
16
|
+
export async function runRoundtrip(filePath, opts) {
|
|
17
|
+
const data = await readWorkflowFile(filePath);
|
|
18
|
+
if (!data)
|
|
19
|
+
return;
|
|
20
|
+
const sourceFormat = resolveFormat(data, opts.format);
|
|
21
|
+
if (sourceFormat !== "native") {
|
|
22
|
+
console.error(`Roundtrip source must be a native (.ga) workflow; got ${sourceFormat}.` +
|
|
23
|
+
` Convert to native first or pass a .ga file.`);
|
|
24
|
+
process.exitCode = 2;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const cache = new ToolCache({ cacheDir: opts.cacheDir });
|
|
28
|
+
await cache.index.load();
|
|
29
|
+
if (cache.index.listAll().length === 0) {
|
|
30
|
+
console.warn("Tool cache is empty — all steps will fall back (no roundtrip possible)");
|
|
31
|
+
}
|
|
32
|
+
const expansionOpts = {
|
|
33
|
+
resolver: createDefaultResolver({ workflowDirectory: dirname(filePath) }),
|
|
34
|
+
};
|
|
35
|
+
const { resolver, status: toolStatus } = await loadToolInputsForWorkflow(data, "native", cache, expansionOpts);
|
|
36
|
+
for (const s of toolStatus) {
|
|
37
|
+
if (!s.loaded) {
|
|
38
|
+
const ver = s.toolVersion ? `@${s.toolVersion}` : "";
|
|
39
|
+
console.error(` tool ${s.toolId}${ver}: ${s.error}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const result = roundtripValidate(data, resolver);
|
|
43
|
+
if (opts.json) {
|
|
44
|
+
console.log(JSON.stringify(result, null, 2));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
reportResult(filePath, result, opts);
|
|
48
|
+
}
|
|
49
|
+
process.exitCode = exitCodeFor(result);
|
|
50
|
+
}
|
|
51
|
+
function reportResult(filePath, result, filter) {
|
|
52
|
+
const total = result.stepResults.length;
|
|
53
|
+
const failed = result.stepResults.filter((s) => !s.success).length;
|
|
54
|
+
const benignCount = result.stepResults.reduce((n, s) => n + s.diffs.filter((d) => d.severity === "benign").length, 0);
|
|
55
|
+
const errorCount = result.stepResults.reduce((n, s) => n + s.diffs.filter((d) => d.severity === "error").length, 0);
|
|
56
|
+
console.log(`Roundtrip: ${filePath}`);
|
|
57
|
+
console.log(` ${total - failed}/${total} step(s) ok, ${benignCount} benign diff(s), ${errorCount} real diff(s)`);
|
|
58
|
+
// --brief short-circuits: skip the per-step detail entirely. Still prints
|
|
59
|
+
// the one-line summary above, which is the whole point of --brief.
|
|
60
|
+
if (filter.brief)
|
|
61
|
+
return;
|
|
62
|
+
for (const step of result.stepResults) {
|
|
63
|
+
const hasError = step.diffs.some((d) => d.severity === "error");
|
|
64
|
+
const hasBenign = step.diffs.some((d) => d.severity === "benign");
|
|
65
|
+
if (filter.errorsOnly && !hasError && step.success)
|
|
66
|
+
continue;
|
|
67
|
+
if (filter.benignOnly) {
|
|
68
|
+
// Show only steps with benign diffs and no errors and no failure.
|
|
69
|
+
if (!hasBenign || hasError || !step.success)
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Default: skip clean-passing tool steps but keep informational
|
|
73
|
+
// subworkflow notes (failureClass set, success true) visible.
|
|
74
|
+
if (!filter.errorsOnly &&
|
|
75
|
+
!filter.benignOnly &&
|
|
76
|
+
step.diffs.length === 0 &&
|
|
77
|
+
step.success &&
|
|
78
|
+
!step.failureClass) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// Indent nested subworkflow steps (depth>0) so the hierarchy is visible.
|
|
82
|
+
const indent = " ".repeat(step.depth);
|
|
83
|
+
const label = step.toolId ? `${step.stepId} (${step.toolId})` : step.stepId;
|
|
84
|
+
if (!step.success) {
|
|
85
|
+
console.error(`${indent} step ${label}: ${step.failureClass ?? "failed"} — ${step.error ?? ""}`);
|
|
86
|
+
}
|
|
87
|
+
else if (step.failureClass) {
|
|
88
|
+
console.log(`${indent} step ${label}: ${step.failureClass} (${step.error ?? ""})`);
|
|
89
|
+
}
|
|
90
|
+
const diffsToShow = filter.errorsOnly
|
|
91
|
+
? step.diffs.filter((d) => d.severity === "error")
|
|
92
|
+
: filter.benignOnly
|
|
93
|
+
? step.diffs.filter((d) => d.severity === "benign")
|
|
94
|
+
: step.diffs;
|
|
95
|
+
for (const d of diffsToShow) {
|
|
96
|
+
const tag = d.severity === "error" ? "ERROR" : `benign:${d.kind ?? "?"}`;
|
|
97
|
+
const loc = d.path || "<root>";
|
|
98
|
+
console.log(`${indent} [${tag}] ${loc}: ${d.message}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Exit code policy: 0 clean, 1 benign-only, 2 real diffs or errors.
|
|
104
|
+
* Exposed for reuse by the tree command.
|
|
105
|
+
*/
|
|
106
|
+
export function exitCodeFor(result) {
|
|
107
|
+
if (!result.success)
|
|
108
|
+
return 2;
|
|
109
|
+
if (!result.clean)
|
|
110
|
+
return 1;
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
/** Count diffs across a result by severity — reused by tree aggregation. */
|
|
114
|
+
export function countDiffs(result) {
|
|
115
|
+
const flat = result.stepResults.flatMap((s) => s.diffs);
|
|
116
|
+
return {
|
|
117
|
+
benign: flat.filter((d) => d.severity === "benign").length,
|
|
118
|
+
error: flat.filter((d) => d.severity === "error").length,
|
|
119
|
+
failed: result.stepResults.filter((s) => !s.success).length,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=roundtrip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roundtrip.js","sourceRoot":"","sources":["../../src/commands/roundtrip.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper for stateful workflow conversion: expand a workflow, walk every
|
|
3
|
+
* step (including subworkflows), and preload tool parameter definitions
|
|
4
|
+
* from a `ToolCache` into a synchronous `ToolInputsResolver` suitable for
|
|
5
|
+
* `toFormat2Stateful` / `toNativeStateful`.
|
|
6
|
+
*
|
|
7
|
+
* Using `expandedNative` / `expandedFormat2` ensures externally-referenced
|
|
8
|
+
* subworkflows (@import, URL, TRS) contribute their tools — not just
|
|
9
|
+
* inline subworkflows (which is all `unique_tools` would cover).
|
|
10
|
+
*
|
|
11
|
+
* Keys inputs by `${tool_id}\0${tool_version ?? ""}` so multi-version
|
|
12
|
+
* workflows don't collide. Matches gxformat2's `ConversionOptions`
|
|
13
|
+
* callback-shaped design: callers pass the resolver, not the map.
|
|
14
|
+
*/
|
|
15
|
+
import type { ToolCache } from "@galaxy-tool-util/core";
|
|
16
|
+
import { type ExpansionOptions, type ToolInputsResolver, type WorkflowFormat } from "@galaxy-tool-util/schema";
|
|
17
|
+
export interface ToolLoadStatus {
|
|
18
|
+
toolId: string;
|
|
19
|
+
toolVersion: string | null;
|
|
20
|
+
loaded: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface LoadedToolInputs {
|
|
24
|
+
resolver: ToolInputsResolver;
|
|
25
|
+
status: ToolLoadStatus[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Expand the workflow, walk every step, and preload tool inputs from the
|
|
29
|
+
* cache. Returns a sync resolver for `toFormat2Stateful` / `toNativeStateful`
|
|
30
|
+
* plus a per-tool load status list.
|
|
31
|
+
*/
|
|
32
|
+
export declare function loadToolInputsForWorkflow(data: Record<string, unknown>, format: WorkflowFormat, cache: ToolCache, expansionOpts?: ExpansionOptions): Promise<LoadedToolInputs>;
|
|
33
|
+
//# sourceMappingURL=stateful-tool-inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateful-tool-inputs.d.ts","sourceRoot":"","sources":["../../src/commands/stateful-tool-inputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAGL,KAAK,gBAAgB,EAKrB,KAAK,kBAAkB,EAEvB,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAKlC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAMD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,SAAS,EAChB,aAAa,CAAC,EAAE,gBAAgB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAyB3B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { expandedFormat2, expandedNative, } from "@galaxy-tool-util/schema";
|
|
2
|
+
import { isResolveError, loadCachedTool } from "./resolve-tool.js";
|
|
3
|
+
function toolKey(toolId, version) {
|
|
4
|
+
return `${toolId}\0${version ?? ""}`;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Expand the workflow, walk every step, and preload tool inputs from the
|
|
8
|
+
* cache. Returns a sync resolver for `toFormat2Stateful` / `toNativeStateful`
|
|
9
|
+
* plus a per-tool load status list.
|
|
10
|
+
*/
|
|
11
|
+
export async function loadToolInputsForWorkflow(data, format, cache, expansionOpts) {
|
|
12
|
+
const refs = format === "native"
|
|
13
|
+
? collectNativeToolRefs(await expandedNative(data, expansionOpts))
|
|
14
|
+
: collectFormat2ToolRefs(await expandedFormat2(data, expansionOpts));
|
|
15
|
+
const loaded = new Map();
|
|
16
|
+
const status = [];
|
|
17
|
+
for (const [toolId, version] of refs) {
|
|
18
|
+
const key = toolKey(toolId, version);
|
|
19
|
+
if (loaded.has(key))
|
|
20
|
+
continue;
|
|
21
|
+
const resolved = await loadCachedTool(cache, toolId, version);
|
|
22
|
+
if (isResolveError(resolved)) {
|
|
23
|
+
const reason = resolved.kind === "no_version" ? `no version for ${toolId}` : `${toolId} not in cache`;
|
|
24
|
+
status.push({ toolId, toolVersion: version, loaded: false, error: reason });
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
loaded.set(key, resolved.tool.inputs);
|
|
28
|
+
status.push({ toolId, toolVersion: version, loaded: true });
|
|
29
|
+
}
|
|
30
|
+
const resolver = (toolId, version) => loaded.get(toolKey(toolId, version));
|
|
31
|
+
return { resolver, status };
|
|
32
|
+
}
|
|
33
|
+
// --- Step walkers over expanded workflows ---
|
|
34
|
+
function collectNativeToolRefs(wf) {
|
|
35
|
+
const seen = new Set();
|
|
36
|
+
const refs = [];
|
|
37
|
+
const walk = (steps) => {
|
|
38
|
+
for (const step of Object.values(steps)) {
|
|
39
|
+
if (step.tool_id != null) {
|
|
40
|
+
const key = toolKey(step.tool_id, step.tool_version ?? null);
|
|
41
|
+
if (!seen.has(key)) {
|
|
42
|
+
seen.add(key);
|
|
43
|
+
refs.push([step.tool_id, step.tool_version ?? null]);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (step.subworkflow)
|
|
47
|
+
walk(step.subworkflow.steps);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
walk(wf.steps);
|
|
51
|
+
return refs;
|
|
52
|
+
}
|
|
53
|
+
function collectFormat2ToolRefs(wf) {
|
|
54
|
+
const seen = new Set();
|
|
55
|
+
const refs = [];
|
|
56
|
+
const walk = (steps) => {
|
|
57
|
+
for (const step of steps) {
|
|
58
|
+
if (step.tool_id != null) {
|
|
59
|
+
const key = toolKey(step.tool_id, step.tool_version ?? null);
|
|
60
|
+
if (!seen.has(key)) {
|
|
61
|
+
seen.add(key);
|
|
62
|
+
refs.push([step.tool_id, step.tool_version ?? null]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (step.run && typeof step.run === "object") {
|
|
66
|
+
walk(step.run.steps);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
walk(wf.steps);
|
|
71
|
+
return refs;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=stateful-tool-inputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateful-tool-inputs.js","sourceRoot":"","sources":["../../src/commands/stateful-tool-inputs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-schema.d.ts","sourceRoot":"","sources":["../../src/commands/structural-schema.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBtF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `galaxy-tool-cache structural-schema` — export the structural JSON Schema
|
|
3
|
+
* for Galaxy workflow validation (gxformat2 or native).
|
|
4
|
+
*/
|
|
5
|
+
import { GalaxyWorkflowSchema, NativeGalaxyWorkflowSchema } from "@galaxy-tool-util/schema";
|
|
6
|
+
import * as JSONSchema from "effect/JSONSchema";
|
|
7
|
+
import { writeWorkflowOutput } from "./workflow-io.js";
|
|
8
|
+
export async function runStructuralSchema(opts) {
|
|
9
|
+
const format = opts.format ?? "format2";
|
|
10
|
+
if (format !== "format2" && format !== "native") {
|
|
11
|
+
console.error(`Unknown format: ${format}. Use 'format2' (default) or 'native'.`);
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
let jsonSchema;
|
|
16
|
+
try {
|
|
17
|
+
jsonSchema =
|
|
18
|
+
format === "native"
|
|
19
|
+
? JSONSchema.make(NativeGalaxyWorkflowSchema)
|
|
20
|
+
: JSONSchema.make(GalaxyWorkflowSchema);
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
24
|
+
console.error(`JSON Schema generation failed: ${msg}`);
|
|
25
|
+
process.exitCode = 1;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const output = JSON.stringify(jsonSchema, null, 2) + "\n";
|
|
29
|
+
await writeWorkflowOutput(output, opts.output, "Structural schema");
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=structural-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-schema.js","sourceRoot":"","sources":["../../src/commands/structural-schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAOvD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAA6B;IACrE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC;IACxC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,CAAC,KAAK,CAAC,mBAAmB,MAAM,wCAAwC,CAAC,CAAC;QACjF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,UAAmB,CAAC;IACxB,IAAI,CAAC;QACH,UAAU;YACR,MAAM,KAAK,QAAQ;gBACjB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,0BAA0B,CAAC;gBAC7C,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,KAAK,CAAC,kCAAkC,GAAG,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1D,MAAM,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared tree-walking infrastructure for batch workflow operations.
|
|
3
|
+
*
|
|
4
|
+
* Provides a generic discover→load→process→aggregate loop so that
|
|
5
|
+
* each tree command only supplies a per-workflow processing function
|
|
6
|
+
* and an aggregation/formatting function.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors Python's _tree_orchestrator.py pattern.
|
|
9
|
+
*/
|
|
10
|
+
import type { WorkflowFormat } from "@galaxy-tool-util/schema";
|
|
11
|
+
export interface WorkflowInfo {
|
|
12
|
+
path: string;
|
|
13
|
+
relativePath: string;
|
|
14
|
+
format: WorkflowFormat;
|
|
15
|
+
}
|
|
16
|
+
export interface WorkflowOutcome<T> {
|
|
17
|
+
info: WorkflowInfo;
|
|
18
|
+
result?: T;
|
|
19
|
+
error?: string;
|
|
20
|
+
skipped?: boolean;
|
|
21
|
+
skipReason?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface TreeResult<T> {
|
|
24
|
+
root: string;
|
|
25
|
+
outcomes: WorkflowOutcome<T>[];
|
|
26
|
+
}
|
|
27
|
+
export interface TreeSummary {
|
|
28
|
+
total: number;
|
|
29
|
+
ok: number;
|
|
30
|
+
fail: number;
|
|
31
|
+
error: number;
|
|
32
|
+
skipped: number;
|
|
33
|
+
}
|
|
34
|
+
/** Call from processOne to skip a workflow with a reason. */
|
|
35
|
+
export declare function skipWorkflow(reason: string): never;
|
|
36
|
+
/** Discover workflow files recursively under root. */
|
|
37
|
+
export declare function discoverWorkflows(root: string, includeFormat2?: boolean): Promise<WorkflowInfo[]>;
|
|
38
|
+
/** Load and parse a discovered workflow file. Returns null on failure. */
|
|
39
|
+
export declare function loadWorkflowSafe(info: WorkflowInfo): Promise<Record<string, unknown> | null>;
|
|
40
|
+
export type ProcessOne<T> = (info: WorkflowInfo, data: Record<string, unknown>) => Promise<T> | T;
|
|
41
|
+
/** Discover, load, and process all workflows under a directory. */
|
|
42
|
+
export declare function collectTree<T>(root: string, processOne: ProcessOne<T>, includeFormat2?: boolean): Promise<TreeResult<T>>;
|
|
43
|
+
/** Compute a basic summary from tree outcomes. */
|
|
44
|
+
export declare function summarizeOutcomes<T>(outcomes: WorkflowOutcome<T>[], isFail?: (result: T) => boolean): TreeSummary;
|
|
45
|
+
//# sourceMappingURL=tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/commands/tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO/D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAElD;AAyCD,sDAAsD;AACtD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,cAAc,UAAO,GACpB,OAAO,CAAC,YAAY,EAAE,CAAC,CAKzB;AAkDD,0EAA0E;AAC1E,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAOzC;AAID,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAElG,mEAAmE;AACnE,wBAAsB,WAAW,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,cAAc,UAAO,GACpB,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAwBxB;AAED,kDAAkD;AAClD,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,EAC9B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,GAC9B,WAAW,CAiBb"}
|