From c31c62a4b615ac8c0cd424fb7522bfe7a95b17f8 Mon Sep 17 00:00:00 2001 From: 2022117144 <162019766+2022117144@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:16:46 +0800 Subject: [PATCH] fix(vscode): update file sources when flows are moved --- pnpm-lock.yaml | 3 + vscode/docs/file-move-demo-preview.png | Bin 0 -> 42683 bytes vscode/docs/file-move-demo.mp4 | Bin 0 -> 56301 bytes vscode/docs/file-moves.md | 44 ++++++++++ vscode/package.json | 5 +- vscode/src/extension.ts | 2 + vscode/src/flowRename.ts | 40 +++++++++ vscode/src/remapFlowPaths.ts | 55 ++++++++++++ .../src/test/flowRename.integration.test.ts | 62 ++++++++++++++ vscode/src/test/remapFlowPaths.test.ts | 79 ++++++++++++++++++ 10 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 vscode/docs/file-move-demo-preview.png create mode 100644 vscode/docs/file-move-demo.mp4 create mode 100644 vscode/docs/file-moves.md create mode 100644 vscode/src/flowRename.ts create mode 100644 vscode/src/remapFlowPaths.ts create mode 100644 vscode/src/test/flowRename.integration.test.ts create mode 100644 vscode/src/test/remapFlowPaths.test.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 40423ef1..13c9694d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -563,6 +563,9 @@ importers: walker: specifier: ^1.0.8 version: 1.0.8 + yaml: + specifier: ^2.3.1 + version: 2.8.0 devDependencies: '@playwright/test': specifier: ^1.53.2 diff --git a/vscode/docs/file-move-demo-preview.png b/vscode/docs/file-move-demo-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..bfce63c025b95797f715adf91f20a78095c0cf53 GIT binary patch literal 42683 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ⅈf9?-+odpecx(WWsOi&e|YVO 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 literal 0 HcmV?d00001 diff --git a/vscode/docs/file-moves.md b/vscode/docs/file-moves.md new file mode 100644 index 00000000..25e20b99 --- /dev/null +++ b/vscode/docs/file-moves.md @@ -0,0 +1,44 @@ +# File moves and flow references + +Moving or renaming files through VS Code's Explorer now updates the current +flow format's `source: { type: file, data: ... }` references in `.flyde` documents. +It also rebases a flow's outgoing references when that flow itself moves. +Folder moves and multiple renames in one operation use the original paths; +package sources are left alone. YAML comments and unsaved document edits are +preserved. Invalid/unreadable flows are skipped with a warning. + +This participates in `workspace.onWillRenameFiles`, so the text edits are part +of VS Code's rename operation. Renames performed externally (for example, by a +shell or a Git checkout) do not generate that event and are outside this patch. +The handler does not migrate legacy `imports` documents into the current format. + +## Demonstration + +[Short animated test walkthrough](file-move-demo.mp4) + +The video illustrates the recorded extension-host results; it is not a screen +recording of the full Flyde webview. To reproduce interactively, import a child +flow in a parent flow, rename the child in Explorer, then inspect the parent's +file source. Moving the parent into a subdirectory should rebase its relative +path. Moving their common folder should leave their relative relationship intact. + +## Validation + +- TypeScript 5.5.4 strict compilation of both new modules and their tests. +- 12 Mocha path-remapping tests (including swaps, folder boundaries, nested + inline nodes, package references, comments, absolute paths and invalid YAML). +- Four tests run in an actual isolated VS Code 1.87.2 extension host using + `WorkspaceEdit.renameFile`: target move, parent move, folder move and a dirty + parent document. All four passed. +- YAML dependency uses the existing lockfile's 2.8.0 resolution. + +The repository extension-test runner discovers the new `*.test.ts` files after +compilation. In a fully installed workspace, run the existing VS Code test +workflow (`pnpm --filter flyde-vscode test`, including its normal pretest build). +Validation here compiled the new modules separately and loaded their real event +handler in a small isolated extension host; the full workspace/webview build +was not run because dependency resolution encountered connection resets. +No full-editor visual or external-file-watcher behavior is claimed. + +This is an AI-assisted contribution. No private credentials or backend +configuration are included. diff --git a/vscode/package.json b/vscode/package.json index 3f1678cc..840ef292 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -254,7 +254,8 @@ "socket.io": "^4.5.1", "ts-node": "^10.9.2", "use-debounce": "^8.0.4", - "walker": "^1.0.8" + "walker": "^1.0.8", + "yaml": "^2.3.1" }, "packageManager": "yarn@3.3.1" -} \ No newline at end of file +} diff --git a/vscode/src/extension.ts b/vscode/src/extension.ts index ea022727..94403a07 100644 --- a/vscode/src/extension.ts +++ b/vscode/src/extension.ts @@ -1,6 +1,7 @@ // The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below import * as vscode from "vscode"; +import { registerFlowRenameHandler } from "./flowRename"; import { FlydeEditorEditorProvider } from "./flydeEditor"; import * as execa from "execa"; @@ -29,6 +30,7 @@ let process: execa.ExecaChildProcess | undefined; const FLYDE_DEFAULT_SERVER_PORT = 8545; export function activate(context: vscode.ExtensionContext) { + registerFlowRenameHandler(context); // eslint-disable-next-line @typescript-eslint/naming-convention const { Uri } = vscode; const { fs } = vscode.workspace; diff --git a/vscode/src/flowRename.ts b/vscode/src/flowRename.ts new file mode 100644 index 00000000..7d29c864 --- /dev/null +++ b/vscode/src/flowRename.ts @@ -0,0 +1,40 @@ +import * as vscode from "vscode"; +import { remapFlowPaths } from "./remapFlowPaths"; + +export function registerFlowRenameHandler(context: Pick): void { + context.subscriptions.push(vscode.workspace.onWillRenameFiles((event) => { + event.waitUntil((async () => { + const moves = event.files + .filter(({ oldUri, newUri }) => oldUri.scheme === "file" && newUri.scheme === "file") + .map(({ oldUri, newUri }) => ({ oldPath: oldUri.fsPath, newPath: newUri.fsPath })); + if (!moves.length) { return; } + const diskFlows = await vscode.workspace.findFiles("**/*.flyde", "**/node_modules/**"); + const flows = new Map(diskFlows.map((uri) => [uri.toString(), uri])); + // Include dirty and open flows that have not yet been written to disk. + for (const document of vscode.workspace.textDocuments) { + if (document.uri.scheme === "file" && document.uri.path.endsWith(".flyde")) { + flows.set(document.uri.toString(), document.uri); + } + } + const edit = new vscode.WorkspaceEdit(); + const failed: string[] = []; + for (const uri of flows.values()) { + try { + const document = await vscode.workspace.openTextDocument(uri); + const text = document.getText(); + const replacement = remapFlowPaths(text, uri.fsPath, moves); + if (replacement !== undefined) { + edit.replace(uri, new vscode.Range(document.positionAt(0), document.positionAt(text.length)), replacement); + } + } catch { + // One invalid/unreadable flow must not prevent updating valid flows. + failed.push(vscode.workspace.asRelativePath(uri)); + } + } + if (failed.length) { + void vscode.window.showWarningMessage(`Flyde could not update file references in: ${failed.join(", ")}`); + } + return edit; + })()); + })); +} diff --git a/vscode/src/remapFlowPaths.ts b/vscode/src/remapFlowPaths.ts new file mode 100644 index 00000000..c01a3cf1 --- /dev/null +++ b/vscode/src/remapFlowPaths.ts @@ -0,0 +1,55 @@ +import * as path from "path"; +import { isMap, isScalar, visit, parseDocument } from "yaml"; + +export interface FileMove { + oldPath: string; + newPath: string; +} + +// All moves are evaluated against the original paths, so swaps and chained +// renames in one VS Code operation are not applied twice. +export function movedPath(file: string, moves: readonly FileMove[]): string { + const match = moves + .filter(({ oldPath }) => { + const relative = path.relative(oldPath, file); + return relative === "" || + (!path.isAbsolute(relative) && relative !== ".." && + !relative.startsWith(`..${path.sep}`)); + }) + .sort((a, b) => b.oldPath.length - a.oldPath.length)[0]; + return match ? path.join(match.newPath, path.relative(match.oldPath, file)) : file; +} + +/** Rebase file sources, including inline/nested nodes, without migrating a flow. */ +export function remapFlowPaths( + text: string, + flowPath: string, + moves: readonly FileMove[] +): string | undefined { + const document = parseDocument(text); + if (document.errors.length) { + throw new Error(document.errors.map((error) => error.message).join("; ")); + } + const newFlowPath = movedPath(flowPath, moves); + let changed = false; + visit(document, { + Map(_key, node) { + // A file source is deliberately distinguished from package and inline + // sources: similarly named user configuration must not be rewritten. + const source = node.get("source", true); + if (!isMap(source) || source.get("type") !== "file") { return; } + const data = source.get("data", true); + if (!isScalar(data) || typeof data.value !== "string" || !data.value) { return; } + const oldTarget = path.resolve(path.dirname(flowPath), data.value); + const newTarget = movedPath(oldTarget, moves); + if (oldTarget === newTarget && flowPath === newFlowPath) { return; } + // Preserve absolute references; relative paths in .flyde files use '/'. + let next = path.isAbsolute(data.value) + ? newTarget + : path.relative(path.dirname(newFlowPath), newTarget).split(path.sep).join("/"); + if (!path.isAbsolute(data.value) && !next.startsWith(".")) { next = `./${next}`; } + if (next !== data.value) { data.value = next; changed = true; } + }, + }); + return changed ? document.toString() : undefined; +} diff --git a/vscode/src/test/flowRename.integration.test.ts b/vscode/src/test/flowRename.integration.test.ts new file mode 100644 index 00000000..0dd97baa --- /dev/null +++ b/vscode/src/test/flowRename.integration.test.ts @@ -0,0 +1,62 @@ +import * as vscode from "vscode"; +import * as fs from "fs"; +import * as os from "os"; +import * as path from "path"; +import * as assert from "assert"; +import { registerFlowRenameHandler } from "../flowRename"; + +suite("flow rename extension host", () => { + for (const scenario of ["target", "parent", "folder", "dirty"]) { + test(scenario, async () => { + const dir = fs.mkdtempSync(path.join(os.tmpdir(), "flyde-rename-")); + const parent = path.join(dir, "Parent.flyde"); + const child = path.join(dir, "Child.flyde"); + fs.writeFileSync(child, "node: {}\n"); + fs.writeFileSync(parent, "# preserved\nnode:\n instances:\n - source:\n type: file\n data: ./Child.flyde\n"); + const subscriptions: vscode.Disposable[] = []; + registerFlowRenameHandler({ subscriptions }); + try { + const document = await vscode.workspace.openTextDocument(parent); + if (scenario === "dirty") { + const typing = new vscode.WorkspaceEdit(); + typing.insert(document.uri, new vscode.Position(0, 0), "# unsaved edit\n"); + assert.ok(await vscode.workspace.applyEdit(typing)); + assert.ok(document.isDirty); + } + let from = child; + let to = path.join(dir, "New.flyde"); + let expected = "./New.flyde"; + let resultPath = parent; + if (scenario === "parent") { + from = parent; + to = path.join(dir, "nested", "Parent.flyde"); + fs.mkdirSync(path.dirname(to)); + expected = "../Child.flyde"; + resultPath = to; + } else if (scenario === "folder") { + from = dir; + to = `${dir}-moved`; + expected = "./Child.flyde"; + resultPath = path.join(to, "Parent.flyde"); + } + const move = new vscode.WorkspaceEdit(); + move.renameFile(vscode.Uri.file(from), vscode.Uri.file(to)); + assert.ok(await vscode.workspace.applyEdit(move)); + const result = await vscode.workspace.openTextDocument(resultPath); + assert.ok(result.getText().includes(`data: ${expected}`), result.getText()); + assert.ok(result.getText().includes("# preserved")); + if (scenario === "dirty") { + assert.ok(result.getText().includes("# unsaved edit")); + assert.ok(result.isDirty); + } + await result.save(); + } finally { + subscriptions.forEach((subscription) => subscription.dispose()); + fs.rmSync(dir, { recursive: true, force: true }); + if (scenario === "folder") { + fs.rmSync(`${dir}-moved`, { recursive: true, force: true }); + } + } + }); + } +}); diff --git a/vscode/src/test/remapFlowPaths.test.ts b/vscode/src/test/remapFlowPaths.test.ts new file mode 100644 index 00000000..751f43cc --- /dev/null +++ b/vscode/src/test/remapFlowPaths.test.ts @@ -0,0 +1,79 @@ +import * as assert from "assert"; +import * as path from "path"; +import { parse } from "yaml"; +import { movedPath, remapFlowPaths } from "../remapFlowPaths"; + +suite("flow file moves", () => { + const root = path.resolve("test-workspace"); + const file = (relative: string) => path.join(root, relative); + const flow = (target: string, type = "file") => + `# keep this comment\nnode:\n instances:\n - id: child\n source:\n type: ${type}\n data: '${target}' # source comment\n`; + const source = (text: string) => parse(text).node.instances[0].source.data; + test("renames a referenced file and preserves comments", () => { + const result = remapFlowPaths(flow("./Child.flyde"), file("Parent.flyde"), [ + { oldPath: file("Child.flyde"), newPath: file("nodes/Renamed.flyde") }, + ])!; + assert.strictEqual(source(result), "./nodes/Renamed.flyde"); + assert.ok(result.includes("# keep this comment")); + assert.ok(result.includes("# source comment")); + }); + test("rebases outgoing references when the parent flow moves", () => { + const result = remapFlowPaths(flow("./Child.flyde"), file("Parent.flyde"), [ + { oldPath: file("Parent.flyde"), newPath: file("flows/Parent.flyde") }, + ])!; + assert.strictEqual(source(result), "../Child.flyde"); + }); + test("a whole folder move keeps relationships within it unchanged", () => { + assert.strictEqual(remapFlowPaths(flow("./Child.flyde"), file("old/Parent.flyde"), [ + { oldPath: file("old"), newPath: file("new") }, + ]), undefined); + }); + test("folder moves update incoming references", () => { + assert.strictEqual(source(remapFlowPaths(flow("./old/Child.flyde"), file("Parent.flyde"), [ + { oldPath: file("old"), newPath: file("new") }, + ])!), "./new/Child.flyde"); + }); + test("folder names are matched by path boundary, not string prefix", () => { + assert.strictEqual(movedPath(file("nodes-other/Child.flyde"), [ + { oldPath: file("nodes"), newPath: file("renamed") }, + ]), file("nodes-other/Child.flyde")); + }); + test("simultaneous swaps are applied only once", () => { + assert.strictEqual(source(remapFlowPaths(flow("./A.flyde"), file("Parent.flyde"), [ + { oldPath: file("A.flyde"), newPath: file("B.flyde") }, + { oldPath: file("B.flyde"), newPath: file("A.flyde") }, + ])!), "./B.flyde"); + }); + test("nested inline flows are visited", () => { + const text = `node:\n instances:\n - node:\n instances:\n - source:\n type: file\n data: ./Child.flyde\n`; + const result = remapFlowPaths(text, file("Parent.flyde"), [ + { oldPath: file("Child.flyde"), newPath: file("New.flyde") }, + ])!; + assert.strictEqual(parse(result).node.instances[0].node.instances[0].source.data, "./New.flyde"); + }); + test("package references are not modified", () => { + assert.strictEqual(remapFlowPaths(flow("./Child.flyde", "package"), file("Parent.flyde"), [ + { oldPath: file("Child.flyde"), newPath: file("New.flyde") }, + ]), undefined); + }); + test("unrelated moves return no edit", () => { + assert.strictEqual(remapFlowPaths(flow("./Child.flyde"), file("Parent.flyde"), [ + { oldPath: file("Other.flyde"), newPath: file("New.flyde") }, + ]), undefined); + }); + test("absolute references remain absolute", () => { + const target = file("Child.flyde"); + assert.strictEqual(source(remapFlowPaths(flow(target), file("Parent.flyde"), [ + { oldPath: target, newPath: file("New.flyde") }, + ])!), file("New.flyde")); + }); + test("more specific nested moves win", () => { + assert.strictEqual(movedPath(file("old/Child.flyde"), [ + { oldPath: file("old"), newPath: file("new") }, + { oldPath: file("old/Child.flyde"), newPath: file("special.flyde") }, + ]), file("special.flyde")); + }); + test("invalid YAML is rejected without producing replacement text", () => { + assert.throws(() => remapFlowPaths("node: [", file("Parent.flyde"), [])); + }); +});