Compare commits

...

1 Commits

Author SHA1 Message Date
Claude Bot
c4c80d8051 fix(FileSink): truncate existing file when using writer()
The FileSink's flags() method was ignoring the truncate option, which
defaults to true. This caused existing files to not be truncated when
writing via file.writer(), so if the new content was shorter than the
old content, the tail of the old content would remain.

Closes #25968

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 09:49:54 +00:00
2 changed files with 55 additions and 3 deletions

View File

@@ -54,9 +54,11 @@ pub const Options = struct {
mode: bun.Mode = 0o664,
pub fn flags(this: *const Options) i32 {
_ = this;
return bun.O.NONBLOCK | bun.O.CLOEXEC | bun.O.CREAT | bun.O.WRONLY;
var f: i32 = bun.O.NONBLOCK | bun.O.CLOEXEC | bun.O.CREAT | bun.O.WRONLY;
if (this.truncate) {
f |= bun.O.TRUNC;
}
return f;
}
};

View File

@@ -0,0 +1,50 @@
import { expect, test } from "bun:test";
import { bunEnv, bunExe, tempDir } from "harness";
test("FileSink truncates existing file", async () => {
using dir = tempDir("issue-25968", {});
const filePath = `${dir}/file.txt`;
// Write initial long content
const file = Bun.file(filePath);
await Bun.write(file, "Long content");
// Write shorter content using writer
const writer = file.writer();
writer.write("Short");
writer.end();
// Verify the file is truncated and only contains the new content
const result = await file.text();
expect(result).toBe("Short");
});
test("FileSink truncates when writing to existing file via spawn", async () => {
using dir = tempDir("issue-25968-spawn", {});
const filePath = `${dir}/file.txt`;
await using proc = Bun.spawn({
cmd: [
bunExe(),
"-e",
`
const file = Bun.file("${filePath.replace(/\\/g, "\\\\")}");
await Bun.write(file, "Long content that is longer");
const writer = file.writer();
writer.write("Short");
writer.end();
console.log(await file.text());
`,
],
env: bunEnv,
cwd: String(dir),
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(stderr).toBe("");
expect(stdout.trim()).toBe("Short");
expect(exitCode).toBe(0);
});