Compare commits

...

7 Commits

Author SHA1 Message Date
RiskyMH
b77362bcad refactor: use strings.eql instead of std.mem.eql 2025-12-01 17:05:14 +11:00
RiskyMH
a1d32e96a3 fix: use jsc instead of JSC for proper import 2025-12-01 16:50:25 +11:00
RiskyMH
3820bcc739 Merge remote-tracking branch 'origin/main' into riskymh/bun-write-self
# Conflicts:
#	test/js/bun/io/bun-write.test.js
2025-12-01 16:29:00 +11:00
Michael H
087618cc89 Merge branch 'main' into riskymh/bun-write-self 2025-07-10 17:31:03 +10:00
RiskyMH
b4c97d0830 bun run prettier 2025-06-18 07:12:02 +00:00
RiskyMH
a85f3e36e2 add file descriptor test 2025-06-18 17:09:50 +10:00
RiskyMH
6c3b88cd79 Fix bun.write to not make file empty if same file 2025-06-18 16:58:26 +10:00
2 changed files with 112 additions and 0 deletions

View File

@@ -1046,6 +1046,25 @@ pub fn writeFileWithSourceDestination(ctx: *jsc.JSGlobalObject, source_blob: *Bl
}
// If this is file <> file, we can just copy the file
else if (destination_type == .file and source_type == .file) {
// Check if source and destination are the same file
const dest_pathlike = &destination_store.data.file.pathlike;
const src_pathlike = &source_store.data.file.pathlike;
if (dest_pathlike.* == .path and src_pathlike.* == .path) {
if (strings.eql(dest_pathlike.path.slice(), src_pathlike.path.slice())) {
if (source_blob.size == Blob.max_size) {
source_blob.resolveSize();
}
return jsc.JSPromise.resolvedPromiseValue(ctx, .jsNumber(source_blob.size));
}
} else if (dest_pathlike.* == .fd and src_pathlike.* == .fd) {
if (dest_pathlike.fd == src_pathlike.fd) {
if (source_blob.size == Blob.max_size) {
source_blob.resolveSize();
}
return jsc.JSPromise.resolvedPromiseValue(ctx, .jsNumber(source_blob.size));
}
}
if (comptime Environment.isWindows) {
return Blob.copy_file.CopyFileWindows.init(
destination_store,

View File

@@ -542,4 +542,97 @@ const IS_UV_FS_COPYFILE_DISABLED =
expect(await exited).toBe(0);
}, 10000);
}
describe("writing a file to itself", () => {
test("should work with its own Bun.file", async () => {
using tmpbase = tempDir("bun-write-self-1", {});
const tempFilePath = join(tmpbase, `bun-write-self-test.txt`);
const content = "Hello, world!";
const file = Bun.file(tempFilePath);
await Bun.write(file, content);
const fileContent1 = await file.text();
expect(fileContent1).toBe(content);
const size = await Bun.write(file, file);
expect(size).toBe(content.length);
const fileContent2 = await file.text();
expect(fileContent2).toBe(content);
});
test("should work with a different reference", async () => {
using tmpbase = tempDir("bun-write-self-2", {});
const tempFilePath = join(tmpbase, `bun-write-self-test.txt`);
const content = "Hello, world!";
const file1 = Bun.file(tempFilePath);
await Bun.write(file1, content);
const file2 = Bun.file(tempFilePath);
const size = await Bun.write(file1, file2);
expect(size).toBe(content.length);
const fileContent = await file1.text();
expect(fileContent).toBe(content);
});
test("even with just a string path", async () => {
using tmpbase = tempDir("bun-write-self-3", {});
const tempFilePath = join(tmpbase, `bun-write-self-test.txt`);
const content = "Hello, world!";
const file1 = Bun.file(tempFilePath);
await file1.write(content);
const size = await Bun.write(tempFilePath, file1);
expect(size).toBe(content.length);
const fileContent = await file1.text();
expect(fileContent).toBe(content);
});
test("should handle same file descriptor", async () => {
using tmpbase = tempDir("bun-write-self-4", {});
const tempFilePath = join(tmpbase, `bun-write-self-test.txt`);
const content = "Hello, world!";
const file = Bun.file(tempFilePath);
await Bun.write(file, content);
const fd = fs.openSync(tempFilePath, "r+");
const fdFile = Bun.file(fd);
const size = await Bun.write(fdFile, fdFile);
expect(size).toBe(content.length);
const fileContent = await fdFile.text();
expect(fileContent).toBe(content);
fs.closeSync(fd);
});
// right now it doesn't handle this case
test.todo("should handle same file descriptor (2)", async () => {
using tmpbase = tempDir("bun-write-self-5", {});
const tempFilePath = join(tmpbase, `bun-write-self-test.txt`);
const content = "Hello, world!";
const file = Bun.file(tempFilePath);
await Bun.write(file, content);
const fd = fs.openSync(tempFilePath, "r+");
const fdFile = Bun.file(fd);
const size = await Bun.write(fdFile, file);
expect(size).toBe(content.length);
const fileContent = await fdFile.text();
expect(fileContent).toBe(content);
fs.closeSync(fd);
});
});
});