Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d5f8a79
split unit U1 of PR 1833 (issue 1375)
Oct 5, 2026
aa0cdab
fix(file-safety): close the pre-merge findings on the publish primiti…
Oct 5, 2026
c4120b0
fix(file-safety): propagate a non-ENOENT lstat failure in resolvePubl…
Oct 5, 2026
97b599d
fix(file-safety): keep the rollback pair typed and the mock stand-ins…
Oct 5, 2026
58f803d
fix(file-safety): do not roll the backup back over an already committ…
Oct 5, 2026
63dcbe6
refactor(file-safety): reuse errorCode and assert the DACL save order
Oct 5, 2026
20a61fb
test(file-safety): make the DACL order test type-safe and assert real…
Oct 5, 2026
734ad85
fix(file-safety): keep the publish error message in RollbackFailureError
Oct 5, 2026
08d2173
test(file-safety): assert the exact staging directory removed after a…
Oct 5, 2026
f6f5b9b
test: re-run mocked e2e and the ubuntu lane - no source change since …
Oct 5, 2026
e1eee2b
fix(file-safety): give the Windows DACL dump a per-write name
Oct 5, 2026
c6784a4
fix(file-safety): do not restore a backup over a concurrent publish
Oct 7, 2026
bd1b7ba
fix(file-safety): keep the target present by backing it up with a dur…
Oct 7, 2026
44b8ea8
test: re-trigger the windows unit shard - the run exited 1 after both…
Oct 7, 2026
d90bc62
fix(file-safety): remove a partial backup when the backup copy or its…
Oct 7, 2026
94843f2
fix(file-safety): refuse a staging path that is the target, and cover…
Oct 7, 2026
d252152
fix(file-safety): report a failed DACL restore, and cover the primiti…
Oct 7, 2026
8574b8d
test(file-safety): drop the duplicated failed-commit case and cover t…
Oct 7, 2026
97cbd33
fix(file-safety): remove the backup copy after a post-commit failure …
Oct 7, 2026
eb68002
fix(file-safety): make the backup copy writable before fsyncing it
Oct 7, 2026
9a3a600
fix(file-safety): create the backup privately before its content exists
Oct 7, 2026
f9aef70
fix(file-safety): do not read a failed target lstat as a missing target
Oct 7, 2026
04a2bd1
fix(file-safety): compare staging and target identity with bigint stats
Oct 7, 2026
17e3664
test(file-safety): pin the bigint options in the staging-identity tests
Oct 7, 2026
a26782a
fix(file-safety): report a Windows replacement whose DACL was not pre…
Oct 7, 2026
c1d4bc8
fix(file-safety): keep DACL warning delivery from failing the save
Oct 7, 2026
95ee4e7
fix(file-safety): handle async warning sinks and confine before mkdir
Oct 7, 2026
af76bc6
fix(file-safety): retry the post-commit backup cleanup and report a l…
Oct 8, 2026
6d8d69f
fix(file-safety): carry the leftover backup path when cleanup fails o…
Oct 8, 2026
30110ea
fix(file-safety): guarantee the seed descriptor close, and pin the al…
Oct 8, 2026
03dc013
fix(file-safety): do not retry a failed seed-descriptor close
Oct 8, 2026
9067b20
chore(file-safety): drop the dead committed flag and correct the cove…
Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as fs from "fs/promises"
import * as os from "os"
import * as path from "path"

import { safeWriteText } from "../safeWriteText"

// No fs mocks in this file: the point is to assert what a real filesystem ends up
// holding after a publish attempt, which the mocked spec cannot show. The failure is
// provoked with real filesystem semantics rather than with a stubbed call.
describe("safeWriteText against a real filesystem", () => {
let dir: string

beforeEach(async () => {
dir = await fs.mkdtemp(path.join(os.tmpdir(), "safe-write-text-int-"))
})

afterEach(async () => {
await fs.rm(dir, { recursive: true, force: true })
})

// The commit-rename failure mode is covered deterministically in safeWriteText.spec.ts
// ('a failed commit does not move the target, so nothing has to be rolled back'): on a real
// filesystem there is no portable way to make only the rename fail - the ESM fs namespace
// cannot be spied, and read-only-parent / sticky-bit / cross-device setups are not portable.
it("publishes the new bytes and leaves no staging or backup residue", async () => {
const targetPath = path.join(dir, "target.txt")
await fs.writeFile(targetPath, "old bytes")

// No platform override: the real platform's own durability and ACL steps run.
// A failed icacls restore in a throwaway temp directory is reported, not thrown,
// so the publish still lands.
await safeWriteText(targetPath, "new bytes", { backup: true })

expect(await fs.readFile(targetPath, "utf8")).toBe("new bytes")
expect(await fs.readdir(dir)).toEqual(["target.txt"])
})

it("leaves the target bytes untouched when the backup copy cannot be made", async () => {
// A regular file cannot be renamed over a directory, so the step-3 backup copy fails
// on a real filesystem with no mocking. Note what this case does NOT cover: the commit
// rename is never reached, because the backup failure aborts the write first.
const targetPath = path.join(dir, "target-dir")
await fs.mkdir(targetPath)
const inside = path.join(targetPath, "payload.txt")
await fs.writeFile(inside, "original bytes")

await expect(safeWriteText(targetPath, "new data", { backup: true })).rejects.toThrow()

// The directory and its content are exactly as they were, and no backup copy
// or staging directory was left behind next to them.
expect(await fs.readFile(inside, "utf8")).toBe("original bytes")
expect(await fs.readdir(dir)).toEqual(["target-dir"])
})
})
Loading
Loading