diff --git a/cli/src/commands/sync/sync.ts b/cli/src/commands/sync/sync.ts index 3519cfe4bc..358d08f9c7 100644 --- a/cli/src/commands/sync/sync.ts +++ b/cli/src/commands/sync/sync.ts @@ -104,6 +104,13 @@ import { getNonDottedPaths, } from "../../utils/resource_folders.ts"; +// Parse cliBehavior version string (e.g. "v1", "v2") into a number. Returns 0 if absent/invalid. +export function parseCliBehavior(value?: string): number { + if (!value) return 0; + const match = value.match(/^v(\d+)$/); + return match ? parseInt(match[1], 10) : 0; +} + // Merge CLI options with effective settings, preserving CLI flags as overrides function mergeCliWithEffectiveOptions< T extends GlobalOptions & SyncOptions & { repository?: string }, @@ -1855,7 +1862,7 @@ export async function pull( resourceTypeToFormatExtension, resourceTypeToIsFileset, true, - parseFloat(opts.version ?? "0") >= 0.1, + parseCliBehavior(opts.cliBehavior) >= 1, ); const local = !opts.stateful @@ -2385,7 +2392,7 @@ export async function push( resourceTypeToFormatExtension, resourceTypeToIsFileset, false, - parseFloat(opts.version ?? "0") >= 0.1, + parseCliBehavior(opts.cliBehavior) >= 1, ); const local = await FSFSElement(path.join(process.cwd(), ""), codebases, false); @@ -2586,7 +2593,7 @@ export async function push( // Build permissioned_as context (only when respectVirtualUserPermissions is enabled) let permissionedAsContext: PermissionedAsContext | undefined = undefined; - if (opts.version && parseFloat(opts.version) >= 0.1) { + if (parseCliBehavior(opts.cliBehavior) >= 1) { const user = await wmill.whoami({ workspace: workspace.workspaceId }); const userIsAdminOrDeployer = user.is_admin || (user.groups ?? []).includes("wm_deployers"); diff --git a/cli/src/core/conf.ts b/cli/src/core/conf.ts index f49d501276..9177209b0d 100644 --- a/cli/src/core/conf.ts +++ b/cli/src/core/conf.ts @@ -104,7 +104,7 @@ export interface SyncOptions { lint?: boolean; locksRequired?: boolean; defaultPermissionedAs?: PermissionedAsRule[]; - version?: string; + cliBehavior?: string; } export interface Codebase { @@ -353,7 +353,7 @@ export const DEFAULT_SYNC_OPTIONS: Readonly< | "includeSettings" | "includeKey" | "nonDottedPaths" - | "version" + | "cliBehavior" > > > = { @@ -377,7 +377,7 @@ export const DEFAULT_SYNC_OPTIONS: Readonly< includeKey: false, skipWorkspaceDependencies: false, nonDottedPaths: false, - version: "0.1", + cliBehavior: "v1", } as const; export async function mergeConfigWithConfigFile( diff --git a/cli/test/cli_behavior.test.ts b/cli/test/cli_behavior.test.ts new file mode 100644 index 0000000000..8ddf254f78 --- /dev/null +++ b/cli/test/cli_behavior.test.ts @@ -0,0 +1,39 @@ +import { expect, test, describe } from "bun:test"; +import { parseCliBehavior } from "../src/commands/sync/sync.ts"; + +describe("parseCliBehavior", () => { + test("parses v1 to 1", () => { + expect(parseCliBehavior("v1")).toBe(1); + }); + + test("parses v2 to 2", () => { + expect(parseCliBehavior("v2")).toBe(2); + }); + + test("parses v10 to 10", () => { + expect(parseCliBehavior("v10")).toBe(10); + }); + + test("returns 0 for undefined", () => { + expect(parseCliBehavior(undefined)).toBe(0); + }); + + test("returns 0 for empty string", () => { + expect(parseCliBehavior("")).toBe(0); + }); + + test("returns 0 for invalid format", () => { + expect(parseCliBehavior("0.1")).toBe(0); + expect(parseCliBehavior("1")).toBe(0); + expect(parseCliBehavior("version1")).toBe(0); + expect(parseCliBehavior("V1")).toBe(0); + }); + + test("version comparisons work correctly", () => { + expect(parseCliBehavior("v1") >= 1).toBe(true); + expect(parseCliBehavior("v2") >= 1).toBe(true); + expect(parseCliBehavior(undefined) >= 1).toBe(false); + expect(parseCliBehavior("v1") >= 2).toBe(false); + expect(parseCliBehavior("v2") >= 2).toBe(true); + }); +});