Skip to content

Commit a5b0dd8

Browse files
committed
Feedback
1 parent 6cdf735 commit a5b0dd8

File tree

2 files changed

+73
-22
lines changed

2 files changed

+73
-22
lines changed

packages/code-link-cli/src/helpers/watcher.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,53 @@ describe("initWatcher", () => {
112112
await watcher.close()
113113
await fs.rm(tmpDir, { recursive: true, force: true })
114114
})
115+
116+
it("keeps using the raw path after sanitization rename fails", async () => {
117+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "framer-watcher-"))
118+
const events: WatcherEvent[] = []
119+
const watcher: Watcher = initWatcher(tmpDir)
120+
watcher.on("change", event => events.push(event))
121+
const rawWatcher = createdWatchers.at(-1)
122+
if (!rawWatcher) throw new Error("No watcher created")
123+
124+
const rawPath = path.join(tmpDir, "bad name!.tsx")
125+
await fs.writeFile(rawPath, "export const Version = 1", "utf-8")
126+
127+
const renameSpy = vi.spyOn(fs, "rename").mockRejectedValueOnce(new Error("rename failed"))
128+
await rawWatcher.__emit("add", rawPath)
129+
await waitForBuffer()
130+
131+
await fs.writeFile(rawPath, "export const Version = 2", "utf-8")
132+
await rawWatcher.__emit("change", rawPath)
133+
134+
const renamedPath = path.join(tmpDir, "GoodName.tsx")
135+
await fs.rename(rawPath, renamedPath)
136+
await rawWatcher.__emit("unlink", rawPath)
137+
await rawWatcher.__emit("add", renamedPath)
138+
139+
expect(events).toEqual([
140+
{
141+
kind: "add",
142+
relativePath: "bad name!.tsx",
143+
content: "export const Version = 1",
144+
},
145+
{
146+
kind: "change",
147+
relativePath: "bad name!.tsx",
148+
content: "export const Version = 2",
149+
},
150+
{
151+
kind: "rename",
152+
relativePath: "GoodName.tsx",
153+
oldRelativePath: "bad name!.tsx",
154+
content: "export const Version = 2",
155+
},
156+
])
157+
158+
renameSpy.mockRestore()
159+
await watcher.close()
160+
await fs.rm(tmpDir, { recursive: true, force: true })
161+
})
115162
})
116163

117164
describe("rename detection", () => {

packages/code-link-cli/src/helpers/watcher.ts

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ export function initWatcher(filesDir: string): Watcher {
151151
}
152152

153153
/**
154-
* Resolves the sanitized relative path for a given absolute path.
155-
* On "add", renames files on disk if they don't match sanitization rules.
154+
* Resolves the relative path identity for a watcher event.
155+
* Only "add" may rewrite that identity by successfully sanitizing on disk.
156156
*/
157157
const resolveRelativePath = async (
158158
kind: "add" | "change" | "delete",
@@ -163,28 +163,32 @@ export function initWatcher(filesDir: string): Watcher {
163163
}
164164

165165
const rawRelativePath = normalizePath(getRelativePath(filesDir, absolutePath))
166-
const sanitized = sanitizeFilePath(rawRelativePath, false)
167-
const relativePath = sanitized.path
166+
let relativePath = rawRelativePath
168167

169168
let effectiveAbsolutePath = absolutePath
170-
if (relativePath !== rawRelativePath && kind === "add") {
171-
const newAbsolutePath = path.join(filesDir, relativePath)
172-
try {
173-
await fs.mkdir(path.dirname(newAbsolutePath), { recursive: true })
174-
await fs.rename(absolutePath, newAbsolutePath)
175-
debug(`Renamed ${rawRelativePath} -> ${relativePath}`)
176-
effectiveAbsolutePath = newAbsolutePath
177-
178-
// Suppress the echo events chokidar will fire for this rename
179-
recentSanitizations.add(rawRelativePath) // upcoming unlink echo
180-
recentSanitizations.add(relativePath) // upcoming add echo
181-
setTimeout(() => {
182-
recentSanitizations.delete(rawRelativePath)
183-
recentSanitizations.delete(relativePath)
184-
}, RENAME_BUFFER_MS * 3)
185-
} catch (err) {
186-
warn(`Failed to rename ${rawRelativePath}`, err)
187-
return { relativePath: rawRelativePath, effectiveAbsolutePath: absolutePath }
169+
if (kind === "add") {
170+
const sanitized = sanitizeFilePath(rawRelativePath, false)
171+
if (sanitized.path !== rawRelativePath) {
172+
const nextRelativePath = sanitized.path
173+
const newAbsolutePath = path.join(filesDir, nextRelativePath)
174+
try {
175+
await fs.mkdir(path.dirname(newAbsolutePath), { recursive: true })
176+
await fs.rename(absolutePath, newAbsolutePath)
177+
debug(`Renamed ${rawRelativePath} -> ${nextRelativePath}`)
178+
relativePath = nextRelativePath
179+
effectiveAbsolutePath = newAbsolutePath
180+
181+
// Suppress the echo events chokidar will fire for this rename
182+
recentSanitizations.add(rawRelativePath) // upcoming unlink echo
183+
recentSanitizations.add(nextRelativePath) // upcoming add echo
184+
setTimeout(() => {
185+
recentSanitizations.delete(rawRelativePath)
186+
recentSanitizations.delete(nextRelativePath)
187+
}, RENAME_BUFFER_MS * 3)
188+
} catch (err) {
189+
warn(`Failed to rename ${rawRelativePath}`, err)
190+
return { relativePath: rawRelativePath, effectiveAbsolutePath: absolutePath }
191+
}
188192
}
189193
}
190194

0 commit comments

Comments
 (0)