diff options
author | Bert Belder <bertbelder@gmail.com> | 2020-04-29 22:00:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-29 16:00:31 -0400 |
commit | 3e6ea6284178df0be4982d9775f47b47b14c6139 (patch) | |
tree | ed684ea536e32023e72004110556ad8285126676 /cli | |
parent | 721a4ad59d4a8bdd8470d6b98839137f14c84ba9 (diff) |
BREAKING: Include limited metadata in 'DirEntry' objects (#4941)
This change is to prevent needed a separate stat syscall for each file
when using readdir.
For consistency, this PR also modifies std's `WalkEntry` interface to
extend `DirEntry` with an additional `path` field.
Diffstat (limited to 'cli')
-rw-r--r-- | cli/js/lib.deno.ns.d.ts | 5 | ||||
-rw-r--r-- | cli/js/ops/fs/read_dir.ts | 14 | ||||
-rw-r--r-- | cli/js/ops/fs/stat.ts | 2 | ||||
-rw-r--r-- | cli/js/tests/read_dir_test.ts | 13 | ||||
-rw-r--r-- | cli/ops/fs.rs | 28 |
5 files changed, 25 insertions, 37 deletions
diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts index e58ec0b55..d7d885b5b 100644 --- a/cli/js/lib.deno.ns.d.ts +++ b/cli/js/lib.deno.ns.d.ts @@ -1386,8 +1386,11 @@ declare namespace Deno { * Requires `allow-read` permission. */ export function realpath(path: string): Promise<string>; - export interface DirEntry extends FileInfo { + export interface DirEntry { name: string; + isFile: boolean; + isDirectory: boolean; + isSymlink: boolean; } /** Synchronously reads the directory given by `path` and returns an iterable diff --git a/cli/js/ops/fs/read_dir.ts b/cli/js/ops/fs/read_dir.ts index 29b8676ef..7d65fed48 100644 --- a/cli/js/ops/fs/read_dir.ts +++ b/cli/js/ops/fs/read_dir.ts @@ -1,21 +1,19 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "../dispatch_json.ts"; -import { FileInfo, StatResponse, parseFileInfo } from "./stat.ts"; -export interface DirEntry extends FileInfo { +export interface DirEntry { name: string; + isFile: boolean; + isDirectory: boolean; + isSymlink: boolean; } interface ReadDirResponse { - entries: StatResponse[]; + entries: DirEntry[]; } function res(response: ReadDirResponse): DirEntry[] { - return response.entries.map( - (statRes: StatResponse): DirEntry => { - return { ...parseFileInfo(statRes), name: statRes.name! }; - } - ); + return response.entries; } export function readdirSync(path: string): Iterable<DirEntry> { diff --git a/cli/js/ops/fs/stat.ts b/cli/js/ops/fs/stat.ts index c3563a8c4..e8fd28218 100644 --- a/cli/js/ops/fs/stat.ts +++ b/cli/js/ops/fs/stat.ts @@ -29,8 +29,6 @@ export interface StatResponse { mtime: number | null; atime: number | null; birthtime: number | null; - // Null for stat(), but exists for readdir(). - name: string | null; // Unix only members dev: number; ino: number; diff --git a/cli/js/tests/read_dir_test.ts b/cli/js/tests/read_dir_test.ts index 2c7f42103..f1c7ea121 100644 --- a/cli/js/tests/read_dir_test.ts +++ b/cli/js/tests/read_dir_test.ts @@ -4,19 +4,14 @@ import { unitTest, assert, assertEquals } from "./test_util.ts"; function assertSameContent(files: Deno.DirEntry[]): void { let counter = 0; - for (const file of files) { - if (file.name === "subdir") { - assert(file.isDirectory); - counter++; - } - - if (file.name === "002_hello.ts") { - assertEquals(file.mode!, Deno.statSync(`cli/tests/${file.name}`).mode!); + for (const entry of files) { + if (entry.name === "subdir") { + assert(entry.isDirectory); counter++; } } - assertEquals(counter, 2); + assertEquals(counter, 1); } unitTest({ perms: { read: true } }, function readdirSyncSuccess(): void { diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs index 28e260694..55ee1afa3 100644 --- a/cli/ops/fs.rs +++ b/cli/ops/fs.rs @@ -460,10 +460,7 @@ fn to_msec(maybe_time: Result<SystemTime, io::Error>) -> serde_json::Value { } #[inline(always)] -fn get_stat_json( - metadata: std::fs::Metadata, - maybe_name: Option<String>, -) -> JsonResult { +fn get_stat_json(metadata: std::fs::Metadata) -> JsonResult { // Unix stat member (number types only). 0 if not on unix. macro_rules! usm { ($member: ident) => {{ @@ -480,7 +477,7 @@ fn get_stat_json( #[cfg(unix)] use std::os::unix::fs::MetadataExt; - let mut json_val = json!({ + let json_val = json!({ "isFile": metadata.is_file(), "isDirectory": metadata.is_dir(), "isSymlink": metadata.file_type().is_symlink(), @@ -502,14 +499,6 @@ fn get_stat_json( "blksize": usm!(blksize), "blocks": usm!(blocks), }); - - // "name" is an optional field by our design. - if let Some(name) = maybe_name { - if let serde_json::Value::Object(ref mut m) = json_val { - m.insert("name".to_owned(), json!(name)); - } - } - Ok(json_val) } @@ -540,7 +529,7 @@ fn op_stat( } else { std::fs::metadata(&path)? }; - get_stat_json(metadata, None) + get_stat_json(metadata) }) } @@ -599,10 +588,15 @@ fn op_read_dir( let entries: Vec<_> = std::fs::read_dir(path)? .filter_map(|entry| { let entry = entry.unwrap(); - let metadata = entry.metadata().unwrap(); + let file_type = entry.file_type().unwrap(); // Not all filenames can be encoded as UTF-8. Skip those for now. - if let Ok(filename) = into_string(entry.file_name()) { - Some(get_stat_json(metadata, Some(filename)).unwrap()) + if let Ok(name) = into_string(entry.file_name()) { + Some(json!({ + "name": name, + "isFile": file_type.is_file(), + "isDirectory": file_type.is_dir(), + "isSymlink": file_type.is_symlink() + })) } else { None } |