From 3f031ad9af2d61671f8408632f31592ac4186926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 16 Mar 2023 19:14:56 -0400 Subject: [PATCH] BREAKING(ext/fs): FileInfo.dev is defined on Windows (#18237) Addresses feedback from https://github.com/denoland/deno/pull/18073#issuecomment-1471480385. Reverts changes to `FileInfo` fields that are not available on Windows making them `null`. Only `FileInfo.dev` is non-null. --- cli/tests/unit/stat_test.ts | 18 ++++++------ cli/tsc/dts/lib.deno.ns.d.ts | 30 ++++++++++---------- ext/fs/30_fs.js | 53 +++++++++++++++++++++++------------- 3 files changed, 58 insertions(+), 43 deletions(-) diff --git a/cli/tests/unit/stat_test.ts b/cli/tests/unit/stat_test.ts index 572e54e257..f386fd92fd 100644 --- a/cli/tests/unit/stat_test.ts +++ b/cli/tests/unit/stat_test.ts @@ -291,7 +291,7 @@ Deno.test( ignore: Deno.build.os !== "windows", permissions: { read: true, write: true }, }, - function statUnixFieldsOnWindows() { + function statNoUnixFields() { const enc = new TextEncoder(); const data = enc.encode("Hello"); const tempDir = Deno.makeTempDirSync(); @@ -299,14 +299,14 @@ Deno.test( Deno.writeFileSync(filename, data, { mode: 0o666 }); const s = Deno.statSync(filename); assert(s.dev !== 0); - assert(s.ino === 0); - assert(s.mode === 0); - assert(s.nlink === 0); - assert(s.uid === 0); - assert(s.gid === 0); - assert(s.rdev === 0); - assert(s.blksize === 0); - assert(s.blocks === 0); + assert(s.ino === null); + assert(s.mode === null); + assert(s.nlink === null); + assert(s.uid === null); + assert(s.gid === null); + assert(s.rdev === null); + assert(s.blksize === null); + assert(s.blocks === null); }, ); diff --git a/cli/tsc/dts/lib.deno.ns.d.ts b/cli/tsc/dts/lib.deno.ns.d.ts index 472c147d01..7431d3c05e 100644 --- a/cli/tsc/dts/lib.deno.ns.d.ts +++ b/cli/tsc/dts/lib.deno.ns.d.ts @@ -3082,37 +3082,37 @@ declare namespace Deno { dev: number; /** Inode number. * - * _Linux/Mac OS only, always returns 0 on Windows_ */ - ino: number; + * _Linux/Mac OS only._ */ + ino: number | null; /** **UNSTABLE**: Match behavior with Go on Windows for `mode`. * * The underlying raw `st_mode` bits that contain the standard Unix * permissions for this file/directory. */ - mode: number; + mode: number | null; /** Number of hard links pointing to this file. * - * _Linux/Mac OS only, always returns 0 on Windows_ */ - nlink: number; + * _Linux/Mac OS only._ */ + nlink: number | null; /** User ID of the owner of this file. * - * _Linux/Mac OS only, always returns 0 on Windows_ */ - uid: number; + * _Linux/Mac OS only._ */ + uid: number | null; /** Group ID of the owner of this file. * - * _Linux/Mac OS only, always returns 0 on Windows_ */ - gid: number; + * _Linux/Mac OS only._ */ + gid: number | null; /** Device ID of this file. * - * _Linux/Mac OS only, always returns 0 on Windows_ */ - rdev: number; + * _Linux/Mac OS only._ */ + rdev: number | null; /** Blocksize for filesystem I/O. * - * _Linux/Mac OS only, always returns 0 on Windows_ */ - blksize: number; + * _Linux/Mac OS only._ */ + blksize: number | null; /** Number of blocks allocated to the file, in 512-byte units. * - * _Linux/Mac OS only, always returns 0 on Windows_ */ - blocks: number; + * _Linux/Mac OS only._ */ + blocks: number | null; } /** Resolves to the absolute normalized path, with symbolic links resolved. diff --git a/ext/fs/30_fs.js b/ext/fs/30_fs.js index 72123f6307..a8ae7ad3aa 100644 --- a/ext/fs/30_fs.js +++ b/ext/fs/30_fs.js @@ -211,16 +211,30 @@ async function rename(oldpath, newpath) { // 3. u64 // offset += 2 // high u32 | low u32 +// +// 4. ?u64 converts a zero u64 value to JS null on Windows. function createByteStruct(types) { // types can be "date", "bool" or "u64". let offset = 0; - let str = "return {"; + let str = + 'const unix = Deno.build.os === "darwin" || Deno.build.os === "linux"; return {'; const typeEntries = ObjectEntries(types); for (let i = 0; i < typeEntries.length; ++i) { - const { 0: name, 1: type } = typeEntries[i]; + let { 0: name, 1: type } = typeEntries[i]; + + const optional = type.startsWith("?"); + if (optional) type = type.slice(1); if (type == "u64") { - str += `${name}: view[${offset}] + view[${offset + 1}] * 2**32,`; + if (!optional) { + str += `${name}: view[${offset}] + view[${offset + 1}] * 2**32,`; + } else { + str += `${name}: (unix ? (view[${offset}] + view[${ + offset + 1 + }] * 2**32) : (view[${offset}] + view[${ + offset + 1 + }] * 2**32) || null),`; + } } else if (type == "date") { str += `${name}: view[${offset}] === 0 ? null : new Date(view[${ offset + 2 @@ -245,17 +259,18 @@ const { 0: statStruct, 1: statBuf } = createByteStruct({ atime: "date", birthtime: "date", dev: "u64", - ino: "u64", - mode: "u64", - nlink: "u64", - uid: "u64", - gid: "u64", - rdev: "u64", - blksize: "u64", - blocks: "u64", + ino: "?u64", + mode: "?u64", + nlink: "?u64", + uid: "?u64", + gid: "?u64", + rdev: "?u64", + blksize: "?u64", + blocks: "?u64", }); function parseFileInfo(response) { + const unix = core.build.os === "darwin" || core.build.os === "linux"; return { isFile: response.isFile, isDirectory: response.isDirectory, @@ -267,14 +282,14 @@ function parseFileInfo(response) { ? new Date(response.birthtime) : null, dev: response.dev, - ino: response.ino, - mode: response.mode, - nlink: response.nlink, - uid: response.uid, - gid: response.gid, - rdev: response.rdev, - blksize: response.blksize, - blocks: response.blocks, + ino: unix ? response.ino : null, + mode: unix ? response.mode : null, + nlink: unix ? response.nlink : null, + uid: unix ? response.uid : null, + gid: unix ? response.gid : null, + rdev: unix ? response.rdev : null, + blksize: unix ? response.blksize : null, + blocks: unix ? response.blocks : null, }; }