@openfn/cli 1.24.1 → 1.25.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/dist/index.js +28 -6
- package/dist/process/runner.js +176 -46
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -368,7 +368,7 @@ var ignoreImports = {
|
|
|
368
368
|
}
|
|
369
369
|
};
|
|
370
370
|
var getBaseDir = (opts2) => {
|
|
371
|
-
const basePath = opts2.path ?? ".";
|
|
371
|
+
const basePath = opts2.path ?? opts2.workspace ?? ".";
|
|
372
372
|
if (/\.(jso?n?|ya?ml)$/.test(basePath)) {
|
|
373
373
|
return nodePath.dirname(basePath);
|
|
374
374
|
}
|
|
@@ -923,12 +923,27 @@ var alias = {
|
|
|
923
923
|
description: "Environment name (eg staging, prod, branch)"
|
|
924
924
|
}
|
|
925
925
|
};
|
|
926
|
+
var clean = {
|
|
927
|
+
name: "clean",
|
|
928
|
+
yargs: {
|
|
929
|
+
description: "Clean the working dir before checking out the new project",
|
|
930
|
+
default: false,
|
|
931
|
+
boolean: true
|
|
932
|
+
}
|
|
933
|
+
};
|
|
926
934
|
var dryRun2 = {
|
|
927
935
|
name: "dryRun",
|
|
928
936
|
yargs: {
|
|
929
937
|
description: "Runs the command but does not commit any changes to disk or app"
|
|
930
938
|
}
|
|
931
939
|
};
|
|
940
|
+
var format = {
|
|
941
|
+
name: "format",
|
|
942
|
+
yargs: {
|
|
943
|
+
hidden: true,
|
|
944
|
+
description: "The format to save the project as - state, yaml or json. Use this to download raw state files."
|
|
945
|
+
}
|
|
946
|
+
};
|
|
932
947
|
var removeUnmapped = {
|
|
933
948
|
name: "remove-unmapped",
|
|
934
949
|
yargs: {
|
|
@@ -1138,7 +1153,7 @@ var command_default9 = pullCommand;
|
|
|
1138
1153
|
var repo = {
|
|
1139
1154
|
command: "repo [subcommand]",
|
|
1140
1155
|
describe: "Run commands on the module repo (install|clean)",
|
|
1141
|
-
builder: (yargs2) => yargs2.command(
|
|
1156
|
+
builder: (yargs2) => yargs2.command(clean2).command(install).command(list).example("repo install -a http", "Install @openfn/language-http").example("repo clean", "Remove everything from the repo working dir")
|
|
1142
1157
|
};
|
|
1143
1158
|
var installOptions = [
|
|
1144
1159
|
log,
|
|
@@ -1177,7 +1192,7 @@ var cleanOptions = [
|
|
|
1177
1192
|
}
|
|
1178
1193
|
}
|
|
1179
1194
|
];
|
|
1180
|
-
var
|
|
1195
|
+
var clean2 = {
|
|
1181
1196
|
command: "clean",
|
|
1182
1197
|
describe: "Removes all modules from the runtime module repo",
|
|
1183
1198
|
handler: ensure("repo-clean", cleanOptions),
|
|
@@ -1229,14 +1244,19 @@ import Project3, { Workspace as Workspace4 } from "@openfn/project";
|
|
|
1229
1244
|
|
|
1230
1245
|
// src/projects/checkout.ts
|
|
1231
1246
|
import Project2, { Workspace as Workspace3 } from "@openfn/project";
|
|
1247
|
+
import { rimraf as rimraf2 } from "rimraf";
|
|
1248
|
+
|
|
1249
|
+
// src/projects/util.ts
|
|
1232
1250
|
import { rimraf } from "rimraf";
|
|
1233
|
-
|
|
1251
|
+
|
|
1252
|
+
// src/projects/checkout.ts
|
|
1253
|
+
var options11 = [log, workspace, clean];
|
|
1234
1254
|
var command3 = {
|
|
1235
1255
|
command: "checkout <project>",
|
|
1236
1256
|
describe: "Switch to a different OpenFn project in the same workspace",
|
|
1237
1257
|
handler: ensure("project-checkout", options11),
|
|
1238
1258
|
builder: (yargs2) => build(options11, yargs2).positional("project", {
|
|
1239
|
-
describe: "The id, alias or UUID of the project to
|
|
1259
|
+
describe: "The id, alias or UUID of the project to checkout",
|
|
1240
1260
|
demandOption: true
|
|
1241
1261
|
})
|
|
1242
1262
|
};
|
|
@@ -1291,7 +1311,8 @@ var options13 = [
|
|
|
1291
1311
|
}),
|
|
1292
1312
|
outputPath2,
|
|
1293
1313
|
env2,
|
|
1294
|
-
workspace
|
|
1314
|
+
workspace,
|
|
1315
|
+
format
|
|
1295
1316
|
];
|
|
1296
1317
|
var command5 = {
|
|
1297
1318
|
command: "fetch [project]",
|
|
@@ -1307,6 +1328,7 @@ var command5 = {
|
|
|
1307
1328
|
var fetch_default = command5;
|
|
1308
1329
|
|
|
1309
1330
|
// src/projects/pull.ts
|
|
1331
|
+
import { Workspace as Workspace6 } from "@openfn/project";
|
|
1310
1332
|
var options14 = [
|
|
1311
1333
|
alias,
|
|
1312
1334
|
env2,
|
package/dist/process/runner.js
CHANGED
|
@@ -190,22 +190,31 @@ var createNullLogger = () => createLogger2(void 0, { log: { default: "none" } })
|
|
|
190
190
|
import fs from "node:fs";
|
|
191
191
|
import path2 from "node:path";
|
|
192
192
|
import { rmdir } from "node:fs/promises";
|
|
193
|
-
var
|
|
194
|
-
|
|
195
|
-
const {
|
|
196
|
-
|
|
193
|
+
var CACHE_DIR = ".cli-cache";
|
|
194
|
+
var getCachePath = (options8, workflowName, stepId) => {
|
|
195
|
+
const { baseDir, cachePath } = options8;
|
|
196
|
+
if (cachePath) {
|
|
197
|
+
if (stepId) {
|
|
198
|
+
return path2.resolve(cachePath, `${stepId.replace(/ /, "-")}.json`);
|
|
199
|
+
}
|
|
200
|
+
return path2.resolve(cachePath);
|
|
201
|
+
}
|
|
202
|
+
const basePath = path2.resolve(
|
|
203
|
+
baseDir ?? process.cwd(),
|
|
204
|
+
`${CACHE_DIR}/${workflowName}`
|
|
205
|
+
);
|
|
197
206
|
if (stepId) {
|
|
198
|
-
return
|
|
207
|
+
return `${basePath}/${stepId.replace(/ /, "-")}.json`;
|
|
199
208
|
}
|
|
200
|
-
return
|
|
209
|
+
return basePath;
|
|
201
210
|
};
|
|
202
|
-
var ensureGitIgnore = (options8) => {
|
|
211
|
+
var ensureGitIgnore = (options8, cachePath) => {
|
|
203
212
|
if (!options8._hasGitIgnore) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
);
|
|
213
|
+
let root = cachePath;
|
|
214
|
+
while (root.length > 1 && !root.endsWith(CACHE_DIR)) {
|
|
215
|
+
root = path2.dirname(root);
|
|
216
|
+
}
|
|
217
|
+
const ignorePath = path2.resolve(root, ".gitignore");
|
|
209
218
|
try {
|
|
210
219
|
fs.accessSync(ignorePath);
|
|
211
220
|
} catch (e) {
|
|
@@ -216,15 +225,15 @@ var ensureGitIgnore = (options8) => {
|
|
|
216
225
|
};
|
|
217
226
|
var saveToCache = async (plan, stepId, output, options8, logger) => {
|
|
218
227
|
if (options8.cacheSteps) {
|
|
219
|
-
const cachePath = await getCachePath(
|
|
228
|
+
const cachePath = await getCachePath(options8, plan.workflow.name, stepId);
|
|
220
229
|
fs.mkdirSync(path2.dirname(cachePath), { recursive: true });
|
|
221
|
-
ensureGitIgnore(options8);
|
|
230
|
+
ensureGitIgnore(options8, path2.dirname(cachePath));
|
|
222
231
|
logger.info(`Writing ${stepId} output to ${cachePath}`);
|
|
223
232
|
fs.writeFileSync(cachePath, JSON.stringify(output));
|
|
224
233
|
}
|
|
225
234
|
};
|
|
226
235
|
var clearCache = async (plan, options8, logger) => {
|
|
227
|
-
const cacheDir = await getCachePath(
|
|
236
|
+
const cacheDir = await getCachePath(options8, plan.workflow?.name);
|
|
228
237
|
try {
|
|
229
238
|
await rmdir(cacheDir, { recursive: true });
|
|
230
239
|
logger.info(`Cleared cache at ${cacheDir}`);
|
|
@@ -685,7 +694,11 @@ var load_state_default = async (plan, opts, log2, start) => {
|
|
|
685
694
|
const upstreamStepId = getUpstreamStepId(plan, start);
|
|
686
695
|
if (upstreamStepId) {
|
|
687
696
|
log2.debug(`Input step for "${start}" is "${upstreamStepId}"`);
|
|
688
|
-
const cachedStatePath = await getCachePath(
|
|
697
|
+
const cachedStatePath = await getCachePath(
|
|
698
|
+
opts,
|
|
699
|
+
plan.workflow.name,
|
|
700
|
+
upstreamStepId
|
|
701
|
+
);
|
|
689
702
|
log2.debug("Loading cached state from", cachedStatePath);
|
|
690
703
|
try {
|
|
691
704
|
await fs2.access(cachedStatePath);
|
|
@@ -857,6 +870,7 @@ var loadPlan = async (options8, logger) => {
|
|
|
857
870
|
};
|
|
858
871
|
options8.credentials ??= workspace2.getConfig().credentials;
|
|
859
872
|
options8.collectionsEndpoint ??= proj.openfn?.endpoint;
|
|
873
|
+
options8.cachePath ??= workspace2.workflowsPath + `/${name}/${CACHE_DIR}`;
|
|
860
874
|
}
|
|
861
875
|
if (options8.path && /ya?ml$/.test(options8.path)) {
|
|
862
876
|
const content = await fs3.readFile(path4.resolve(options8.path), "utf-8");
|
|
@@ -886,7 +900,10 @@ var loadPlan = async (options8, logger) => {
|
|
|
886
900
|
defaultName
|
|
887
901
|
);
|
|
888
902
|
} else {
|
|
889
|
-
|
|
903
|
+
const { id, start, options: o, ...w } = workflowObj;
|
|
904
|
+
const opts = { ...o, start };
|
|
905
|
+
const plan = { id, workflow: w, options: opts };
|
|
906
|
+
return loadXPlan(plan, options8, logger, defaultName);
|
|
890
907
|
}
|
|
891
908
|
};
|
|
892
909
|
var load_plan_default = loadPlan;
|
|
@@ -1370,7 +1387,10 @@ var executeHandler = async (options8, logger) => {
|
|
|
1370
1387
|
const result = await execute_default(finalPlan, state, options8, logger);
|
|
1371
1388
|
if (options8.cacheSteps) {
|
|
1372
1389
|
logger.success(
|
|
1373
|
-
|
|
1390
|
+
`Cached output written to ${getCachePath(
|
|
1391
|
+
options8,
|
|
1392
|
+
plan.workflow.name
|
|
1393
|
+
)} (see info logs for details)`
|
|
1374
1394
|
);
|
|
1375
1395
|
}
|
|
1376
1396
|
await serialize_output_default(options8, result, logger);
|
|
@@ -1956,12 +1976,27 @@ var alias = {
|
|
|
1956
1976
|
description: "Environment name (eg staging, prod, branch)"
|
|
1957
1977
|
}
|
|
1958
1978
|
};
|
|
1979
|
+
var clean2 = {
|
|
1980
|
+
name: "clean",
|
|
1981
|
+
yargs: {
|
|
1982
|
+
description: "Clean the working dir before checking out the new project",
|
|
1983
|
+
default: false,
|
|
1984
|
+
boolean: true
|
|
1985
|
+
}
|
|
1986
|
+
};
|
|
1959
1987
|
var dryRun = {
|
|
1960
1988
|
name: "dryRun",
|
|
1961
1989
|
yargs: {
|
|
1962
1990
|
description: "Runs the command but does not commit any changes to disk or app"
|
|
1963
1991
|
}
|
|
1964
1992
|
};
|
|
1993
|
+
var format = {
|
|
1994
|
+
name: "format",
|
|
1995
|
+
yargs: {
|
|
1996
|
+
hidden: true,
|
|
1997
|
+
description: "The format to save the project as - state, yaml or json. Use this to download raw state files."
|
|
1998
|
+
}
|
|
1999
|
+
};
|
|
1965
2000
|
var removeUnmapped = {
|
|
1966
2001
|
name: "remove-unmapped",
|
|
1967
2002
|
yargs: {
|
|
@@ -2013,6 +2048,7 @@ var CLIError = class extends Error {
|
|
|
2013
2048
|
};
|
|
2014
2049
|
|
|
2015
2050
|
// src/projects/util.ts
|
|
2051
|
+
import { rimraf } from "rimraf";
|
|
2016
2052
|
var loadAppAuthConfig = (options8, logger) => {
|
|
2017
2053
|
const { OPENFN_API_KEY, OPENFN_ENDPOINT } = process.env;
|
|
2018
2054
|
const config2 = {
|
|
@@ -2036,22 +2072,22 @@ var ensureExt = (filePath, ext) => {
|
|
|
2036
2072
|
return filePath;
|
|
2037
2073
|
};
|
|
2038
2074
|
var getSerializePath = (project, workspacePath, outputPath2) => {
|
|
2039
|
-
const outputRoot = resolve_path_default(outputPath2 || workspacePath);
|
|
2075
|
+
const outputRoot = resolve_path_default(outputPath2 || workspacePath || ".");
|
|
2040
2076
|
const projectsDir = project?.config.dirs.projects ?? ".projects";
|
|
2041
|
-
return outputPath2 ?? `${outputRoot}/${projectsDir}/${project
|
|
2077
|
+
return outputPath2 ?? `${outputRoot}/${projectsDir}/${project?.qname}`;
|
|
2042
2078
|
};
|
|
2043
2079
|
var serialize = async (project, outputPath2, formatOverride, dryRun2 = false) => {
|
|
2044
2080
|
const root = path9.dirname(outputPath2);
|
|
2045
2081
|
await mkdir3(root, { recursive: true });
|
|
2046
|
-
const
|
|
2047
|
-
const output = project?.serialize("project", { format });
|
|
2082
|
+
const format2 = formatOverride ?? project.config?.formats.project;
|
|
2083
|
+
const output = format2 === "state" ? project?.serialize("state", { format: "json" }) : project?.serialize("project", { format: format2 });
|
|
2048
2084
|
const maybeWriteFile = (filePath, output2) => {
|
|
2049
2085
|
if (!dryRun2) {
|
|
2050
2086
|
return writeFile5(filePath, output2);
|
|
2051
2087
|
}
|
|
2052
2088
|
};
|
|
2053
2089
|
let finalPath;
|
|
2054
|
-
if (
|
|
2090
|
+
if (format2 === "yaml") {
|
|
2055
2091
|
finalPath = ensureExt(outputPath2, "yaml");
|
|
2056
2092
|
await maybeWriteFile(finalPath, output);
|
|
2057
2093
|
} else {
|
|
@@ -2132,6 +2168,23 @@ var DeployError = class extends Error {
|
|
|
2132
2168
|
super(message);
|
|
2133
2169
|
}
|
|
2134
2170
|
};
|
|
2171
|
+
async function tidyWorkflowDir(currentProject, incomingProject, dryRun2 = false) {
|
|
2172
|
+
if (!currentProject || !incomingProject) {
|
|
2173
|
+
return [];
|
|
2174
|
+
}
|
|
2175
|
+
const currentFiles = currentProject.serialize("fs");
|
|
2176
|
+
const newFiles = incomingProject.serialize("fs");
|
|
2177
|
+
const toRemove = [];
|
|
2178
|
+
for (const path17 in currentFiles) {
|
|
2179
|
+
if (!newFiles[path17]) {
|
|
2180
|
+
toRemove.push(path17);
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
if (!dryRun2) {
|
|
2184
|
+
await rimraf(toRemove);
|
|
2185
|
+
}
|
|
2186
|
+
return toRemove.sort();
|
|
2187
|
+
}
|
|
2135
2188
|
|
|
2136
2189
|
// src/util/command-builders.ts
|
|
2137
2190
|
import c from "chalk";
|
|
@@ -2243,7 +2296,13 @@ Pass --force to override this error and deploy anyway.`);
|
|
|
2243
2296
|
logger.success("Nothing to deploy");
|
|
2244
2297
|
return;
|
|
2245
2298
|
}
|
|
2246
|
-
|
|
2299
|
+
const skipVersionTest = localProject.workflows.find((wf) => wf.history.length === 0) || remoteProject.workflows.find((wf) => wf.history.length === 0);
|
|
2300
|
+
if (skipVersionTest) {
|
|
2301
|
+
logger.warn(
|
|
2302
|
+
"Skipping compatibility check as no local version history detected"
|
|
2303
|
+
);
|
|
2304
|
+
logger.warn("Pushing these changes may overrite changes made to the app");
|
|
2305
|
+
} else if (!localProject.canMergeInto(remoteProject)) {
|
|
2247
2306
|
if (!options8.force) {
|
|
2248
2307
|
logger.error(`Error: Projects have diverged!
|
|
2249
2308
|
|
|
@@ -2815,9 +2874,13 @@ import {
|
|
|
2815
2874
|
syncRemoteSpec
|
|
2816
2875
|
} from "@openfn/deploy";
|
|
2817
2876
|
|
|
2877
|
+
// src/projects/pull.ts
|
|
2878
|
+
import { Workspace as Workspace4 } from "@openfn/project";
|
|
2879
|
+
|
|
2818
2880
|
// src/projects/fetch.ts
|
|
2819
2881
|
import path12 from "node:path";
|
|
2820
2882
|
import Project2, { Workspace as Workspace2 } from "@openfn/project";
|
|
2883
|
+
import { writeFile as writeFile8 } from "node:fs/promises";
|
|
2821
2884
|
var options2 = [
|
|
2822
2885
|
alias,
|
|
2823
2886
|
apiKey,
|
|
@@ -2831,7 +2894,8 @@ var options2 = [
|
|
|
2831
2894
|
}),
|
|
2832
2895
|
outputPath,
|
|
2833
2896
|
env,
|
|
2834
|
-
workspace
|
|
2897
|
+
workspace,
|
|
2898
|
+
format
|
|
2835
2899
|
];
|
|
2836
2900
|
var command2 = {
|
|
2837
2901
|
command: "fetch [project]",
|
|
@@ -2845,28 +2909,68 @@ var command2 = {
|
|
|
2845
2909
|
handler: ensure("project-fetch", options2)
|
|
2846
2910
|
};
|
|
2847
2911
|
var printProjectName2 = (project) => `${project.qname} (${project.id})`;
|
|
2848
|
-
var
|
|
2912
|
+
var fetchV1 = async (options8, logger) => {
|
|
2849
2913
|
const workspacePath = options8.workspace ?? process.cwd();
|
|
2850
2914
|
logger.debug("Using workspace at", workspacePath);
|
|
2851
2915
|
const workspace2 = new Workspace2(workspacePath, logger, false);
|
|
2852
|
-
const
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2916
|
+
const localProject = workspace2.get(options8.project);
|
|
2917
|
+
if (localProject) {
|
|
2918
|
+
logger.debug(
|
|
2919
|
+
`Resolved "${options8.project}" to local project ${printProjectName2(
|
|
2920
|
+
localProject
|
|
2921
|
+
)}`
|
|
2922
|
+
);
|
|
2923
|
+
} else {
|
|
2924
|
+
logger.debug(
|
|
2925
|
+
`Failed to resolve "${options8.project}" to local project. Will send request to app anyway.`
|
|
2926
|
+
);
|
|
2927
|
+
}
|
|
2928
|
+
const config2 = loadAppAuthConfig(options8, logger);
|
|
2929
|
+
const { data } = await fetchProject(
|
|
2930
|
+
options8.endpoint ?? localProject?.openfn?.endpoint,
|
|
2931
|
+
config2.apiKey,
|
|
2932
|
+
localProject?.uuid ?? options8.project,
|
|
2856
2933
|
logger
|
|
2857
2934
|
);
|
|
2935
|
+
const finalOutputPath = getSerializePath(
|
|
2936
|
+
localProject,
|
|
2937
|
+
options8.workspace,
|
|
2938
|
+
options8.outputPath
|
|
2939
|
+
);
|
|
2940
|
+
logger.success(`Fetched project file to ${finalOutputPath}`);
|
|
2941
|
+
await writeFile8(finalOutputPath, JSON.stringify(data, null, 2));
|
|
2942
|
+
return data;
|
|
2943
|
+
};
|
|
2944
|
+
var handler2 = async (options8, logger) => {
|
|
2945
|
+
if (options8.format === "state") {
|
|
2946
|
+
return fetchV1(options8, logger);
|
|
2947
|
+
}
|
|
2948
|
+
return fetchV2(options8, logger);
|
|
2949
|
+
};
|
|
2950
|
+
var fetchV2 = async (options8, logger) => {
|
|
2951
|
+
const workspacePath = options8.workspace ?? process.cwd();
|
|
2952
|
+
logger.debug("Using workspace at", workspacePath);
|
|
2953
|
+
const workspace2 = new Workspace2(workspacePath, logger, false);
|
|
2954
|
+
const { outputPath: outputPath2 } = options8;
|
|
2858
2955
|
const remoteProject = await fetchRemoteProject(workspace2, options8, logger);
|
|
2859
|
-
|
|
2956
|
+
if (!options8.force && options8.format !== "state") {
|
|
2957
|
+
const localTargetProject = await resolveOutputProject(
|
|
2958
|
+
workspace2,
|
|
2959
|
+
options8,
|
|
2960
|
+
logger
|
|
2961
|
+
);
|
|
2962
|
+
ensureTargetCompatible(options8, remoteProject, localTargetProject);
|
|
2963
|
+
}
|
|
2860
2964
|
const finalOutputPath = getSerializePath(
|
|
2861
2965
|
remoteProject,
|
|
2862
2966
|
workspacePath,
|
|
2863
2967
|
outputPath2
|
|
2864
2968
|
);
|
|
2865
|
-
let
|
|
2969
|
+
let format2 = options8.format;
|
|
2866
2970
|
if (outputPath2) {
|
|
2867
2971
|
const ext = path12.extname(outputPath2).substring(1);
|
|
2868
2972
|
if (ext.length) {
|
|
2869
|
-
|
|
2973
|
+
format2 = ext;
|
|
2870
2974
|
}
|
|
2871
2975
|
if (options8.alias) {
|
|
2872
2976
|
logger.warn(
|
|
@@ -2874,10 +2978,12 @@ var handler2 = async (options8, logger) => {
|
|
|
2874
2978
|
);
|
|
2875
2979
|
}
|
|
2876
2980
|
}
|
|
2877
|
-
await serialize(
|
|
2878
|
-
|
|
2879
|
-
|
|
2981
|
+
const finalPathWithExt = await serialize(
|
|
2982
|
+
remoteProject,
|
|
2983
|
+
finalOutputPath,
|
|
2984
|
+
format2
|
|
2880
2985
|
);
|
|
2986
|
+
logger.success(`Fetched project file to ${finalPathWithExt}`);
|
|
2881
2987
|
return remoteProject;
|
|
2882
2988
|
};
|
|
2883
2989
|
async function resolveOutputProject(workspace2, options8, logger) {
|
|
@@ -2999,14 +3105,14 @@ To ignore this error and override the local file, pass --force (-f)
|
|
|
2999
3105
|
import Project3, { Workspace as Workspace3 } from "@openfn/project";
|
|
3000
3106
|
import path13 from "path";
|
|
3001
3107
|
import fs4 from "fs";
|
|
3002
|
-
import { rimraf } from "rimraf";
|
|
3003
|
-
var options3 = [log, workspace];
|
|
3108
|
+
import { rimraf as rimraf2 } from "rimraf";
|
|
3109
|
+
var options3 = [log, workspace, clean2];
|
|
3004
3110
|
var command3 = {
|
|
3005
3111
|
command: "checkout <project>",
|
|
3006
3112
|
describe: "Switch to a different OpenFn project in the same workspace",
|
|
3007
3113
|
handler: ensure("project-checkout", options3),
|
|
3008
3114
|
builder: (yargs) => build(options3, yargs).positional("project", {
|
|
3009
|
-
describe: "The id, alias or UUID of the project to
|
|
3115
|
+
describe: "The id, alias or UUID of the project to checkout",
|
|
3010
3116
|
demandOption: true
|
|
3011
3117
|
})
|
|
3012
3118
|
};
|
|
@@ -3015,6 +3121,7 @@ var handler3 = async (options8, logger) => {
|
|
|
3015
3121
|
const workspacePath = options8.workspace ?? process.cwd();
|
|
3016
3122
|
const workspace2 = new Workspace3(workspacePath, logger);
|
|
3017
3123
|
const { project: _, ...config2 } = workspace2.getConfig();
|
|
3124
|
+
const currentProject = workspace2.getActiveProject();
|
|
3018
3125
|
let switchProject;
|
|
3019
3126
|
if (/\.(yaml|json)$/.test(projectIdentifier)) {
|
|
3020
3127
|
const filePath = projectIdentifier.startsWith("/") ? projectIdentifier : path13.join(workspacePath, projectIdentifier);
|
|
@@ -3028,7 +3135,11 @@ var handler3 = async (options8, logger) => {
|
|
|
3028
3135
|
`Project with id ${projectIdentifier} not found in the workspace`
|
|
3029
3136
|
);
|
|
3030
3137
|
}
|
|
3031
|
-
|
|
3138
|
+
if (options8.clean) {
|
|
3139
|
+
await rimraf2(workspace2.workflowsPath);
|
|
3140
|
+
} else {
|
|
3141
|
+
await tidyWorkflowDir(currentProject, switchProject);
|
|
3142
|
+
}
|
|
3032
3143
|
const files = switchProject.serialize("fs");
|
|
3033
3144
|
for (const f in files) {
|
|
3034
3145
|
if (files[f]) {
|
|
@@ -3071,11 +3182,30 @@ var command4 = {
|
|
|
3071
3182
|
handler: ensure("project-pull", options4)
|
|
3072
3183
|
};
|
|
3073
3184
|
async function handler4(options8, logger) {
|
|
3185
|
+
ensureProjectId(options8, logger);
|
|
3074
3186
|
await handler2(options8, logger);
|
|
3075
3187
|
logger.success(`Downloaded latest project version`);
|
|
3076
3188
|
await handler3(options8, logger);
|
|
3077
3189
|
logger.success(`Checked out project locally`);
|
|
3078
3190
|
}
|
|
3191
|
+
var ensureProjectId = (options8, logger) => {
|
|
3192
|
+
if (!options8.project) {
|
|
3193
|
+
logger?.debug(
|
|
3194
|
+
"No project ID specified: looking up checked out project in Workspace"
|
|
3195
|
+
);
|
|
3196
|
+
const ws = new Workspace4(options8.workspace);
|
|
3197
|
+
if (ws.activeProject) {
|
|
3198
|
+
options8.project = ws.activeProject.uuid;
|
|
3199
|
+
logger?.info(
|
|
3200
|
+
`Project id not provided: will default to ${options8.project}`
|
|
3201
|
+
);
|
|
3202
|
+
} else {
|
|
3203
|
+
throw new Error(
|
|
3204
|
+
"Project not provided: specify a project UUID, id or alias"
|
|
3205
|
+
);
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
};
|
|
3079
3209
|
var pull_default = handler4;
|
|
3080
3210
|
|
|
3081
3211
|
// src/pull/handler.ts
|
|
@@ -3190,7 +3320,7 @@ __export(projects_exports, {
|
|
|
3190
3320
|
});
|
|
3191
3321
|
|
|
3192
3322
|
// src/projects/list.ts
|
|
3193
|
-
import { Workspace as
|
|
3323
|
+
import { Workspace as Workspace5 } from "@openfn/project";
|
|
3194
3324
|
var options5 = [log, workspace];
|
|
3195
3325
|
var command5 = {
|
|
3196
3326
|
command: "list [project-path]",
|
|
@@ -3203,7 +3333,7 @@ var handler5 = async (options8, logger) => {
|
|
|
3203
3333
|
logger.info("Searching for projects in workspace at:");
|
|
3204
3334
|
logger.info(" ", options8.workspace);
|
|
3205
3335
|
logger.break();
|
|
3206
|
-
const workspace2 = new
|
|
3336
|
+
const workspace2 = new Workspace5(options8.workspace);
|
|
3207
3337
|
if (!workspace2.valid) {
|
|
3208
3338
|
throw new Error("No OpenFn projects found");
|
|
3209
3339
|
}
|
|
@@ -3221,7 +3351,7 @@ ${project.workflows.map((w) => " - " + w.id).join("\n")}`;
|
|
|
3221
3351
|
}
|
|
3222
3352
|
|
|
3223
3353
|
// src/projects/version.ts
|
|
3224
|
-
import { Workspace as
|
|
3354
|
+
import { Workspace as Workspace6 } from "@openfn/project";
|
|
3225
3355
|
var options6 = [workflow, workspace, workflowMappings];
|
|
3226
3356
|
var command6 = {
|
|
3227
3357
|
command: "version [workflow]",
|
|
@@ -3230,7 +3360,7 @@ var command6 = {
|
|
|
3230
3360
|
builder: (yargs) => build(options6, yargs)
|
|
3231
3361
|
};
|
|
3232
3362
|
var handler6 = async (options8, logger) => {
|
|
3233
|
-
const workspace2 = new
|
|
3363
|
+
const workspace2 = new Workspace6(options8.workspace);
|
|
3234
3364
|
if (!workspace2.valid) {
|
|
3235
3365
|
logger.error("Command was run in an invalid openfn workspace");
|
|
3236
3366
|
return;
|
|
@@ -3265,7 +3395,7 @@ ${final}`);
|
|
|
3265
3395
|
};
|
|
3266
3396
|
|
|
3267
3397
|
// src/projects/merge.ts
|
|
3268
|
-
import Project5, { Workspace as
|
|
3398
|
+
import Project5, { Workspace as Workspace7 } from "@openfn/project";
|
|
3269
3399
|
import path15 from "node:path";
|
|
3270
3400
|
import fs6 from "node:fs/promises";
|
|
3271
3401
|
var options7 = [
|
|
@@ -3301,7 +3431,7 @@ var command7 = {
|
|
|
3301
3431
|
};
|
|
3302
3432
|
var handler7 = async (options8, logger) => {
|
|
3303
3433
|
const workspacePath = options8.workspace;
|
|
3304
|
-
const workspace2 = new
|
|
3434
|
+
const workspace2 = new Workspace7(workspacePath);
|
|
3305
3435
|
if (!workspace2.valid) {
|
|
3306
3436
|
logger.error("Command was run in an invalid openfn workspace");
|
|
3307
3437
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"description": "CLI devtools for the OpenFn toolchain",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"@types/ws": "^8.18.1",
|
|
34
34
|
"@types/yargs": "^17.0.33",
|
|
35
35
|
"ava": "5.3.1",
|
|
36
|
+
"lodash-es": "^4.17.21",
|
|
36
37
|
"mock-fs": "^5.5.0",
|
|
37
38
|
"tslib": "^2.8.1",
|
|
38
39
|
"tsup": "^7.2.0",
|
|
@@ -52,10 +53,10 @@
|
|
|
52
53
|
"@openfn/describe-package": "0.1.5",
|
|
53
54
|
"@openfn/lexicon": "^1.4.0",
|
|
54
55
|
"@openfn/compiler": "1.2.2",
|
|
55
|
-
"@openfn/logger": "1.1.1",
|
|
56
56
|
"@openfn/deploy": "0.11.5",
|
|
57
|
-
"@openfn/
|
|
58
|
-
"@openfn/
|
|
57
|
+
"@openfn/logger": "1.1.1",
|
|
58
|
+
"@openfn/project": "^0.12.1",
|
|
59
|
+
"@openfn/runtime": "1.8.3"
|
|
59
60
|
},
|
|
60
61
|
"files": [
|
|
61
62
|
"dist",
|