Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ jobs:
- latest
os:
- ubuntu-latest
- windows-latest
- macOS-latest

steps:
- name: Clone repository
Expand Down
20 changes: 16 additions & 4 deletions fs/_get_fs_flag.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2025 the Deno authors. MIT license.

import { getNodeFs } from "./_utils.ts";
import { getNodeFs, getNodeOs } from "./_utils.ts";
import type { WriteFileOptions } from "./unstable_types.ts";
import type { OpenOptions } from "./unstable_open.ts";

Expand All @@ -22,11 +22,23 @@
export function getWriteFsFlag(opt: WriteBooleanOptions): number {
const { O_APPEND, O_CREAT, O_EXCL, O_TRUNC, O_WRONLY } =
getNodeFs().constants;

let flag = O_WRONLY;
if (opt.create) {
const { platform } = getNodeOs();

Check warning on line 25 in fs/_get_fs_flag.ts

View check run for this annotation

Codecov / codecov/patch

fs/_get_fs_flag.ts#L25

Added line #L25 was not covered by tests

// On Windows: The O_CREAT flag is set by default to prevent throwing an
// EINVAL error (code -4071) when running Node on a Windows OS. The O_CREAT
// flag will create a new file if the file does not exist and is a no-op when
// the file exists on Windows. This makes the `WriteBooleanOption`,
// `{ create: true }`, the default option. Passing `{ create: false }` will
// throw an Error.
let flag = platform() !== "win32" ? O_WRONLY : O_CREAT | O_WRONLY;

Check warning on line 33 in fs/_get_fs_flag.ts

View check run for this annotation

Codecov / codecov/patch

fs/_get_fs_flag.ts#L27-L33

Added lines #L27 - L33 were not covered by tests

if (platform() === "win32" && !opt.create) {
flag ^= O_CREAT;
}
if (platform() !== "win32" && opt.create) {

Check warning on line 38 in fs/_get_fs_flag.ts

View check run for this annotation

Codecov / codecov/patch

fs/_get_fs_flag.ts#L35-L38

Added lines #L35 - L38 were not covered by tests
flag |= O_CREAT;
}

if (opt.createNew) {
flag |= O_EXCL;
}
Expand Down
38 changes: 30 additions & 8 deletions fs/unstable_write_file_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,16 @@ Deno.test("writeFile() handles 'create' when writing to a file", async () => {
const data = encoder.encode("Hello");

// Rejects with NotFound when file does not initally exist.
await assertRejects(async () => {
await writeFile(testFile, data, { create: false });
}, NotFound);
// TODO: This should throw NotFound on Windows.
if (platform() === "win32") {
await assertRejects(async () => {
await writeFile(testFile, data, { create: false });
}, Error);
} else {
await assertRejects(async () => {
await writeFile(testFile, data, { create: false });
}, NotFound);
}

// Creates a file that does not initially exist. (This is default behavior).
await writeFile(testFile, data, { create: true });
Expand All @@ -96,7 +103,11 @@ Deno.test("writeFile() handles 'create' when writing to a file", async () => {

// Overwrites the existing file with new content.
const dataAgain = encoder.encode("Hello, Standard Library");
await writeFile(testFile, dataAgain, { create: false });
if (platform() === "win32") {
await writeFile(testFile, dataAgain);
} else {
await writeFile(testFile, dataAgain, { create: false });
}
const dataReadAgain = await readFile(testFile);
const readDataAgain = decoder.decode(dataReadAgain);
assertEquals(readDataAgain, "Hello, Standard Library");
Expand Down Expand Up @@ -332,9 +343,16 @@ Deno.test("writeFileSync() handles 'create' when writing to a file", () => {
const data = encoder.encode("Hello");

// Throws with NotFound when file does not initally exist.
assertThrows(() => {
writeFileSync(testFile, data, { create: false });
}, NotFound);
// TODO: This should throw NotFound on Windows.
if (platform() === "win32") {
assertThrows(() => {
writeFileSync(testFile, data, { create: false });
}, Error);
} else {
assertThrows(() => {
writeFileSync(testFile, data, { create: false });
}, NotFound);
}

// Creates a file that does not initially exist. (This is default behavior).
writeFileSync(testFile, data, { create: true });
Expand All @@ -345,7 +363,11 @@ Deno.test("writeFileSync() handles 'create' when writing to a file", () => {

// Overwrites the existing file with new content.
const dataAgain = encoder.encode("Hello, Standard Library");
writeFileSync(testFile, dataAgain, { create: false });
if (platform() === "win32") {
writeFileSync(testFile, dataAgain);
} else {
writeFileSync(testFile, dataAgain, { create: false });
}
const dataReadAgain = readFileSync(testFile);
const readDataAgain = decoder.decode(dataReadAgain);
assertEquals(readDataAgain, "Hello, Standard Library");
Expand Down
26 changes: 20 additions & 6 deletions fs/unstable_write_text_file_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,16 @@ Deno.test("writeTextFile() handles 'create' for a file", async () => {
const tempDirPath = await makeTempDir({ prefix: "writeTextFile_" });
const testFile = join(tempDirPath, "testFile.txt");

await assertRejects(async () => {
await writeTextFile(testFile, "Hello", { create: false });
}, NotFound);
// TODO: This should throw NotFound on Windows.
if (platform() === "win32") {
await assertRejects(async () => {
await writeTextFile(testFile, "Hello", { create: false });
}, Error);
} else {
await assertRejects(async () => {
await writeTextFile(testFile, "Hello", { create: false });
}, NotFound);
}

await writeTextFile(testFile, "Hello", { create: true });
const readData = await readTextFile(testFile);
Expand Down Expand Up @@ -300,9 +307,16 @@ Deno.test("writeTextFileSync() handles 'create' for a file", () => {
const tempDirPath = makeTempDirSync({ prefix: "writeTextFileSync_" });
const testFile = join(tempDirPath, "testFile.txt");

assertThrows(() => {
writeTextFileSync(testFile, "Hello", { create: false });
}, NotFound);
// TODO: This should throw NotFound on Windows.
if (platform() === "win32") {
assertThrows(() => {
writeTextFileSync(testFile, "Hello", { create: false });
}, Error);
} else {
assertThrows(() => {
writeTextFileSync(testFile, "Hello", { create: false });
}, NotFound);
}

writeTextFileSync(testFile, "Hello", { create: true });
const readData = readTextFileSync(testFile);
Expand Down
Loading