From 05d4d6dd4818171dde915a506dbfca1eebf7a655 Mon Sep 17 00:00:00 2001 From: Travis <165698+travisp@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:36:41 -0400 Subject: [PATCH] fix(cli): preserve non-dotted flow lock filenames --- cli/src/commands/flow/flow_metadata.ts | 9 ++- cli/test/unified_generate_metadata.test.ts | 78 +++++++++++++++++++++- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/cli/src/commands/flow/flow_metadata.ts b/cli/src/commands/flow/flow_metadata.ts index 908e3c63dc..6a9040094f 100644 --- a/cli/src/commands/flow/flow_metadata.ts +++ b/cli/src/commands/flow/flow_metadata.ts @@ -29,7 +29,10 @@ import { FlowFile } from "./flow.ts"; import { FlowValue } from "../../../gen/types.gen.ts"; import { replaceInlineScripts } from "../../../windmill-utils-internal/src/inline-scripts/replacer.ts"; import { workspaceDependenciesLanguages } from "../../utils/script_common.ts"; -import { extractNameFromFolder, getFolderSuffix } from "../../utils/resource_folders.ts"; +import { + extractNameFromFolder, + getNonDottedPaths, +} from "../../utils/resource_folders.ts"; const TOP_HASH = "__flow_hash"; async function generateFlowHash( @@ -157,7 +160,9 @@ export async function generateFlowLockInternal( filteredDeps ); - const lockAssigner = newPathAssigner(opts.defaultTs ?? "bun"); + const lockAssigner = newPathAssigner(opts.defaultTs ?? "bun", { + skipInlineScriptSuffix: getNonDottedPaths(), + }); const inlineScripts = extractInlineScriptsForFlows( flowValue.value.modules, {}, diff --git a/cli/test/unified_generate_metadata.test.ts b/cli/test/unified_generate_metadata.test.ts index 5cd240dce9..5ed7bdb21a 100644 --- a/cli/test/unified_generate_metadata.test.ts +++ b/cli/test/unified_generate_metadata.test.ts @@ -8,7 +8,7 @@ import { expect, test, describe } from "bun:test"; import { withTestBackend } from "./test_backend.ts"; import { addWorkspace } from "../workspace.ts"; -import { writeFile } from "node:fs/promises"; +import { mkdir, readFile, stat, writeFile } from "node:fs/promises"; import { createLocalScript, createLocalFlow, @@ -19,7 +19,12 @@ import { /** * Helper to set up a workspace with wmill.yaml */ -async function setupWorkspace(backend: any, tempDir: string, workspaceName: string) { +async function setupWorkspace( + backend: any, + tempDir: string, + workspaceName: string, + nonDottedPaths = false +) { const testWorkspace = { remote: backend.baseUrl, workspaceId: backend.workspace, @@ -29,11 +34,52 @@ async function setupWorkspace(backend: any, tempDir: string, workspaceName: stri await addWorkspace(testWorkspace, { force: true, configDir: backend.testConfigDir }); await writeFile(`${tempDir}/wmill.yaml`, `defaultTs: bun -includes: +${nonDottedPaths ? "nonDottedPaths: true\n" : ""}includes: - "**" excludes: []`, "utf-8"); } +async function createLocalNonDottedFlow(tempDir: string, name: string) { + const flowDir = `${tempDir}/f/test/${name}__flow`; + await mkdir(flowDir, { recursive: true }); + + await writeFile( + `${flowDir}/a.ts`, + `export async function main() {\n return "Hello from flow ${name}";\n}`, + "utf-8" + ); + + await writeFile( + `${flowDir}/flow.yaml`, + `summary: "${name} flow" +description: "A flow for testing" +value: + modules: + - id: a + value: + type: rawscript + content: "!inline a.ts" + language: bun + input_transforms: {} +schema: + $schema: "https://json-schema.org/draft/2020-12/schema" + type: object + properties: {} + required: [] +`, + "utf-8" + ); +} + +async function fileExists(filePath: string): Promise { + try { + await stat(filePath); + return true; + } catch { + return false; + } +} + // ============================================================================= // Main test: processes scripts, flows, and apps together // ============================================================================= @@ -156,6 +202,32 @@ describe("generate-metadata flags", () => { }); }); + test("--lock-only preserves non-dotted flow filenames", async () => { + await withTestBackend(async (backend, tempDir) => { + await setupWorkspace(backend, tempDir, "lock_only_non_dotted_test", true); + + await createLocalNonDottedFlow(tempDir, "my_flow"); + + const result = await backend.runCLICommand( + ["generate-metadata", "--yes", "--lock-only"], + tempDir, + "lock_only_non_dotted_test" + ); + + expect(result.code).toEqual(0); + + const flowDir = `${tempDir}/f/test/my_flow__flow`; + const flowYaml = await readFile(`${flowDir}/flow.yaml`, "utf-8"); + + expect(flowYaml).toContain("!inline a.ts"); + expect(flowYaml).toContain("!inline a.lock"); + expect(flowYaml).not.toContain(".inline_script."); + expect(await fileExists(`${flowDir}/a.lock`)).toEqual(true); + expect(await fileExists(`${flowDir}/a.inline_script.ts`)).toEqual(false); + expect(await fileExists(`${flowDir}/a.inline_script.lock`)).toEqual(false); + }); + }); + test("--schema-only only processes scripts (skips flows and apps)", async () => { await withTestBackend(async (backend, tempDir) => { await setupWorkspace(backend, tempDir, "schema_only_test");