From 114ec3c1f71b40bd4bba473b0187e7c664ed1755 Mon Sep 17 00:00:00 2001 From: Hirotaka Tagawa / wafuwafu13 Date: Wed, 24 May 2023 20:18:13 +0100 Subject: [PATCH] feat(ext/fs): add isBlockDevice, isCharDevice, isFifo, isSocket to FileInfo (#19008) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `isFile`, `isDirectory`, `isSymlink` are defined in `Deno.FileInfo`, but `isBlockDevice`, `isCharacterDevice`, `isFIFO`, `isSocket` are not defined. --------- Co-authored-by: Bartek IwaƄczuk --- cli/standalone/virtual_fs.rs | 12 ++++++++++++ cli/tests/integration/lsp_tests.rs | 2 +- cli/tests/unit/stat_test.ts | 8 ++++++++ cli/tsc/dts/lib.deno.ns.d.ts | 16 ++++++++++++++++ ext/fs/30_fs.js | 19 ++++++++++++++++++- ext/fs/ops.rs | 8 ++++++++ ext/io/fs.rs | 22 ++++++++++++++++++++++ 7 files changed, 85 insertions(+), 2 deletions(-) diff --git a/cli/standalone/virtual_fs.rs b/cli/standalone/virtual_fs.rs index 9c0601bcc1..31f630db8a 100644 --- a/cli/standalone/virtual_fs.rs +++ b/cli/standalone/virtual_fs.rs @@ -203,6 +203,10 @@ impl<'a> VfsEntryRef<'a> { gid: 0, rdev: 0, blocks: 0, + is_block_device: false, + is_char_device: false, + is_fifo: false, + is_socket: false, }, VfsEntryRef::File(file) => FsStat { is_directory: false, @@ -221,6 +225,10 @@ impl<'a> VfsEntryRef<'a> { gid: 0, rdev: 0, blocks: 0, + is_block_device: false, + is_char_device: false, + is_fifo: false, + is_socket: false, }, VfsEntryRef::Symlink(_) => FsStat { is_directory: false, @@ -239,6 +247,10 @@ impl<'a> VfsEntryRef<'a> { gid: 0, rdev: 0, blocks: 0, + is_block_device: false, + is_char_device: false, + is_fifo: false, + is_socket: false, }, } } diff --git a/cli/tests/integration/lsp_tests.rs b/cli/tests/integration/lsp_tests.rs index db009999b6..4ddf5d4e35 100644 --- a/cli/tests/integration/lsp_tests.rs +++ b/cli/tests/integration/lsp_tests.rs @@ -4715,7 +4715,7 @@ fn lsp_completions_auto_import() { "source": "./b.ts", "data": { "exportName": "foo", - "exportMapKey": "foo|6806|file:///a/b", + "exportMapKey": "foo|6810|file:///a/b", "moduleSpecifier": "./b.ts", "fileName": "file:///a/b.ts" }, diff --git a/cli/tests/unit/stat_test.ts b/cli/tests/unit/stat_test.ts index f386fd92fd..69730d439b 100644 --- a/cli/tests/unit/stat_test.ts +++ b/cli/tests/unit/stat_test.ts @@ -307,6 +307,10 @@ Deno.test( assert(s.rdev === null); assert(s.blksize === null); assert(s.blocks === null); + assert(s.isBlockDevice === null); + assert(s.isCharDevice === null); + assert(s.isFifo === null); + assert(s.isSocket === null); }, ); @@ -334,5 +338,9 @@ Deno.test( assert(s.rdev !== null); assert(s.blksize !== null); assert(s.blocks !== null); + assert(!s.isBlockDevice); + assert(!s.isCharDevice); + assert(!s.isFifo); + assert(!s.isSocket); }, ); diff --git a/cli/tsc/dts/lib.deno.ns.d.ts b/cli/tsc/dts/lib.deno.ns.d.ts index 4d8c9293e7..a7d6adab83 100644 --- a/cli/tsc/dts/lib.deno.ns.d.ts +++ b/cli/tsc/dts/lib.deno.ns.d.ts @@ -3122,6 +3122,22 @@ declare namespace Deno { * * _Linux/Mac OS only._ */ blocks: number | null; + /** True if this is info for a block device. + * + * _Linux/Mac OS only._ */ + isBlockDevice: boolean | null; + /** True if this is info for a char device. + * + * _Linux/Mac OS only._ */ + isCharDevice: boolean | null; + /** True if this is info for a fifo. + * + * _Linux/Mac OS only._ */ + isFifo: boolean | null; + /** True if this is info for a socket. + * + * _Linux/Mac OS only._ */ + isSocket: boolean | 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 dbe064ab8a..f14fcd5d1b 100644 --- a/ext/fs/30_fs.js +++ b/ext/fs/30_fs.js @@ -245,6 +245,7 @@ async function rename(oldpath, newpath) { // high u32 | low u32 // // 4. ?u64 converts a zero u64 value to JS null on Windows. +// ?bool converts a false bool value to JS null on Windows. function createByteStruct(types) { // types can be "date", "bool" or "u64". let offset = 0; @@ -273,7 +274,15 @@ function createByteStruct(types) { }] + view[${offset + 3}] * 2**32),`; offset += 2; } else { - 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),`; + } } offset += 2; } @@ -299,6 +308,10 @@ const { 0: statStruct, 1: statBuf } = createByteStruct({ rdev: "?u64", blksize: "?u64", blocks: "?u64", + isBlockDevice: "?bool", + isCharDevice: "?bool", + isFifo: "?bool", + isSocket: "?bool", }); function parseFileInfo(response) { @@ -322,6 +335,10 @@ function parseFileInfo(response) { rdev: unix ? response.rdev : null, blksize: unix ? response.blksize : null, blocks: unix ? response.blocks : null, + isBlockDevice: unix ? response.isBlockDevice : null, + isCharDevice: unix ? response.isCharDevice : null, + isFifo: unix ? response.isFifo : null, + isSocket: unix ? response.isSocket : null, }; } diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs index 0fad92044c..5bf3b1c6fd 100644 --- a/ext/fs/ops.rs +++ b/ext/fs/ops.rs @@ -1596,6 +1596,10 @@ create_struct_writer! { rdev: u64, blksize: u64, blocks: u64, + is_block_device: bool, + is_char_device: bool, + is_fifo: bool, + is_socket: bool, } } @@ -1623,6 +1627,10 @@ impl From for SerializableStat { rdev: stat.rdev, blksize: stat.blksize, blocks: stat.blocks, + is_block_device: stat.is_block_device, + is_char_device: stat.is_char_device, + is_fifo: stat.is_fifo, + is_socket: stat.is_socket, } } } diff --git a/ext/io/fs.rs b/ext/io/fs.rs index e335324f5e..9afa192ab9 100644 --- a/ext/io/fs.rs +++ b/ext/io/fs.rs @@ -89,6 +89,10 @@ pub struct FsStat { pub rdev: u64, pub blksize: u64, pub blocks: u64, + pub is_block_device: bool, + pub is_char_device: bool, + pub is_fifo: bool, + pub is_socket: bool, } impl FsStat { @@ -107,6 +111,20 @@ impl FsStat { }}; } + macro_rules! unix_or_false { + ($member:ident) => {{ + #[cfg(unix)] + { + use std::os::unix::fs::FileTypeExt; + metadata.file_type().$member() + } + #[cfg(not(unix))] + { + false + } + }}; + } + #[inline(always)] fn to_msec(maybe_time: Result) -> Option { match maybe_time { @@ -139,6 +157,10 @@ impl FsStat { rdev: unix_or_zero!(rdev), blksize: unix_or_zero!(blksize), blocks: unix_or_zero!(blocks), + is_block_device: unix_or_false!(is_block_device), + is_char_device: unix_or_false!(is_char_device), + is_fifo: unix_or_false!(is_fifo), + is_socket: unix_or_false!(is_socket), } } }