windmill-cli 1.518.2 → 1.519.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/esm/gen/core/OpenAPI.js +1 -1
- package/esm/gen/services.gen.js +74 -2
- package/esm/{apps.js → src/commands/app/apps.js} +6 -6
- package/esm/{dev.js → src/commands/dev/dev.js} +11 -11
- package/esm/{flow.js → src/commands/flow/flow.js} +13 -13
- package/esm/{folder.js → src/commands/folder/folder.js} +6 -6
- package/esm/src/commands/gitsync-settings/converter.js +134 -0
- package/esm/src/commands/gitsync-settings/gitsync-settings.js +2 -0
- package/esm/src/commands/gitsync-settings/index.js +28 -0
- package/esm/src/commands/gitsync-settings/legacySettings.js +119 -0
- package/esm/src/commands/gitsync-settings/pull.js +372 -0
- package/esm/src/commands/gitsync-settings/push.js +263 -0
- package/esm/src/commands/gitsync-settings/types.js +37 -0
- package/esm/src/commands/gitsync-settings/utils.js +129 -0
- package/esm/{hub.js → src/commands/hub/hub.js} +6 -6
- package/esm/src/commands/init/init.js +214 -0
- package/esm/{instance.js → src/commands/instance/instance.js} +18 -18
- package/esm/{queues.js → src/commands/queues/queues.js} +4 -4
- package/esm/{resource.js → src/commands/resource/resource.js} +7 -7
- package/esm/{resource-type.js → src/commands/resource-type/resource-type.js} +6 -6
- package/esm/{schedule.js → src/commands/schedule/schedule.js} +6 -6
- package/esm/{script.js → src/commands/script/script.js} +14 -14
- package/esm/{pull.js → src/commands/sync/pull.js} +2 -2
- package/esm/{sync.js → src/commands/sync/sync.js} +47 -146
- package/esm/{trigger.js → src/commands/trigger/trigger.js} +6 -6
- package/esm/{user.js → src/commands/user/user.js} +6 -6
- package/esm/{variable.js → src/commands/variable/variable.js} +6 -6
- package/esm/{worker_groups.js → src/commands/worker-groups/worker_groups.js} +5 -5
- package/esm/{workers.js → src/commands/workers/workers.js} +4 -4
- package/esm/{workspace.js → src/commands/workspace/workspace.js} +78 -44
- package/esm/{auth.js → src/core/auth.js} +3 -3
- package/esm/src/core/branch-profiles.js +46 -0
- package/esm/src/core/conf.js +162 -0
- package/esm/src/core/context.js +263 -0
- package/esm/{login.js → src/core/login.js} +2 -2
- package/esm/{settings.js → src/core/settings.js} +8 -8
- package/esm/src/core/store.js +19 -0
- package/esm/src/main.js +174 -0
- package/esm/{types.js → src/types.js} +16 -16
- package/esm/{codebase.js → src/utils/codebase.js} +1 -1
- package/esm/src/utils/git.js +29 -0
- package/esm/{metadata.js → src/utils/metadata.js} +31 -31
- package/esm/{upgrade.js → src/utils/upgrade.js} +1 -1
- package/esm/{utils.js → src/utils/utils.js} +11 -3
- package/esm/windmill-utils-internal/src/config/config.js +190 -0
- package/esm/windmill-utils-internal/src/inline-scripts/extractor.js +13 -9
- package/esm/windmill-utils-internal/src/path-utils/path-assigner.js +25 -9
- package/package.json +6 -6
- package/types/gen/services.gen.d.ts +37 -1
- package/types/gen/services.gen.d.ts.map +1 -1
- package/types/gen/types.gen.d.ts +48 -3
- package/types/gen/types.gen.d.ts.map +1 -1
- package/types/src/commands/app/apps.d.ts +17 -0
- package/types/src/commands/app/apps.d.ts.map +1 -0
- package/types/src/commands/dev/dev.d.ts +12 -0
- package/types/src/commands/dev/dev.d.ts.map +1 -0
- package/types/{flow.d.ts → src/commands/flow/flow.d.ts} +5 -5
- package/types/src/commands/flow/flow.d.ts.map +1 -0
- package/types/{folder.d.ts → src/commands/folder/folder.d.ts} +3 -3
- package/types/src/commands/folder/folder.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/converter.d.ts +10 -0
- package/types/src/commands/gitsync-settings/converter.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/gitsync-settings.d.ts +3 -0
- package/types/src/commands/gitsync-settings/gitsync-settings.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/index.d.ts +25 -0
- package/types/src/commands/gitsync-settings/index.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/legacySettings.d.ts +4 -0
- package/types/src/commands/gitsync-settings/legacySettings.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/pull.d.ts +14 -0
- package/types/src/commands/gitsync-settings/pull.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/push.d.ts +10 -0
- package/types/src/commands/gitsync-settings/push.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/types.d.ts +35 -0
- package/types/src/commands/gitsync-settings/types.d.ts.map +1 -0
- package/types/src/commands/gitsync-settings/utils.d.ts +36 -0
- package/types/src/commands/gitsync-settings/utils.d.ts.map +1 -0
- package/types/{hub.d.ts → src/commands/hub/hub.d.ts} +2 -2
- package/types/src/commands/hub/hub.d.ts.map +1 -0
- package/types/src/commands/init/init.d.ts +34 -0
- package/types/src/commands/init/init.d.ts.map +1 -0
- package/types/{instance.d.ts → src/commands/instance/instance.d.ts} +1 -1
- package/types/src/commands/instance/instance.d.ts.map +1 -0
- package/types/src/commands/queues/queues.d.ts +14 -0
- package/types/src/commands/queues/queues.d.ts.map +1 -0
- package/types/{resource.d.ts → src/commands/resource/resource.d.ts} +3 -3
- package/types/src/commands/resource/resource.d.ts.map +1 -0
- package/types/src/commands/resource-type/resource-type.d.ts +16 -0
- package/types/src/commands/resource-type/resource-type.d.ts.map +1 -0
- package/types/{schedule.d.ts → src/commands/schedule/schedule.d.ts} +3 -3
- package/types/src/commands/schedule/schedule.d.ts.map +1 -0
- package/types/{script.d.ts → src/commands/script/script.d.ts} +9 -9
- package/types/src/commands/script/script.d.ts.map +1 -0
- package/types/{pull.d.ts → src/commands/sync/pull.d.ts} +3 -3
- package/types/src/commands/sync/pull.d.ts.map +1 -0
- package/types/{sync.d.ts → src/commands/sync/sync.d.ts} +11 -13
- package/types/src/commands/sync/sync.d.ts.map +1 -0
- package/types/{trigger.d.ts → src/commands/trigger/trigger.d.ts} +3 -3
- package/types/src/commands/trigger/trigger.d.ts.map +1 -0
- package/types/{user.d.ts → src/commands/user/user.d.ts} +5 -5
- package/types/src/commands/user/user.d.ts.map +1 -0
- package/types/{variable.d.ts → src/commands/variable/variable.d.ts} +3 -3
- package/types/src/commands/variable/variable.d.ts.map +1 -0
- package/types/{worker_groups.d.ts → src/commands/worker-groups/worker_groups.d.ts} +2 -3
- package/types/src/commands/worker-groups/worker_groups.d.ts.map +1 -0
- package/types/{workers.d.ts → src/commands/workers/workers.d.ts} +1 -1
- package/types/src/commands/workers/workers.d.ts.map +1 -0
- package/types/{workspace.d.ts → src/commands/workspace/workspace.d.ts} +6 -4
- package/types/src/commands/workspace/workspace.d.ts.map +1 -0
- package/types/{auth.d.ts → src/core/auth.d.ts} +2 -2
- package/types/src/core/auth.d.ts.map +1 -0
- package/types/src/core/branch-profiles.d.ts +12 -0
- package/types/src/core/branch-profiles.d.ts.map +1 -0
- package/types/{conf.d.ts → src/core/conf.d.ts} +12 -3
- package/types/src/core/conf.d.ts.map +1 -0
- package/types/{context.d.ts → src/core/context.d.ts} +2 -2
- package/types/src/core/context.d.ts.map +1 -0
- package/types/{login.d.ts → src/core/login.d.ts} +1 -1
- package/types/src/core/login.d.ts.map +1 -0
- package/types/{settings.d.ts → src/core/settings.d.ts} +2 -2
- package/types/src/core/settings.d.ts.map +1 -0
- package/types/src/core/store.d.ts +2 -0
- package/types/src/core/store.d.ts.map +1 -0
- package/types/src/guidance/flow_guidance.d.ts.map +1 -0
- package/types/src/guidance/script_guidance.d.ts.map +1 -0
- package/types/src/main.d.ts +74 -0
- package/types/src/main.d.ts.map +1 -0
- package/types/src/types.d.ts.map +1 -0
- package/types/{codebase.d.ts → src/utils/codebase.d.ts} +1 -1
- package/types/src/utils/codebase.d.ts.map +1 -0
- package/types/src/utils/git.d.ts +3 -0
- package/types/src/utils/git.d.ts.map +1 -0
- package/types/src/utils/local_encryption.d.ts.map +1 -0
- package/types/{metadata.d.ts → src/utils/metadata.d.ts} +4 -4
- package/types/src/utils/metadata.d.ts.map +1 -0
- package/types/src/utils/script_common.d.ts.map +1 -0
- package/types/{upgrade.d.ts → src/utils/upgrade.d.ts} +1 -1
- package/types/src/utils/upgrade.d.ts.map +1 -0
- package/types/{utils.d.ts → src/utils/utils.d.ts} +2 -1
- package/types/src/utils/utils.d.ts.map +1 -0
- package/types/windmill-utils-internal/src/config/config.d.ts +12 -0
- package/types/windmill-utils-internal/src/config/config.d.ts.map +1 -0
- package/types/windmill-utils-internal/src/gen/types.gen.d.ts +48 -3
- package/types/windmill-utils-internal/src/gen/types.gen.d.ts.map +1 -1
- package/types/windmill-utils-internal/src/inline-scripts/extractor.d.ts +1 -4
- package/types/windmill-utils-internal/src/inline-scripts/extractor.d.ts.map +1 -1
- package/types/windmill-utils-internal/src/path-utils/path-assigner.d.ts +6 -6
- package/types/windmill-utils-internal/src/path-utils/path-assigner.d.ts.map +1 -1
- package/esm/conf.js +0 -78
- package/esm/context.js +0 -121
- package/esm/gitsync-settings.js +0 -984
- package/esm/main.js +0 -337
- package/esm/store.js +0 -76
- package/types/apps.d.ts +0 -17
- package/types/apps.d.ts.map +0 -1
- package/types/auth.d.ts.map +0 -1
- package/types/codebase.d.ts.map +0 -1
- package/types/conf.d.ts.map +0 -1
- package/types/context.d.ts.map +0 -1
- package/types/dev.d.ts +0 -12
- package/types/dev.d.ts.map +0 -1
- package/types/flow.d.ts.map +0 -1
- package/types/flow_guidance.d.ts.map +0 -1
- package/types/folder.d.ts.map +0 -1
- package/types/gitsync-settings.d.ts +0 -40
- package/types/gitsync-settings.d.ts.map +0 -1
- package/types/hub.d.ts.map +0 -1
- package/types/instance.d.ts.map +0 -1
- package/types/local_encryption.d.ts.map +0 -1
- package/types/login.d.ts.map +0 -1
- package/types/main.d.ts +0 -70
- package/types/main.d.ts.map +0 -1
- package/types/metadata.d.ts.map +0 -1
- package/types/pull.d.ts.map +0 -1
- package/types/queues.d.ts +0 -14
- package/types/queues.d.ts.map +0 -1
- package/types/resource-type.d.ts +0 -16
- package/types/resource-type.d.ts.map +0 -1
- package/types/resource.d.ts.map +0 -1
- package/types/schedule.d.ts.map +0 -1
- package/types/script.d.ts.map +0 -1
- package/types/script_common.d.ts.map +0 -1
- package/types/script_guidance.d.ts.map +0 -1
- package/types/settings.d.ts.map +0 -1
- package/types/store.d.ts +0 -3
- package/types/store.d.ts.map +0 -1
- package/types/sync.d.ts.map +0 -1
- package/types/trigger.d.ts.map +0 -1
- package/types/types.d.ts.map +0 -1
- package/types/upgrade.d.ts.map +0 -1
- package/types/user.d.ts.map +0 -1
- package/types/utils.d.ts.map +0 -1
- package/types/variable.d.ts.map +0 -1
- package/types/worker_groups.d.ts.map +0 -1
- package/types/workers.d.ts.map +0 -1
- package/types/workspace.d.ts.map +0 -1
- /package/esm/{flow_guidance.js → src/guidance/flow_guidance.js} +0 -0
- /package/esm/{script_guidance.js → src/guidance/script_guidance.js} +0 -0
- /package/esm/{local_encryption.js → src/utils/local_encryption.js} +0 -0
- /package/esm/{script_common.js → src/utils/script_common.js} +0 -0
- /package/types/{flow_guidance.d.ts → src/guidance/flow_guidance.d.ts} +0 -0
- /package/types/{script_guidance.d.ts → src/guidance/script_guidance.d.ts} +0 -0
- /package/types/{types.d.ts → src/types.d.ts} +0 -0
- /package/types/{local_encryption.d.ts → src/utils/local_encryption.d.ts} +0 -0
- /package/types/{script_common.d.ts → src/utils/script_common.d.ts} +0 -0
|
@@ -1,80 +1,29 @@
|
|
|
1
|
-
import * as dntShim from "
|
|
2
|
-
import { requireLogin } from "
|
|
3
|
-
import { fetchVersion, resolveWorkspace } from "
|
|
4
|
-
import { colors, Command, Confirm,
|
|
5
|
-
import * as wmill from "
|
|
6
|
-
import { getTypeStrFromPath, parseFromPath, pushObj, showConflict, showDiff, } from "
|
|
1
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
|
+
import { requireLogin } from "../../core/auth.js";
|
|
3
|
+
import { fetchVersion, resolveWorkspace } from "../../core/context.js";
|
|
4
|
+
import { colors, Command, Confirm, ensureDir, minimatch, path, log, yamlStringify, yamlParseContent, SEP, } from "../../../deps.js";
|
|
5
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
6
|
+
import { getTypeStrFromPath, parseFromPath, pushObj, showConflict, showDiff, } from "../../types.js";
|
|
7
7
|
import { downloadZip } from "./pull.js";
|
|
8
|
-
import { exts, findContentFile, findGlobalDeps, findResourceFile, handleScriptMetadata, removeExtensionToPath, } from "
|
|
9
|
-
import { handleFile } from "
|
|
10
|
-
import { deepEqual, isFileResource } from "
|
|
11
|
-
import { readConfigFile, getEffectiveSettings } from "
|
|
12
|
-
import { removePathPrefix } from "
|
|
13
|
-
import { listSyncCodebases } from "
|
|
14
|
-
import { generateFlowLockInternal, generateScriptMetadataInternal, readLockfile, } from "
|
|
15
|
-
import { pushResource } from "
|
|
16
|
-
import {
|
|
8
|
+
import { exts, findContentFile, findGlobalDeps, findResourceFile, handleScriptMetadata, removeExtensionToPath, } from "../script/script.js";
|
|
9
|
+
import { handleFile } from "../script/script.js";
|
|
10
|
+
import { deepEqual, isFileResource } from "../../utils/utils.js";
|
|
11
|
+
import { readConfigFile, getEffectiveSettings, validateBranchConfiguration, } from "../../core/conf.js";
|
|
12
|
+
import { removePathPrefix } from "../../types.js";
|
|
13
|
+
import { listSyncCodebases } from "../../utils/codebase.js";
|
|
14
|
+
import { generateFlowLockInternal, generateScriptMetadataInternal, readLockfile, } from "../../utils/metadata.js";
|
|
15
|
+
import { pushResource } from "../resource/resource.js";
|
|
16
|
+
import { newPathAssigner } from "../../../windmill-utils-internal/src/path-utils/path-assigner.js";
|
|
17
|
+
import { extractInlineScripts as extractInlineScriptsForFlows } from "../../../windmill-utils-internal/src/inline-scripts/extractor.js";
|
|
17
18
|
// Merge CLI options with effective settings, preserving CLI flags as overrides
|
|
18
19
|
function mergeCliWithEffectiveOptions(cliOpts, effectiveOpts) {
|
|
19
20
|
// overlay CLI options on top (undefined cliOpts won't override effectiveOpts)
|
|
20
21
|
return Object.assign({}, effectiveOpts, cliOpts);
|
|
21
22
|
}
|
|
22
|
-
// Resolve effective sync options
|
|
23
|
-
async function resolveEffectiveSyncOptions(workspace,
|
|
23
|
+
// Resolve effective sync options using branch-based configuration
|
|
24
|
+
async function resolveEffectiveSyncOptions(workspace, promotion) {
|
|
24
25
|
const localConfig = await readConfigFile();
|
|
25
|
-
|
|
26
|
-
if (repositoryPath) {
|
|
27
|
-
return getEffectiveSettings(localConfig, workspace.remote, workspace.workspaceId, repositoryPath);
|
|
28
|
-
}
|
|
29
|
-
// Auto-detect repository from overrides if not specified
|
|
30
|
-
if (localConfig.overrides) {
|
|
31
|
-
const prefix = `${workspace.remote}:${workspace.workspaceId}:`;
|
|
32
|
-
const applicableRepos = [];
|
|
33
|
-
// Find all repository-specific overrides for this workspace
|
|
34
|
-
for (const key of Object.keys(localConfig.overrides)) {
|
|
35
|
-
if (key.startsWith(prefix) && !key.endsWith(":*")) {
|
|
36
|
-
const repo = key.substring(prefix.length);
|
|
37
|
-
if (repo) {
|
|
38
|
-
applicableRepos.push(repo);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (applicableRepos.length === 1) {
|
|
43
|
-
// Single repository found - auto-select it
|
|
44
|
-
log.info(`Auto-selected repository: ${applicableRepos[0]}`);
|
|
45
|
-
return getEffectiveSettings(localConfig, workspace.remote, workspace.workspaceId, applicableRepos[0]);
|
|
46
|
-
}
|
|
47
|
-
else if (applicableRepos.length > 1) {
|
|
48
|
-
// Multiple repositories found - prompt for selection
|
|
49
|
-
const isInteractive = dntShim.Deno.stdin.isTerminal() && dntShim.Deno.stdout.isTerminal();
|
|
50
|
-
if (isInteractive) {
|
|
51
|
-
const choices = [
|
|
52
|
-
{
|
|
53
|
-
name: "Use top-level settings (no repository-specific override)",
|
|
54
|
-
value: "",
|
|
55
|
-
},
|
|
56
|
-
...applicableRepos.map((repo) => ({ name: repo, value: repo })),
|
|
57
|
-
];
|
|
58
|
-
const selectedRepo = await Select.prompt({
|
|
59
|
-
message: "Multiple repository overrides found. Select which to use:",
|
|
60
|
-
options: choices,
|
|
61
|
-
});
|
|
62
|
-
if (selectedRepo) {
|
|
63
|
-
log.info(`Selected repository: ${selectedRepo}`);
|
|
64
|
-
}
|
|
65
|
-
return getEffectiveSettings(localConfig, workspace.remote, workspace.workspaceId, selectedRepo);
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
// Non-interactive mode - list options and use top-level
|
|
69
|
-
log.warn(`Multiple repository overrides found: ${applicableRepos.join(", ")}`);
|
|
70
|
-
log.warn(`Running in non-interactive mode. Use --repository flag to specify which one to use.`);
|
|
71
|
-
log.info(`Falling back to top-level settings (no repository-specific overrides applied)`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
// No repository overrides found or selected - use top-level settings
|
|
76
|
-
log.info(`No repository overrides found, using top-level settings`);
|
|
77
|
-
return getEffectiveSettings(localConfig, workspace.remote, workspace.workspaceId, "");
|
|
26
|
+
return await getEffectiveSettings(localConfig, promotion);
|
|
78
27
|
}
|
|
79
28
|
export function findCodebase(path, codebases) {
|
|
80
29
|
if (!path.endsWith(".ts")) {
|
|
@@ -283,7 +232,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, ig
|
|
|
283
232
|
async *getChildren() {
|
|
284
233
|
if (kind == "flow") {
|
|
285
234
|
const flow = JSON.parse(await f.async("text"));
|
|
286
|
-
const inlineScripts = extractInlineScriptsForFlows(flow.value.modules, {}, SEP, defaultTs
|
|
235
|
+
const inlineScripts = extractInlineScriptsForFlows(flow.value.modules, {}, SEP, defaultTs);
|
|
287
236
|
for (const s of inlineScripts) {
|
|
288
237
|
yield {
|
|
289
238
|
isDirectory: false,
|
|
@@ -917,13 +866,24 @@ async function buildTracker(changes) {
|
|
|
917
866
|
return tracker;
|
|
918
867
|
}
|
|
919
868
|
export async function pull(opts) {
|
|
869
|
+
// Validate branch configuration early
|
|
870
|
+
try {
|
|
871
|
+
await validateBranchConfiguration(false, opts.yes);
|
|
872
|
+
}
|
|
873
|
+
catch (error) {
|
|
874
|
+
if (error instanceof Error && error.message.includes("overrides")) {
|
|
875
|
+
log.error(error.message);
|
|
876
|
+
dntShim.Deno.exit(1);
|
|
877
|
+
}
|
|
878
|
+
throw error;
|
|
879
|
+
}
|
|
920
880
|
if (opts.stateful) {
|
|
921
881
|
await ensureDir(path.join(dntShim.Deno.cwd(), ".wmill"));
|
|
922
882
|
}
|
|
923
883
|
const workspace = await resolveWorkspace(opts);
|
|
924
884
|
await requireLogin(opts);
|
|
925
|
-
// Resolve effective sync options with
|
|
926
|
-
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts.
|
|
885
|
+
// Resolve effective sync options with branch awareness
|
|
886
|
+
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts.promotion);
|
|
927
887
|
// Merge CLI flags with resolved settings (CLI flags take precedence only for explicit overrides)
|
|
928
888
|
opts = mergeCliWithEffectiveOptions(opts, effectiveOpts);
|
|
929
889
|
const codebases = await listSyncCodebases(opts);
|
|
@@ -1143,10 +1103,21 @@ function removeSuffix(str, suffix) {
|
|
|
1143
1103
|
return str.slice(0, str.length - suffix.length);
|
|
1144
1104
|
}
|
|
1145
1105
|
export async function push(opts) {
|
|
1106
|
+
// Validate branch configuration early
|
|
1107
|
+
try {
|
|
1108
|
+
await validateBranchConfiguration(false, opts.yes);
|
|
1109
|
+
}
|
|
1110
|
+
catch (error) {
|
|
1111
|
+
if (error instanceof Error && error.message.includes("overrides")) {
|
|
1112
|
+
log.error(error.message);
|
|
1113
|
+
dntShim.Deno.exit(1);
|
|
1114
|
+
}
|
|
1115
|
+
throw error;
|
|
1116
|
+
}
|
|
1146
1117
|
const workspace = await resolveWorkspace(opts);
|
|
1147
1118
|
await requireLogin(opts);
|
|
1148
|
-
// Resolve effective sync options with
|
|
1149
|
-
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts.
|
|
1119
|
+
// Resolve effective sync options with branch awareness
|
|
1120
|
+
const effectiveOpts = await resolveEffectiveSyncOptions(workspace, opts.promotion);
|
|
1150
1121
|
// Merge CLI flags with resolved settings (CLI flags take precedence only for explicit overrides)
|
|
1151
1122
|
opts = mergeCliWithEffectiveOptions(opts, effectiveOpts);
|
|
1152
1123
|
const codebases = await listSyncCodebases(opts);
|
|
@@ -1556,6 +1527,7 @@ const command = new Command()
|
|
|
1556
1527
|
.option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account. Overrides wmill.yaml excludes")
|
|
1557
1528
|
.option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy")
|
|
1558
1529
|
.option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist")
|
|
1530
|
+
.option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides")
|
|
1559
1531
|
// deno-lint-ignore no-explicit-any
|
|
1560
1532
|
.action(pull)
|
|
1561
1533
|
.command("push")
|
|
@@ -1588,75 +1560,4 @@ const command = new Command()
|
|
|
1588
1560
|
.option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist")
|
|
1589
1561
|
// deno-lint-ignore no-explicit-any
|
|
1590
1562
|
.action(push);
|
|
1591
|
-
const INLINE_SCRIPT = "inline_script";
|
|
1592
|
-
export function newPathAssigner(defaultTs) {
|
|
1593
|
-
let counter = 0;
|
|
1594
|
-
const seen_names = new Set();
|
|
1595
|
-
function assignPath(summary, language) {
|
|
1596
|
-
let name;
|
|
1597
|
-
name = summary?.toLowerCase()?.replaceAll(" ", "_") ?? "";
|
|
1598
|
-
let original_name = name;
|
|
1599
|
-
if (name == "") {
|
|
1600
|
-
original_name = INLINE_SCRIPT;
|
|
1601
|
-
name = `${INLINE_SCRIPT}_0`;
|
|
1602
|
-
}
|
|
1603
|
-
while (seen_names.has(name)) {
|
|
1604
|
-
counter++;
|
|
1605
|
-
name = `${original_name}_${counter}`;
|
|
1606
|
-
}
|
|
1607
|
-
seen_names.add(name);
|
|
1608
|
-
let ext;
|
|
1609
|
-
if (language == "python3")
|
|
1610
|
-
ext = "py";
|
|
1611
|
-
else if (language == defaultTs || language == "bunnative")
|
|
1612
|
-
ext = "ts";
|
|
1613
|
-
else if (language == "bun")
|
|
1614
|
-
ext = "bun.ts";
|
|
1615
|
-
else if (language == "deno")
|
|
1616
|
-
ext = "deno.ts";
|
|
1617
|
-
else if (language == "go")
|
|
1618
|
-
ext = "go";
|
|
1619
|
-
else if (language == "bash")
|
|
1620
|
-
ext = "sh";
|
|
1621
|
-
else if (language == "powershell")
|
|
1622
|
-
ext = "ps1";
|
|
1623
|
-
else if (language == "postgresql")
|
|
1624
|
-
ext = "pg.sql";
|
|
1625
|
-
else if (language == "mysql")
|
|
1626
|
-
ext = "my.sql";
|
|
1627
|
-
else if (language == "bigquery")
|
|
1628
|
-
ext = "bq.sql";
|
|
1629
|
-
else if (language == "oracledb")
|
|
1630
|
-
ext = "odb.sql";
|
|
1631
|
-
else if (language == "snowflake")
|
|
1632
|
-
ext = "sf.sql";
|
|
1633
|
-
else if (language == "mssql")
|
|
1634
|
-
ext = "ms.sql";
|
|
1635
|
-
else if (language == "graphql")
|
|
1636
|
-
ext = "gql";
|
|
1637
|
-
else if (language == "nativets")
|
|
1638
|
-
ext = "native.ts";
|
|
1639
|
-
else if (language == "frontend")
|
|
1640
|
-
ext = "frontend.js";
|
|
1641
|
-
else if (language == "php")
|
|
1642
|
-
ext = "php";
|
|
1643
|
-
else if (language == "rust")
|
|
1644
|
-
ext = "rs";
|
|
1645
|
-
else if (language == "csharp")
|
|
1646
|
-
ext = "cs";
|
|
1647
|
-
else if (language == "nu")
|
|
1648
|
-
ext = "nu";
|
|
1649
|
-
else if (language == "ansible")
|
|
1650
|
-
ext = "playbook.yml";
|
|
1651
|
-
else if (language == "java")
|
|
1652
|
-
ext = "java";
|
|
1653
|
-
else if (language == "duckdb")
|
|
1654
|
-
ext = "duckdb.sql";
|
|
1655
|
-
// for related places search: ADD_NEW_LANG
|
|
1656
|
-
else
|
|
1657
|
-
ext = "no_ext";
|
|
1658
|
-
return [`${name}.inline_script.`, ext];
|
|
1659
|
-
}
|
|
1660
|
-
return { assignPath };
|
|
1661
|
-
}
|
|
1662
1563
|
export default command;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as dntShim from "
|
|
2
|
-
import * as wmill from "
|
|
3
|
-
import { colors, Command, log, SEP, Table } from "
|
|
4
|
-
import { isSuperset, parseFromFile, removeType, } from "
|
|
5
|
-
import { requireLogin } from "
|
|
6
|
-
import { validatePath, resolveWorkspace } from "
|
|
1
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
3
|
+
import { colors, Command, log, SEP, Table } from "../../../deps.js";
|
|
4
|
+
import { isSuperset, parseFromFile, removeType, } from "../../types.js";
|
|
5
|
+
import { requireLogin } from "../../core/auth.js";
|
|
6
|
+
import { validatePath, resolveWorkspace } from "../../core/context.js";
|
|
7
7
|
async function getTrigger(triggerType, workspace, path) {
|
|
8
8
|
const triggerFunctions = {
|
|
9
9
|
http: wmill.getHttpTrigger,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any
|
|
2
|
-
import * as dntShim from "
|
|
3
|
-
import { requireLogin } from "
|
|
4
|
-
import { isSuperset, removeType, removePathPrefix, } from "
|
|
5
|
-
import { compareInstanceObjects } from "
|
|
6
|
-
import { colors, Command, log, Table, yamlStringify, yamlParseFile, } from "
|
|
7
|
-
import * as wmill from "
|
|
2
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
3
|
+
import { requireLogin } from "../../core/auth.js";
|
|
4
|
+
import { isSuperset, removeType, removePathPrefix, } from "../../types.js";
|
|
5
|
+
import { compareInstanceObjects } from "../instance/instance.js";
|
|
6
|
+
import { colors, Command, log, Table, yamlStringify, yamlParseFile, } from "../../../deps.js";
|
|
7
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
8
8
|
const INSTANCE_USERS_PATH = "instance_users.yaml";
|
|
9
9
|
let instanceUsersPath = INSTANCE_USERS_PATH;
|
|
10
10
|
function checkInstanceUsersPath(opts) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any
|
|
2
|
-
import * as dntShim from "
|
|
3
|
-
import { requireLogin } from "
|
|
4
|
-
import { resolveWorkspace, validatePath } from "
|
|
5
|
-
import { isSuperset, parseFromFile, removeType, } from "
|
|
6
|
-
import { colors, Command, Confirm, log, SEP, Table } from "
|
|
7
|
-
import * as wmill from "
|
|
2
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
3
|
+
import { requireLogin } from "../../core/auth.js";
|
|
4
|
+
import { resolveWorkspace, validatePath } from "../../core/context.js";
|
|
5
|
+
import { isSuperset, parseFromFile, removeType, } from "../../types.js";
|
|
6
|
+
import { colors, Command, Confirm, log, SEP, Table } from "../../../deps.js";
|
|
7
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
8
8
|
async function list(opts) {
|
|
9
9
|
const workspace = await resolveWorkspace(opts);
|
|
10
10
|
await requireLogin(opts);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Command, Confirm, setClient, Table } from "
|
|
2
|
-
import { log } from "
|
|
3
|
-
import { allInstances, getActiveInstance, pickInstance } from "
|
|
4
|
-
import * as wmill from "
|
|
5
|
-
import { pullInstanceConfigs, pushInstanceConfigs } from "
|
|
1
|
+
import { Command, Confirm, setClient, Table } from "../../../deps.js";
|
|
2
|
+
import { log } from "../../../deps.js";
|
|
3
|
+
import { allInstances, getActiveInstance, pickInstance } from "../instance/instance.js";
|
|
4
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
5
|
+
import { pullInstanceConfigs, pushInstanceConfigs } from "../../core/settings.js";
|
|
6
6
|
export async function getInstance(opts) {
|
|
7
7
|
const instances = await allInstances();
|
|
8
8
|
const instanceName = await getActiveInstance(opts);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Command, Table } from "
|
|
2
|
-
import { log } from "
|
|
3
|
-
import * as wmill from "
|
|
4
|
-
import { pickInstance } from "
|
|
1
|
+
import { Command, Table } from "../../../deps.js";
|
|
2
|
+
import { log } from "../../../deps.js";
|
|
3
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
4
|
+
import { pickInstance } from "../instance/instance.js";
|
|
5
5
|
function toPercent(value) {
|
|
6
6
|
return value != undefined ? `${(value * 100).toFixed(1)}%` : '?%';
|
|
7
7
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any
|
|
2
|
-
import * as dntShim from "
|
|
3
|
-
import {
|
|
4
|
-
import { loginInteractive, tryGetLoginInfo } from "
|
|
5
|
-
import { colors, Command, Confirm, Input, log, setClient, Table } from "
|
|
6
|
-
import { requireLogin } from "
|
|
7
|
-
import * as wmill from "
|
|
2
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
3
|
+
import { getActiveWorkspaceConfigFilePath, getWorkspaceConfigFilePath } from "../../../windmill-utils-internal/src/config/config.js";
|
|
4
|
+
import { loginInteractive, tryGetLoginInfo } from "../../core/login.js";
|
|
5
|
+
import { colors, Command, Confirm, Input, log, setClient, Table } from "../../../deps.js";
|
|
6
|
+
import { requireLogin } from "../../core/auth.js";
|
|
7
|
+
import * as wmill from "../../../gen/services.gen.js";
|
|
8
8
|
export async function allWorkspaces(configDirOverride) {
|
|
9
9
|
try {
|
|
10
|
-
const file =
|
|
10
|
+
const file = await getWorkspaceConfigFilePath(configDirOverride);
|
|
11
11
|
const txt = await dntShim.Deno.readTextFile(file);
|
|
12
12
|
return txt
|
|
13
13
|
.split("\n")
|
|
@@ -29,13 +29,14 @@ async function getActiveWorkspaceName(opts) {
|
|
|
29
29
|
return opts?.workspace;
|
|
30
30
|
}
|
|
31
31
|
try {
|
|
32
|
-
|
|
32
|
+
const file = await getActiveWorkspaceConfigFilePath(opts?.configDir);
|
|
33
|
+
return await dntShim.Deno.readTextFile(file);
|
|
33
34
|
}
|
|
34
35
|
catch {
|
|
35
36
|
return undefined;
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
export async function getActiveWorkspace(opts) {
|
|
39
|
+
export async function getActiveWorkspace(opts = undefined) {
|
|
39
40
|
const name = await getActiveWorkspaceName(opts);
|
|
40
41
|
if (!name) {
|
|
41
42
|
return undefined;
|
|
@@ -88,7 +89,8 @@ async function switchC(opts, workspaceName) {
|
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
91
|
export async function setActiveWorkspace(workspaceName, configDirOverride) {
|
|
91
|
-
|
|
92
|
+
const file = await getActiveWorkspaceConfigFilePath(configDirOverride);
|
|
93
|
+
await dntShim.Deno.writeTextFile(file, workspaceName);
|
|
92
94
|
}
|
|
93
95
|
export async function add(opts, workspaceName, workspaceId, remote) {
|
|
94
96
|
if (opts.workspace) {
|
|
@@ -214,41 +216,11 @@ export async function addWorkspace(workspace, opts) {
|
|
|
214
216
|
}
|
|
215
217
|
}
|
|
216
218
|
}
|
|
217
|
-
// Check 2: Same (remote, workspaceId) tuple already exists under different name
|
|
218
|
-
const tupleConflict = existingWorkspaces.find(w => w.remote === workspace.remote &&
|
|
219
|
-
w.workspaceId === workspace.workspaceId &&
|
|
220
|
-
w.name !== workspace.name);
|
|
221
|
-
if (tupleConflict) {
|
|
222
|
-
log.info(colors.red.bold(`❌ Workspace ${workspace.workspaceId} on ${workspace.remote} already exists!`));
|
|
223
|
-
log.info(` Existing name: "${tupleConflict.name}"`);
|
|
224
|
-
log.info(` New name: "${workspace.name}"`);
|
|
225
|
-
log.info(colors.yellow(`\nNote: Backend constraint prevents duplicate (remote, workspaceId) combinations.`));
|
|
226
|
-
if (!isInteractive) {
|
|
227
|
-
// In non-interactive mode (tests, scripts), auto-overwrite with force flag
|
|
228
|
-
if (opts.force) {
|
|
229
|
-
log.info(colors.yellow(`Force flag enabled, overwriting existing workspace "${tupleConflict.name}".`));
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
throw new Error(`Backend constraint violation: (${workspace.remote}, ${workspace.workspaceId}) already exists as "${tupleConflict.name}". Use --force to overwrite.`);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
const overwrite = await Confirm.prompt({
|
|
237
|
-
message: `Do you want to overwrite the existing workspace "${tupleConflict.name}"?`,
|
|
238
|
-
default: false,
|
|
239
|
-
});
|
|
240
|
-
if (!overwrite) {
|
|
241
|
-
log.info(colors.yellow("Operation cancelled."));
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// Remove the conflicting workspace
|
|
246
|
-
await removeWorkspace(tupleConflict.name, true, opts);
|
|
247
|
-
}
|
|
248
219
|
// Remove existing workspace with same name (if updating)
|
|
249
220
|
await removeWorkspace(workspace.name, true, opts);
|
|
250
221
|
// Add the new workspace
|
|
251
|
-
const
|
|
222
|
+
const filePath = await getWorkspaceConfigFilePath(opts.configDir);
|
|
223
|
+
const file = await dntShim.Deno.open(filePath, {
|
|
252
224
|
append: true,
|
|
253
225
|
write: true,
|
|
254
226
|
read: true,
|
|
@@ -270,7 +242,8 @@ export async function removeWorkspace(name, silent, opts) {
|
|
|
270
242
|
if (!silent) {
|
|
271
243
|
log.info(colors.yellow(`Removing existing workspace ${name}`));
|
|
272
244
|
}
|
|
273
|
-
|
|
245
|
+
const filePath = await getWorkspaceConfigFilePath(opts.configDir);
|
|
246
|
+
await dntShim.Deno.writeTextFile(filePath, orgWorkspaces
|
|
274
247
|
.filter((x) => x.name !== name)
|
|
275
248
|
.map((x) => JSON.stringify(x))
|
|
276
249
|
.join("\n") + "\n");
|
|
@@ -287,7 +260,60 @@ async function whoami(_opts) {
|
|
|
287
260
|
const activeName = await getActiveWorkspaceName(_opts);
|
|
288
261
|
log.info("Active: " + colors.green.bold(activeName || "none"));
|
|
289
262
|
}
|
|
263
|
+
async function bind(opts, bindWorkspace) {
|
|
264
|
+
const { isGitRepository, getCurrentGitBranch } = await import("../../utils/git.js");
|
|
265
|
+
if (!isGitRepository()) {
|
|
266
|
+
log.error(colors.red("Not in a Git repository"));
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const branch = opts.branch || getCurrentGitBranch();
|
|
270
|
+
if (!branch) {
|
|
271
|
+
log.error(colors.red("Could not determine current Git branch"));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const { readConfigFile } = await import("../../core/conf.js");
|
|
275
|
+
const config = await readConfigFile();
|
|
276
|
+
const activeWorkspace = await getActiveWorkspace(opts);
|
|
277
|
+
if (!activeWorkspace && bindWorkspace) {
|
|
278
|
+
log.error(colors.red("No active workspace. Use 'wmill workspace add' or 'wmill workspace switch' first"));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
// For unbind, check if branch exists
|
|
282
|
+
if (!bindWorkspace && (!config.git_branches || !config.git_branches[branch])) {
|
|
283
|
+
log.error(colors.red(`Branch '${branch}' not found in wmill.yaml git_branches`));
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// Update the branch configuration with workspace binding
|
|
287
|
+
if (!config.git_branches) {
|
|
288
|
+
config.git_branches = {};
|
|
289
|
+
}
|
|
290
|
+
if (!config.git_branches[branch]) {
|
|
291
|
+
config.git_branches[branch] = { overrides: {} };
|
|
292
|
+
}
|
|
293
|
+
if (bindWorkspace && activeWorkspace) {
|
|
294
|
+
config.git_branches[branch].baseUrl = activeWorkspace.remote;
|
|
295
|
+
config.git_branches[branch].workspaceId = activeWorkspace.workspaceId;
|
|
296
|
+
log.info(colors.green(`✓ Bound branch '${branch}' to workspace '${activeWorkspace.name}'\n` +
|
|
297
|
+
` ${activeWorkspace.workspaceId} on ${activeWorkspace.remote}`));
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
// Unbind
|
|
301
|
+
delete config.git_branches[branch].baseUrl;
|
|
302
|
+
delete config.git_branches[branch].workspaceId;
|
|
303
|
+
log.info(colors.green(`✓ Removed workspace binding from branch '${branch}'`));
|
|
304
|
+
}
|
|
305
|
+
// Write back the updated config
|
|
306
|
+
const { yamlStringify } = await import("../../../deps.js");
|
|
307
|
+
try {
|
|
308
|
+
await dntShim.Deno.writeTextFile("wmill.yaml", yamlStringify(config));
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
log.error(colors.red(`Failed to save configuration: ${error.message}`));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
290
315
|
const command = new Command()
|
|
316
|
+
.alias("profile")
|
|
291
317
|
.description("workspace related commands")
|
|
292
318
|
.action(list)
|
|
293
319
|
.command("switch")
|
|
@@ -310,5 +336,13 @@ const command = new Command()
|
|
|
310
336
|
.action(remove)
|
|
311
337
|
.command("whoami")
|
|
312
338
|
.description("Show the currently active user")
|
|
313
|
-
.action(whoami)
|
|
339
|
+
.action(whoami)
|
|
340
|
+
.command("bind")
|
|
341
|
+
.description("Bind the current Git branch to the active workspace")
|
|
342
|
+
.option("--branch <branch:string>", "Specify branch (defaults to current)")
|
|
343
|
+
.action((opts) => bind(opts, true))
|
|
344
|
+
.command("unbind")
|
|
345
|
+
.description("Remove workspace binding from the current Git branch")
|
|
346
|
+
.option("--branch <branch:string>", "Specify branch (defaults to current)")
|
|
347
|
+
.action((opts) => bind(opts, false));
|
|
314
348
|
export default command;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any
|
|
2
|
-
import { log, setClient } from "
|
|
3
|
-
import * as wmill from "
|
|
2
|
+
import { log, setClient } from "../../deps.js";
|
|
3
|
+
import * as wmill from "../../gen/services.gen.js";
|
|
4
4
|
import { loginInteractive, tryGetLoginInfo } from "./login.js";
|
|
5
5
|
/**
|
|
6
6
|
* Main authentication function - moved from context.ts to break circular dependencies
|
|
@@ -30,7 +30,7 @@ export async function requireLogin(opts) {
|
|
|
30
30
|
throw new Error("Unauthorized: Could not authenticate with the provided credentials");
|
|
31
31
|
}
|
|
32
32
|
// Update workspace token
|
|
33
|
-
const { removeWorkspace, addWorkspace } = await import("
|
|
33
|
+
const { removeWorkspace, addWorkspace } = await import("../commands/workspace/workspace.js");
|
|
34
34
|
removeWorkspace(workspace.name, false, opts);
|
|
35
35
|
workspace.token = newToken;
|
|
36
36
|
addWorkspace(workspace, opts);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
2
|
+
import { log } from "../../deps.js";
|
|
3
|
+
import { getStore } from "./store.js";
|
|
4
|
+
const BRANCH_PROFILES_FILE = "branch-profiles.json";
|
|
5
|
+
export async function getBranchProfilesPath(configDirOverride) {
|
|
6
|
+
return (await getStore("", configDirOverride)) + BRANCH_PROFILES_FILE;
|
|
7
|
+
}
|
|
8
|
+
export async function loadBranchProfiles(configDirOverride) {
|
|
9
|
+
try {
|
|
10
|
+
const path = await getBranchProfilesPath(configDirOverride);
|
|
11
|
+
const content = await dntShim.Deno.readTextFile(path);
|
|
12
|
+
return JSON.parse(content);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// File doesn't exist or invalid JSON - return empty mapping
|
|
16
|
+
return { lastUsed: {} };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function saveBranchProfiles(mapping, configDirOverride) {
|
|
20
|
+
const path = await getBranchProfilesPath(configDirOverride);
|
|
21
|
+
await dntShim.Deno.writeTextFile(path, JSON.stringify(mapping, null, 2));
|
|
22
|
+
}
|
|
23
|
+
export function getBranchProfileKey(branch, baseUrl, workspaceId) {
|
|
24
|
+
// Normalize baseUrl to ensure consistency
|
|
25
|
+
let normalizedUrl;
|
|
26
|
+
try {
|
|
27
|
+
normalizedUrl = new URL(baseUrl).toString();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Fallback to non-normalized URL if parsing fails
|
|
31
|
+
normalizedUrl = baseUrl;
|
|
32
|
+
}
|
|
33
|
+
return `${branch}|${normalizedUrl}|${workspaceId}`;
|
|
34
|
+
}
|
|
35
|
+
export async function getLastUsedProfile(branch, baseUrl, workspaceId, configDirOverride) {
|
|
36
|
+
const mapping = await loadBranchProfiles(configDirOverride);
|
|
37
|
+
const key = getBranchProfileKey(branch, baseUrl, workspaceId);
|
|
38
|
+
return mapping.lastUsed[key];
|
|
39
|
+
}
|
|
40
|
+
export async function setLastUsedProfile(branch, baseUrl, workspaceId, profileName, configDirOverride) {
|
|
41
|
+
const mapping = await loadBranchProfiles(configDirOverride);
|
|
42
|
+
const key = getBranchProfileKey(branch, baseUrl, workspaceId);
|
|
43
|
+
mapping.lastUsed[key] = profileName;
|
|
44
|
+
await saveBranchProfiles(mapping, configDirOverride);
|
|
45
|
+
log.debug(`Saved last used profile for ${key}: ${profileName}`);
|
|
46
|
+
}
|