1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-12 00:54:02 -05:00

refactor(cli/js/ops/fs): Improve readdir() and FileInfo interfaces (#4763)

This commit is contained in:
Nayeem Rahman 2020-04-16 06:40:30 +01:00 committed by GitHub
parent 6441852a1d
commit 5ac728a5f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 312 additions and 360 deletions

View file

@ -23,7 +23,6 @@ export {
export { chdir, cwd } from "./ops/fs/dir.ts";
export { applySourceMap, formatDiagnostics } from "./ops/errors.ts";
export { errors } from "./errors.ts";
export { FileInfo } from "./file_info.ts";
export {
File,
open,
@ -97,7 +96,7 @@ export {
export { openPlugin } from "./plugins.ts";
export { kill } from "./ops/process.ts";
export { run, RunOptions, Process, ProcessStatus } from "./process.ts";
export { readdirSync, readdir } from "./ops/fs/read_dir.ts";
export { DirEntry, readdirSync, readdir } from "./ops/fs/read_dir.ts";
export { readFileSync, readFile } from "./read_file.ts";
export { readlinkSync, readlink } from "./ops/fs/read_link.ts";
export { realpathSync, realpath } from "./ops/fs/realpath.ts";
@ -105,7 +104,7 @@ export { removeSync, remove, RemoveOptions } from "./ops/fs/remove.ts";
export { renameSync, rename } from "./ops/fs/rename.ts";
export { resources, close } from "./ops/resources.ts";
export { signal, signals, Signal, SignalStream } from "./signals.ts";
export { statSync, lstatSync, stat, lstat } from "./ops/fs/stat.ts";
export { FileInfo, statSync, lstatSync, stat, lstat } from "./ops/fs/stat.ts";
export { symlinkSync, symlink } from "./ops/fs/symlink.ts";
export { connectTLS, listenTLS } from "./tls.ts";
export { truncateSync, truncate } from "./ops/fs/truncate.ts";

View file

@ -1,87 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { StatResponse } from "./ops/fs/stat.ts";
import { build } from "./build.ts";
export interface FileInfo {
size: number;
modified: number | null;
accessed: number | null;
created: number | null;
name: string | null;
dev: number | null;
ino: number | null;
mode: number | null;
nlink: number | null;
uid: number | null;
gid: number | null;
rdev: number | null;
blksize: number | null;
blocks: number | null;
isFile(): boolean;
isDirectory(): boolean;
isSymlink(): boolean;
}
// @internal
export class FileInfoImpl implements FileInfo {
readonly #isFile: boolean;
readonly #isDirectory: boolean;
readonly #isSymlink: boolean;
size: number;
modified: number | null;
accessed: number | null;
created: number | null;
name: string | null;
dev: number | null;
ino: number | null;
mode: number | null;
nlink: number | null;
uid: number | null;
gid: number | null;
rdev: number | null;
blksize: number | null;
blocks: number | null;
/* @internal */
constructor(res: StatResponse) {
const isUnix = build.os === "mac" || build.os === "linux";
const modified = res.modified;
const accessed = res.accessed;
const created = res.created;
const name = res.name;
// Unix only
const { dev, ino, mode, nlink, uid, gid, rdev, blksize, blocks } = res;
this.#isFile = res.isFile;
this.#isDirectory = res.isDirectory;
this.#isSymlink = res.isSymlink;
this.size = res.size;
this.modified = modified ? modified : null;
this.accessed = accessed ? accessed : null;
this.created = created ? created : null;
this.name = name ? name : null;
// Only non-null if on Unix
this.dev = isUnix ? dev : null;
this.ino = isUnix ? ino : null;
this.mode = isUnix ? mode : null;
this.nlink = isUnix ? nlink : null;
this.uid = isUnix ? uid : null;
this.gid = isUnix ? gid : null;
this.rdev = isUnix ? rdev : null;
this.blksize = isUnix ? blksize : null;
this.blocks = isUnix ? blocks : null;
}
isFile(): boolean {
return this.#isFile;
}
isDirectory(): boolean {
return this.#isDirectory;
}
isSymlink(): boolean {
return this.#isSymlink;
}
}

View file

@ -1317,9 +1317,17 @@ declare namespace Deno {
export function readFile(path: string): Promise<Uint8Array>;
/** A FileInfo describes a file and is returned by `stat`, `lstat`,
* `statSync`, `lstatSync`. A list of FileInfo is returned by `readdir`,
* `readdirSync`. */
* `statSync`, `lstatSync`. */
export interface FileInfo {
/** True if this is info for a regular file. Mutually exclusive to
* `FileInfo.isDirectory` and `FileInfo.isSymlink`. */
isFile: boolean;
/** True if this is info for a regular directory. Mutually exclusive to
* `FileInfo.isFile` and `FileInfo.isSymlink`. */
isDirectory: boolean;
/** True if this is info for a symlink. Mutually exclusive to
* `FileInfo.isFile` and `FileInfo.isDirectory`. */
isSymlink: boolean;
/** The size of the file, in bytes. */
size: number;
/** The last modification time of the file. This corresponds to the `mtime`
@ -1334,8 +1342,6 @@ declare namespace Deno {
* field from `stat` on Mac/BSD and `ftCreationTime` on Windows. This may not
* be available on all platforms. */
created: number | null;
/** The file or directory name. */
name: string | null;
/** ID of the device containing the file.
*
* _Linux/Mac OS only._ */
@ -1373,15 +1379,6 @@ declare namespace Deno {
*
* _Linux/Mac OS only._ */
blocks: number | null;
/** Returns whether this is info for a regular file. This result is mutually
* exclusive to `FileInfo.isDirectory` and `FileInfo.isSymlink`. */
isFile(): boolean;
/** Returns whether this is info for a regular directory. This result is
* mutually exclusive to `FileInfo.isFile` and `FileInfo.isSymlink`. */
isDirectory(): boolean;
/** Returns whether this is info for a symlink. This result is
* mutually exclusive to `FileInfo.isFile` and `FileInfo.isDirectory`. */
isSymlink(): boolean;
}
/** Returns absolute normalized path, with symbolic links resolved.
@ -1408,28 +1405,33 @@ declare namespace Deno {
* Requires `allow-read` permission. */
export function realpath(path: string): Promise<string>;
/** UNSTABLE: This API is likely to change to return an iterable object instead
*
* Synchronously reads the directory given by `path` and returns an array of
* `Deno.FileInfo`.
*
* const files = Deno.readdirSync("/");
*
* Throws error if `path` is not a directory.
*
* Requires `allow-read` permission. */
export function readdirSync(path: string): FileInfo[];
export interface DirEntry extends FileInfo {
name: string;
}
/** UNSTABLE: This API is likely to change to return an `AsyncIterable`.
/** Synchronously reads the directory given by `path` and returns an iterable
* of `Deno.DirEntry`.
*
* Reads the directory given by `path` and resolves to an array of `Deno.FileInfo`.
*
* const files = await Deno.readdir("/");
* for (const dirEntry of Deno.readdirSync("/")) {
* console.log(dirEntry.name);
* }
*
* Throws error if `path` is not a directory.
*
* Requires `allow-read` permission. */
export function readdir(path: string): Promise<FileInfo[]>;
export function readdirSync(path: string): Iterable<DirEntry>;
/** Reads the directory given by `path` and returns an async iterable of
* `Deno.DirEntry`.
*
* for await (const dirEntry of Deno.readdir("/")) {
* console.log(dirEntry.name);
* }
*
* Throws error if `path` is not a directory.
*
* Requires `allow-read` permission. */
export function readdir(path: string): AsyncIterable<DirEntry>;
/** Synchronously copies the contents and permissions of one file to another
* specified path, by default creating a new file if needed, else overwriting.
@ -1476,7 +1478,7 @@ declare namespace Deno {
* points to.
*
* const fileInfo = await Deno.lstat("hello.txt");
* assert(fileInfo.isFile());
* assert(fileInfo.isFile);
*
* Requires `allow-read` permission. */
export function lstat(path: string): Promise<FileInfo>;
@ -1486,7 +1488,7 @@ declare namespace Deno {
* what it points to..
*
* const fileInfo = Deno.lstatSync("hello.txt");
* assert(fileInfo.isFile());
* assert(fileInfo.isFile);
*
* Requires `allow-read` permission. */
export function lstatSync(path: string): FileInfo;
@ -1495,7 +1497,7 @@ declare namespace Deno {
* follow symlinks.
*
* const fileInfo = await Deno.stat("hello.txt");
* assert(fileInfo.isFile());
* assert(fileInfo.isFile);
*
* Requires `allow-read` permission. */
export function stat(path: string): Promise<FileInfo>;
@ -1504,7 +1506,7 @@ declare namespace Deno {
* always follow symlinks.
*
* const fileInfo = Deno.statSync("hello.txt");
* assert(fileInfo.isFile());
* assert(fileInfo.isFile);
*
* Requires `allow-read` permission. */
export function statSync(path: string): FileInfo;

View file

@ -1,24 +1,32 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync } from "../dispatch_json.ts";
import { FileInfo, FileInfoImpl } from "../../file_info.ts";
import { StatResponse } from "./stat.ts";
import { FileInfo, StatResponse, parseFileInfo } from "./stat.ts";
export interface DirEntry extends FileInfo {
name: string;
}
interface ReadDirResponse {
entries: StatResponse[];
}
function res(response: ReadDirResponse): FileInfo[] {
function res(response: ReadDirResponse): DirEntry[] {
return response.entries.map(
(statRes: StatResponse): FileInfo => {
return new FileInfoImpl(statRes);
(statRes: StatResponse): DirEntry => {
return { ...parseFileInfo(statRes), name: statRes.name! };
}
);
}
export function readdirSync(path: string): FileInfo[] {
return res(sendSync("op_read_dir", { path }));
export function readdirSync(path: string): Iterable<DirEntry> {
return res(sendSync("op_read_dir", { path }))[Symbol.iterator]();
}
export async function readdir(path: string): Promise<FileInfo[]> {
return res(await sendAsync("op_read_dir", { path }));
export function readdir(path: string): AsyncIterable<DirEntry> {
const array = sendAsync("op_read_dir", { path }).then(res);
return {
async *[Symbol.asyncIterator](): AsyncIterableIterator<DirEntry> {
yield* await array;
},
};
}

View file

@ -1,6 +1,25 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync } from "../dispatch_json.ts";
import { FileInfo, FileInfoImpl } from "../../file_info.ts";
import { build } from "../../build.ts";
export interface FileInfo {
size: number;
modified: number | null;
accessed: number | null;
created: number | null;
dev: number | null;
ino: number | null;
mode: number | null;
nlink: number | null;
uid: number | null;
gid: number | null;
rdev: number | null;
blksize: number | null;
blocks: number | null;
isFile: boolean;
isDirectory: boolean;
isSymlink: boolean;
}
export interface StatResponse {
isFile: boolean;
@ -10,6 +29,7 @@ export interface StatResponse {
modified: number;
accessed: number;
created: number;
// Null for stat(), but exists for readdir().
name: string | null;
// Unix only members
dev: number;
@ -23,12 +43,36 @@ export interface StatResponse {
blocks: number;
}
// @internal
export function parseFileInfo(response: StatResponse): FileInfo {
const isUnix = build.os === "mac" || build.os === "linux";
return {
isFile: response.isFile,
isDirectory: response.isDirectory,
isSymlink: response.isSymlink,
size: response.size,
modified: response.modified ? response.modified : null,
accessed: response.accessed ? response.accessed : null,
created: response.created ? response.created : null,
// Only non-null if on Unix
dev: isUnix ? response.dev : null,
ino: isUnix ? response.ino : null,
mode: isUnix ? response.mode : null,
nlink: isUnix ? response.nlink : null,
uid: isUnix ? response.uid : null,
gid: isUnix ? response.gid : null,
rdev: isUnix ? response.rdev : null,
blksize: isUnix ? response.blksize : null,
blocks: isUnix ? response.blocks : null,
};
}
export async function lstat(path: string): Promise<FileInfo> {
const res = (await sendAsync("op_stat", {
path,
lstat: true,
})) as StatResponse;
return new FileInfoImpl(res);
return parseFileInfo(res);
}
export function lstatSync(path: string): FileInfo {
@ -36,7 +80,7 @@ export function lstatSync(path: string): FileInfo {
path,
lstat: true,
}) as StatResponse;
return new FileInfoImpl(res);
return parseFileInfo(res);
}
export async function stat(path: string): Promise<FileInfo> {
@ -44,7 +88,7 @@ export async function stat(path: string): Promise<FileInfo> {
path,
lstat: false,
})) as StatResponse;
return new FileInfoImpl(res);
return parseFileInfo(res);
}
export function statSync(path: string): FileInfo {
@ -52,5 +96,5 @@ export function statSync(path: string): FileInfo {
path,
lstat: false,
}) as StatResponse;
return new FileInfoImpl(res);
return parseFileInfo(res);
}

View file

@ -273,7 +273,7 @@ unitTest(
const filename = tempDir + "/test.txt";
const f = await Deno.create(filename);
let fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile());
assert(fileInfo.isFile);
assert(fileInfo.size === 0);
const enc = new TextEncoder();
const data = enc.encode("Hello");
@ -297,7 +297,7 @@ unitTest(
let file = await Deno.open(filename, "w");
// assert file was created
let fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile());
assert(fileInfo.isFile);
assertEquals(fileInfo.size, 0);
// write some data
await file.write(data);
@ -335,7 +335,7 @@ unitTest(
const seekPosition = 0;
// assert file was created
let fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile());
assert(fileInfo.isFile);
assertEquals(fileInfo.size, 0);
// write some data
await file.write(data);

View file

@ -31,8 +31,8 @@ unitTest(
// Remove oldname. File still accessible through newname.
Deno.removeSync(oldName);
const newNameStat = Deno.statSync(newName);
assert(newNameStat.isFile());
assert(!newNameStat.isSymlink()); // Not a symlink.
assert(newNameStat.isFile);
assert(!newNameStat.isSymlink); // Not a symlink.
assertEquals(
newData3,
new TextDecoder().decode(Deno.readFileSync(newName))
@ -137,8 +137,8 @@ unitTest(
// Remove oldname. File still accessible through newname.
Deno.removeSync(oldName);
const newNameStat = Deno.statSync(newName);
assert(newNameStat.isFile());
assert(!newNameStat.isSymlink()); // Not a symlink.
assert(newNameStat.isFile);
assert(!newNameStat.isSymlink); // Not a symlink.
assertEquals(
newData3,
new TextDecoder().decode(Deno.readFileSync(newName))

View file

@ -3,7 +3,7 @@ import { unitTest, assert, assertEquals, assertThrows } from "./test_util.ts";
function assertDirectory(path: string, mode?: number): void {
const info = Deno.lstatSync(path);
assert(info.isDirectory());
assert(info.isDirectory);
if (Deno.build.os !== "win" && mode !== undefined) {
assertEquals(info.mode! & 0o777, mode & ~Deno.umask());
}

View file

@ -1,14 +1,12 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
type FileInfo = Deno.FileInfo;
function assertSameContent(files: FileInfo[]): void {
function assertSameContent(files: Deno.DirEntry[]): void {
let counter = 0;
for (const file of files) {
if (file.name === "subdir") {
assert(file.isDirectory());
assert(file.isDirectory);
counter++;
}
@ -22,7 +20,7 @@ function assertSameContent(files: FileInfo[]): void {
}
unitTest({ perms: { read: true } }, function readdirSyncSuccess(): void {
const files = Deno.readdirSync("cli/tests/");
const files = [...Deno.readdirSync("cli/tests/")];
assertSameContent(files);
});
@ -68,7 +66,10 @@ unitTest({ perms: { read: true } }, function readdirSyncNotFound(): void {
unitTest({ perms: { read: true } }, async function readdirSuccess(): Promise<
void
> {
const files = await Deno.readdir("cli/tests/");
const files = [];
for await (const dirEntry of Deno.readdir("cli/tests/")) {
files.push(dirEntry);
}
assertSameContent(files);
});
@ -77,7 +78,7 @@ unitTest({ perms: { read: false } }, async function readdirPerm(): Promise<
> {
let caughtError = false;
try {
await Deno.readdir("tests/");
await Deno.readdir("tests/")[Symbol.asyncIterator]().next();
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);

View file

@ -10,7 +10,7 @@ unitTest(
const path = Deno.makeTempDirSync() + "/subdir";
Deno.mkdirSync(path);
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
Deno.removeSync(path); // remove
// We then check again after remove
let err;
@ -33,7 +33,7 @@ unitTest(
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile()); // check exist first
assert(fileInfo.isFile); // check exist first
Deno.removeSync(filename); // remove
// We then check again after remove
let err;
@ -56,9 +56,9 @@ unitTest(
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory()); // check exist first
assert(subPathInfo.isDirectory); // check exist first
let err;
try {
// Should not be able to recursively remove
@ -94,7 +94,7 @@ unitTest(
assertEquals(errOnWindows.message, "not implemented");
} else {
const pathInfo = Deno.lstatSync(danglingSymlinkPath);
assert(pathInfo.isSymlink());
assert(pathInfo.isSymlink);
Deno.removeSync(danglingSymlinkPath);
let err;
try {
@ -127,7 +127,7 @@ unitTest(
assertEquals(errOnWindows.message, "not implemented");
} else {
const symlinkPathInfo = Deno.statSync(validSymlinkPath);
assert(symlinkPathInfo.isFile());
assert(symlinkPathInfo.isFile);
Deno.removeSync(validSymlinkPath);
let err;
try {
@ -159,7 +159,7 @@ unitTest(
let path = Deno.makeTempDirSync() + "/dir/subdir";
Deno.mkdirSync(path, { recursive: true });
let pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
Deno.removeSync(path, { recursive: true }); // remove
// We then check again after remove
let err;
@ -177,9 +177,9 @@ unitTest(
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory()); // check exist first
assert(subPathInfo.isDirectory); // check exist first
Deno.removeSync(path, { recursive: true }); // remove
// We then check parent directory again after remove
try {
@ -201,7 +201,7 @@ unitTest(
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile()); // check exist first
assert(fileInfo.isFile); // check exist first
Deno.removeSync(filename, { recursive: true }); // remove
// We then check again after remove
let err;
@ -247,7 +247,7 @@ unitTest(
const path = Deno.makeTempDirSync() + "/dir/subdir";
Deno.mkdirSync(path, { recursive: true });
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
await Deno.remove(path); // remove
// We then check again after remove
let err;
@ -270,7 +270,7 @@ unitTest(
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile()); // check exist first
assert(fileInfo.isFile); // check exist first
await Deno.remove(filename); // remove
// We then check again after remove
let err;
@ -293,9 +293,9 @@ unitTest(
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory()); // check exist first
assert(subPathInfo.isDirectory); // check exist first
let err;
try {
// Should not be able to recursively remove
@ -330,7 +330,7 @@ unitTest(
assertEquals(errOnWindows.message, "not implemented");
} else {
const pathInfo = Deno.lstatSync(danglingSymlinkPath);
assert(pathInfo.isSymlink());
assert(pathInfo.isSymlink);
await Deno.remove(danglingSymlinkPath);
let err;
try {
@ -363,7 +363,7 @@ unitTest(
assertEquals(errOnWindows.message, "not implemented");
} else {
const symlinkPathInfo = Deno.statSync(validSymlinkPath);
assert(symlinkPathInfo.isFile());
assert(symlinkPathInfo.isFile);
await Deno.remove(validSymlinkPath);
let err;
try {
@ -397,7 +397,7 @@ unitTest(
let path = Deno.makeTempDirSync() + "/dir/subdir";
Deno.mkdirSync(path, { recursive: true });
let pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
await Deno.remove(path, { recursive: true }); // remove
// We then check again after remove
let err;
@ -415,9 +415,9 @@ unitTest(
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory()); // check exist first
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory()); // check exist first
assert(subPathInfo.isDirectory); // check exist first
await Deno.remove(path, { recursive: true }); // remove
// We then check parent directory again after remove
try {
@ -439,7 +439,7 @@ unitTest(
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile()); // check exist first
assert(fileInfo.isFile); // check exist first
await Deno.remove(filename, { recursive: true }); // remove
// We then check again after remove
let err;

View file

@ -16,12 +16,12 @@ function assertMissing(path: string): void {
function assertFile(path: string): void {
const info = Deno.lstatSync(path);
assert(info.isFile());
assert(info.isFile);
}
function assertDirectory(path: string, mode?: number): void {
const info = Deno.lstatSync(path);
assert(info.isDirectory());
assert(info.isDirectory);
if (Deno.build.os !== "win" && mode !== undefined) {
assertEquals(info.mode! & 0o777, mode & ~Deno.umask());
}

View file

@ -5,16 +5,16 @@ import { unitTest, assert, assertEquals } from "./test_util.ts";
// to create temp files.
unitTest({ perms: { read: true } }, function statSyncSuccess(): void {
const packageInfo = Deno.statSync("README.md");
assert(packageInfo.isFile());
assert(!packageInfo.isSymlink());
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = Deno.statSync("cli/tests/symlink_to_subdir");
assert(modulesInfo.isDirectory());
assert(!modulesInfo.isSymlink());
assert(modulesInfo.isDirectory);
assert(!modulesInfo.isSymlink);
const testsInfo = Deno.statSync("cli/tests");
assert(testsInfo.isDirectory());
assert(!testsInfo.isSymlink());
assert(testsInfo.isDirectory);
assert(!testsInfo.isSymlink);
});
unitTest({ perms: { read: false } }, function statSyncPerm(): void {
@ -45,16 +45,16 @@ unitTest({ perms: { read: true } }, function statSyncNotFound(): void {
unitTest({ perms: { read: true } }, function lstatSyncSuccess(): void {
const packageInfo = Deno.lstatSync("README.md");
assert(packageInfo.isFile());
assert(!packageInfo.isSymlink());
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = Deno.lstatSync("cli/tests/symlink_to_subdir");
assert(!modulesInfo.isDirectory());
assert(modulesInfo.isSymlink());
assert(!modulesInfo.isDirectory);
assert(modulesInfo.isSymlink);
const coreInfo = Deno.lstatSync("core");
assert(coreInfo.isDirectory());
assert(!coreInfo.isSymlink());
assert(coreInfo.isDirectory);
assert(!coreInfo.isSymlink);
});
unitTest({ perms: { read: false } }, function lstatSyncPerm(): void {
@ -87,16 +87,16 @@ unitTest({ perms: { read: true } }, async function statSuccess(): Promise<
void
> {
const packageInfo = await Deno.stat("README.md");
assert(packageInfo.isFile());
assert(!packageInfo.isSymlink());
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = await Deno.stat("cli/tests/symlink_to_subdir");
assert(modulesInfo.isDirectory());
assert(!modulesInfo.isSymlink());
assert(modulesInfo.isDirectory);
assert(!modulesInfo.isSymlink);
const testsInfo = await Deno.stat("cli/tests");
assert(testsInfo.isDirectory());
assert(!testsInfo.isSymlink());
assert(testsInfo.isDirectory);
assert(!testsInfo.isSymlink);
});
unitTest({ perms: { read: false } }, async function statPerm(): Promise<void> {
@ -131,16 +131,16 @@ unitTest({ perms: { read: true } }, async function lstatSuccess(): Promise<
void
> {
const packageInfo = await Deno.lstat("README.md");
assert(packageInfo.isFile());
assert(!packageInfo.isSymlink());
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = await Deno.lstat("cli/tests/symlink_to_subdir");
assert(!modulesInfo.isDirectory());
assert(modulesInfo.isSymlink());
assert(!modulesInfo.isDirectory);
assert(modulesInfo.isSymlink);
const coreInfo = await Deno.lstat("core");
assert(coreInfo.isDirectory());
assert(!coreInfo.isSymlink());
assert(coreInfo.isDirectory);
assert(!coreInfo.isSymlink);
});
unitTest({ perms: { read: false } }, async function lstatPerm(): Promise<void> {

View file

@ -21,8 +21,8 @@ unitTest(
} else {
const newNameInfoLStat = Deno.lstatSync(newname);
const newNameInfoStat = Deno.statSync(newname);
assert(newNameInfoLStat.isSymlink());
assert(newNameInfoStat.isDirectory());
assert(newNameInfoLStat.isSymlink);
assert(newNameInfoStat.isDirectory);
}
}
);
@ -79,8 +79,8 @@ unitTest(
} else {
const newNameInfoLStat = Deno.lstatSync(newname);
const newNameInfoStat = Deno.statSync(newname);
assert(newNameInfoLStat.isSymlink());
assert(newNameInfoStat.isDirectory());
assert(newNameInfoLStat.isSymlink);
assert(newNameInfoStat.isDirectory);
}
}
);

View file

@ -327,7 +327,7 @@ unitTest(function permissionsMatches(): void {
unitTest(
{ perms: { read: true } },
function assertAllUnitTestFilesImported(): void {
const directoryTestFiles = Deno.readdirSync("./cli/js/tests/")
const directoryTestFiles = [...Deno.readdirSync("./cli/js/tests/")]
.map((k) => k.name)
.filter(
(file) =>

View file

@ -3,6 +3,6 @@
(async (): Promise<void> => {
const currDirInfo = await Deno.stat(".");
const parentDirInfo = await Deno.stat("..");
console.log(currDirInfo.isDirectory());
console.log(parentDirInfo.isFile());
console.log(currDirInfo.isDirectory);
console.log(parentDirInfo.isFile);
})();

View file

@ -35,7 +35,7 @@ async function ensureValidCopy(
throw err;
}
if (isCopyFolder && !destStat.isDirectory()) {
if (isCopyFolder && !destStat.isDirectory) {
throw new Error(
`Cannot overwrite non-directory '${dest}' with directory '${src}'.`
);
@ -63,7 +63,7 @@ function ensureValidCopySync(
throw err;
}
if (isCopyFolder && !destStat.isDirectory()) {
if (isCopyFolder && !destStat.isDirectory) {
throw new Error(
`Cannot overwrite non-directory '${dest}' with directory '${src}'.`
);
@ -157,17 +157,14 @@ async function copyDir(
await Deno.utime(dest, srcStatInfo.accessed, srcStatInfo.modified);
}
const files = await Deno.readdir(src);
for (const file of files) {
assert(file.name != null, "file.name must be set");
for await (const file of Deno.readdir(src)) {
const srcPath = path.join(src, file.name);
const destPath = path.join(dest, path.basename(srcPath as string));
if (file.isDirectory()) {
if (file.isDirectory) {
await copyDir(srcPath, destPath, options);
} else if (file.isFile()) {
} else if (file.isFile) {
await copyFile(srcPath, destPath, options);
} else if (file.isSymlink()) {
} else if (file.isSymlink) {
await copySymLink(srcPath, destPath, options);
}
}
@ -188,17 +185,15 @@ function copyDirSync(src: string, dest: string, options: CopyOptions): void {
Deno.utimeSync(dest, srcStatInfo.accessed, srcStatInfo.modified);
}
const files = Deno.readdirSync(src);
for (const file of files) {
for (const file of Deno.readdirSync(src)) {
assert(file.name != null, "file.name must be set");
const srcPath = path.join(src, file.name);
const destPath = path.join(dest, path.basename(srcPath as string));
if (file.isDirectory()) {
if (file.isDirectory) {
copyDirSync(srcPath, destPath, options);
} else if (file.isFile()) {
} else if (file.isFile) {
copyFileSync(srcPath, destPath, options);
} else if (file.isSymlink()) {
} else if (file.isSymlink) {
copySymlinkSync(srcPath, destPath, options);
}
}
@ -228,17 +223,17 @@ export async function copy(
const srcStat = await Deno.lstat(src);
if (srcStat.isDirectory() && isSubdir(src, dest)) {
if (srcStat.isDirectory && isSubdir(src, dest)) {
throw new Error(
`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`
);
}
if (srcStat.isDirectory()) {
if (srcStat.isDirectory) {
await copyDir(src, dest, options);
} else if (srcStat.isFile()) {
} else if (srcStat.isFile) {
await copyFile(src, dest, options);
} else if (srcStat.isSymlink()) {
} else if (srcStat.isSymlink) {
await copySymLink(src, dest, options);
}
}
@ -267,17 +262,17 @@ export function copySync(
const srcStat = Deno.lstatSync(src);
if (srcStat.isDirectory() && isSubdir(src, dest)) {
if (srcStat.isDirectory && isSubdir(src, dest)) {
throw new Error(
`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`
);
}
if (srcStat.isDirectory()) {
if (srcStat.isDirectory) {
copyDirSync(src, dest, options);
} else if (srcStat.isFile()) {
} else if (srcStat.isFile) {
copyFileSync(src, dest, options);
} else if (srcStat.isSymlink()) {
} else if (srcStat.isSymlink) {
copySymlinkSync(src, dest, options);
}
}

View file

@ -266,7 +266,7 @@ testCopy(
}
assert(
(await Deno.lstat(srcLink)).isSymlink(),
(await Deno.lstat(srcLink)).isSymlink,
`'${srcLink}' should be symlink type`
);
@ -274,7 +274,7 @@ testCopy(
const statInfo = await Deno.lstat(destLink);
assert(statInfo.isSymlink(), `'${destLink}' should be symlink type`);
assert(statInfo.isSymlink, `'${destLink}' should be symlink type`);
}
);
@ -296,7 +296,7 @@ testCopy(
await ensureSymlink(srcDir, srcLink);
assert(
(await Deno.lstat(srcLink)).isSymlink(),
(await Deno.lstat(srcLink)).isSymlink,
`'${srcLink}' should be symlink type`
);
@ -304,7 +304,7 @@ testCopy(
const statInfo = await Deno.lstat(destLink);
assert(statInfo.isSymlink());
assert(statInfo.isSymlink);
}
);
@ -506,7 +506,7 @@ testCopySync(
}
assert(
Deno.lstatSync(srcLink).isSymlink(),
Deno.lstatSync(srcLink).isSymlink,
`'${srcLink}' should be symlink type`
);
@ -514,7 +514,7 @@ testCopySync(
const statInfo = Deno.lstatSync(destLink);
assert(statInfo.isSymlink(), `'${destLink}' should be symlink type`);
assert(statInfo.isSymlink, `'${destLink}' should be symlink type`);
}
);
@ -536,7 +536,7 @@ testCopySync(
ensureSymlinkSync(originDir, srcLink);
assert(
Deno.lstatSync(srcLink).isSymlink(),
Deno.lstatSync(srcLink).isSymlink,
`'${srcLink}' should be symlink type`
);
@ -544,6 +544,6 @@ testCopySync(
const statInfo = Deno.lstatSync(destLink);
assert(statInfo.isSymlink());
assert(statInfo.isSymlink);
}
);

View file

@ -10,7 +10,10 @@ const { readdir, readdirSync, mkdir, mkdirSync, remove, removeSync } = Deno;
*/
export async function emptyDir(dir: string): Promise<void> {
try {
const items = await readdir(dir);
const items = [];
for await (const dirEntry of readdir(dir)) {
items.push(dirEntry);
}
while (items.length) {
const item = items.shift();
@ -38,7 +41,7 @@ export async function emptyDir(dir: string): Promise<void> {
*/
export function emptyDirSync(dir: string): void {
try {
const items = readdirSync(dir);
const items = [...readdirSync(dir)];
// if directory already exist. then remove it's child item.
while (items.length) {

View file

@ -20,7 +20,7 @@ Deno.test(async function emptyDirIfItNotExist(): Promise<void> {
try {
// check the dir
const stat = await Deno.stat(testNestDir);
assertEquals(stat.isDirectory(), true);
assertEquals(stat.isDirectory, true);
} finally {
// remove the test dir
await Deno.remove(testDir, { recursive: true });
@ -36,7 +36,7 @@ Deno.test(function emptyDirSyncIfItNotExist(): void {
try {
// check the dir
const stat = Deno.statSync(testNestDir);
assertEquals(stat.isDirectory(), true);
assertEquals(stat.isDirectory, true);
} finally {
// remove the test dir
Deno.removeSync(testDir, { recursive: true });
@ -54,10 +54,10 @@ Deno.test(async function emptyDirIfItExist(): Promise<void> {
// before empty: make sure file/directory exist
const beforeFileStat = await Deno.stat(testDirFile);
assertEquals(beforeFileStat.isFile(), true);
assertEquals(beforeFileStat.isFile, true);
const beforeDirStat = await Deno.stat(testNestDir);
assertEquals(beforeDirStat.isDirectory(), true);
assertEquals(beforeDirStat.isDirectory, true);
await emptyDir(testDir);
@ -65,7 +65,7 @@ Deno.test(async function emptyDirIfItExist(): Promise<void> {
try {
// test dir still there
const stat = await Deno.stat(testDir);
assertEquals(stat.isDirectory(), true);
assertEquals(stat.isDirectory, true);
// nest directory have been remove
await assertThrowsAsync(
@ -97,10 +97,10 @@ Deno.test(function emptyDirSyncIfItExist(): void {
// before empty: make sure file/directory exist
const beforeFileStat = Deno.statSync(testDirFile);
assertEquals(beforeFileStat.isFile(), true);
assertEquals(beforeFileStat.isFile, true);
const beforeDirStat = Deno.statSync(testNestDir);
assertEquals(beforeDirStat.isDirectory(), true);
assertEquals(beforeDirStat.isDirectory, true);
emptyDirSync(testDir);
@ -108,7 +108,7 @@ Deno.test(function emptyDirSyncIfItExist(): void {
try {
// test dir still there
const stat = Deno.statSync(testDir);
assertEquals(stat.isDirectory(), true);
assertEquals(stat.isDirectory, true);
// nest directory have been remove
assertThrows((): void => {

View file

@ -10,7 +10,7 @@ const { lstat, lstatSync, mkdir, mkdirSync } = Deno;
export async function ensureDir(dir: string): Promise<void> {
try {
const fileInfo = await lstat(dir);
if (!fileInfo.isDirectory()) {
if (!fileInfo.isDirectory) {
throw new Error(
`Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'`
);
@ -33,7 +33,7 @@ export async function ensureDir(dir: string): Promise<void> {
export function ensureDirSync(dir: string): void {
try {
const fileInfo = lstatSync(dir);
if (!fileInfo.isDirectory()) {
if (!fileInfo.isDirectory) {
throw new Error(
`Ensure path exists, expected 'dir', got '${getFileInfoType(fileInfo)}'`
);

View file

@ -16,7 +16,7 @@ export async function ensureFile(filePath: string): Promise<void> {
try {
// if file exists
const stat = await lstat(filePath);
if (!stat.isFile()) {
if (!stat.isFile) {
throw new Error(
`Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`
);
@ -47,7 +47,7 @@ export function ensureFileSync(filePath: string): void {
try {
// if file exists
const stat = lstatSync(filePath);
if (!stat.isFile()) {
if (!stat.isFile) {
throw new Error(
`Ensure path exists, expected 'file', got '${getFileInfoType(stat)}'`
);

View file

@ -50,8 +50,8 @@ Deno.test(async function ensureLinkIfItExist(): Promise<void> {
const srcStat = await Deno.lstat(testFile);
const linkStat = await Deno.lstat(linkFile);
assertEquals(srcStat.isFile(), true);
assertEquals(linkStat.isFile(), true);
assertEquals(srcStat.isFile, true);
assertEquals(linkStat.isFile, true);
// har link success. try to change one of them. they should be change both.
@ -98,8 +98,8 @@ Deno.test(function ensureLinkSyncIfItExist(): void {
const linkStat = Deno.lstatSync(linkFile);
assertEquals(srcStat.isFile(), true);
assertEquals(linkStat.isFile(), true);
assertEquals(srcStat.isFile, true);
assertEquals(linkStat.isFile, true);
// har link success. try to change one of them. they should be change both.

View file

@ -67,8 +67,8 @@ Deno.test(async function ensureSymlinkIfItExist(): Promise<void> {
const srcStat = await Deno.lstat(testFile);
const linkStat = await Deno.lstat(linkFile);
assertEquals(srcStat.isFile(), true);
assertEquals(linkStat.isSymlink(), true);
assertEquals(srcStat.isFile, true);
assertEquals(linkStat.isSymlink, true);
await Deno.remove(testDir, { recursive: true });
});
@ -97,8 +97,8 @@ Deno.test(function ensureSymlinkSyncIfItExist(): void {
const linkStat = Deno.lstatSync(linkFile);
assertEquals(srcStat.isFile(), true);
assertEquals(linkStat.isSymlink(), true);
assertEquals(srcStat.isFile, true);
assertEquals(linkStat.isSymlink, true);
Deno.removeSync(testDir, { recursive: true });
});
@ -127,9 +127,9 @@ Deno.test(async function ensureSymlinkDirectoryIfItExist(): Promise<void> {
const linkDirStat = await Deno.lstat(linkDir);
const testFileStat = await Deno.lstat(testFile);
assertEquals(testFileStat.isFile(), true);
assertEquals(testDirStat.isDirectory(), true);
assertEquals(linkDirStat.isSymlink(), true);
assertEquals(testFileStat.isFile, true);
assertEquals(testDirStat.isDirectory, true);
assertEquals(linkDirStat.isSymlink, true);
await Deno.remove(linkDir, { recursive: true });
await Deno.remove(testDir, { recursive: true });
@ -159,9 +159,9 @@ Deno.test(function ensureSymlinkSyncDirectoryIfItExist(): void {
const linkDirStat = Deno.lstatSync(linkDir);
const testFileStat = Deno.lstatSync(testFile);
assertEquals(testFileStat.isFile(), true);
assertEquals(testDirStat.isDirectory(), true);
assertEquals(linkDirStat.isSymlink(), true);
assertEquals(testFileStat.isFile, true);
assertEquals(testDirStat.isDirectory, true);
assertEquals(linkDirStat.isSymlink, true);
Deno.removeSync(linkDir, { recursive: true });
Deno.removeSync(testDir, { recursive: true });

View file

@ -8,7 +8,7 @@ import {
joinGlobs,
normalize,
} from "../path/mod.ts";
import { WalkInfo, walk, walkSync } from "./walk.ts";
import { WalkEntry, walk, walkSync } from "./walk.ts";
import { assert } from "../testing/asserts.ts";
const { cwd, stat, statSync } = Deno;
type FileInfo = Deno.FileInfo;
@ -50,7 +50,7 @@ function throwUnlessNotFound(error: Error): void {
/**
* Expand the glob string from the specified `root` directory and yield each
* result as a `WalkInfo` object.
* result as a `WalkEntry` object.
*/
export async function* expandGlob(
glob: string,
@ -61,7 +61,7 @@ export async function* expandGlob(
extended = false,
globstar = false,
}: ExpandGlobOptions = {}
): AsyncIterableIterator<WalkInfo> {
): AsyncIterableIterator<WalkEntry> {
const globOptions: GlobOptions = { extended, globstar };
const absRoot = isAbsolute(root)
? normalize(root)
@ -84,7 +84,7 @@ export async function* expandGlob(
fixedRoot = joinGlobs([fixedRoot, seg], globOptions);
}
let fixedRootInfo: WalkInfo;
let fixedRootInfo: WalkEntry;
try {
fixedRootInfo = { filename: fixedRoot, info: await stat(fixedRoot) };
} catch (error) {
@ -92,10 +92,10 @@ export async function* expandGlob(
}
async function* advanceMatch(
walkInfo: WalkInfo,
walkInfo: WalkEntry,
globSegment: string
): AsyncIterableIterator<WalkInfo> {
if (!walkInfo.info.isDirectory()) {
): AsyncIterableIterator<WalkEntry> {
if (!walkInfo.info.isDirectory) {
return;
} else if (globSegment == "..") {
const parentPath = joinGlobs([walkInfo.filename, ".."], globOptions);
@ -125,7 +125,7 @@ export async function* expandGlob(
});
}
let currentMatches: WalkInfo[] = [fixedRootInfo];
let currentMatches: WalkEntry[] = [fixedRootInfo];
for (const segment of segments) {
// Advancing the list of current matches may introduce duplicates, so we
// pass everything through this Map.
@ -136,20 +136,20 @@ export async function* expandGlob(
}
}
currentMatches = [...nextMatchMap].sort().map(
([filename, info]): WalkInfo => ({
([filename, info]): WalkEntry => ({
filename,
info,
})
);
}
if (hasTrailingSep) {
currentMatches = currentMatches.filter(({ info }): boolean =>
info.isDirectory()
currentMatches = currentMatches.filter(
({ info }): boolean => info.isDirectory
);
}
if (!includeDirs) {
currentMatches = currentMatches.filter(
({ info }): boolean => !info.isDirectory()
({ info }): boolean => !info.isDirectory
);
}
yield* currentMatches;
@ -165,7 +165,7 @@ export function* expandGlobSync(
extended = false,
globstar = false,
}: ExpandGlobOptions = {}
): IterableIterator<WalkInfo> {
): IterableIterator<WalkEntry> {
const globOptions: GlobOptions = { extended, globstar };
const absRoot = isAbsolute(root)
? normalize(root)
@ -188,7 +188,7 @@ export function* expandGlobSync(
fixedRoot = joinGlobs([fixedRoot, seg], globOptions);
}
let fixedRootInfo: WalkInfo;
let fixedRootInfo: WalkEntry;
try {
fixedRootInfo = { filename: fixedRoot, info: statSync(fixedRoot) };
} catch (error) {
@ -196,10 +196,10 @@ export function* expandGlobSync(
}
function* advanceMatch(
walkInfo: WalkInfo,
walkInfo: WalkEntry,
globSegment: string
): IterableIterator<WalkInfo> {
if (!walkInfo.info.isDirectory()) {
): IterableIterator<WalkEntry> {
if (!walkInfo.info.isDirectory) {
return;
} else if (globSegment == "..") {
const parentPath = joinGlobs([walkInfo.filename, ".."], globOptions);
@ -229,7 +229,7 @@ export function* expandGlobSync(
});
}
let currentMatches: WalkInfo[] = [fixedRootInfo];
let currentMatches: WalkEntry[] = [fixedRootInfo];
for (const segment of segments) {
// Advancing the list of current matches may introduce duplicates, so we
// pass everything through this Map.
@ -240,20 +240,20 @@ export function* expandGlobSync(
}
}
currentMatches = [...nextMatchMap].sort().map(
([filename, info]): WalkInfo => ({
([filename, info]): WalkEntry => ({
filename,
info,
})
);
}
if (hasTrailingSep) {
currentMatches = currentMatches.filter(({ info }): boolean =>
info.isDirectory()
currentMatches = currentMatches.filter(
({ info }): boolean => info.isDirectory
);
}
if (!includeDirs) {
currentMatches = currentMatches.filter(
({ info }): boolean => !info.isDirectory()
({ info }): boolean => !info.isDirectory
);
}
yield* currentMatches;

View file

@ -14,7 +14,7 @@ export async function move(
): Promise<void> {
const srcStat = await Deno.stat(src);
if (srcStat.isDirectory() && isSubdir(src, dest)) {
if (srcStat.isDirectory && isSubdir(src, dest)) {
throw new Error(
`Cannot move '${src}' to a subdirectory of itself, '${dest}'.`
);
@ -41,7 +41,7 @@ export function moveSync(
): void {
const srcStat = Deno.statSync(src);
if (srcStat.isDirectory() && isSubdir(src, dest)) {
if (srcStat.isDirectory && isSubdir(src, dest)) {
throw new Error(
`Cannot move '${src}' to a subdirectory of itself, '${dest}'.`
);

View file

@ -35,11 +35,11 @@ export type PathType = "file" | "dir" | "symlink";
* `lstat`
*/
export function getFileInfoType(fileInfo: Deno.FileInfo): PathType | undefined {
return fileInfo.isFile()
return fileInfo.isFile
? "file"
: fileInfo.isDirectory()
: fileInfo.isDirectory
? "dir"
: fileInfo.isSymlink()
: fileInfo.isSymlink
? "symlink"
: undefined;
}

View file

@ -4,7 +4,6 @@
import { unimplemented, assert } from "../testing/asserts.ts";
import { join } from "../path/mod.ts";
const { readdir, readdirSync, stat, statSync } = Deno;
type FileInfo = Deno.FileInfo;
export interface WalkOptions {
maxDepth?: number;
@ -34,9 +33,9 @@ function include(
return true;
}
export interface WalkInfo {
export interface WalkEntry {
filename: string;
info: FileInfo;
info: Deno.FileInfo;
}
/** Walks the file tree rooted at root, yielding each file or directory in the
@ -55,7 +54,7 @@ export interface WalkInfo {
*
* for await (const { filename, info } of walk(".")) {
* console.log(filename);
* assert(info.isFile());
* assert(info.isFile);
* };
*/
export async function* walk(
@ -69,7 +68,7 @@ export async function* walk(
match = undefined,
skip = undefined,
}: WalkOptions = {}
): AsyncIterableIterator<WalkInfo> {
): AsyncIterableIterator<WalkEntry> {
if (maxDepth < 0) {
return;
}
@ -79,9 +78,8 @@ export async function* walk(
if (maxDepth < 1 || !include(root, undefined, undefined, skip)) {
return;
}
const ls: FileInfo[] = await readdir(root);
for (const info of ls) {
if (info.isSymlink()) {
for await (const dirEntry of readdir(root)) {
if (dirEntry.isSymlink) {
if (followSymlinks) {
// TODO(ry) Re-enable followSymlinks.
unimplemented();
@ -90,12 +88,11 @@ export async function* walk(
}
}
assert(info.name != null);
const filename = join(root, info.name);
const filename = join(root, dirEntry.name);
if (info.isFile()) {
if (dirEntry.isFile) {
if (includeFiles && include(filename, exts, match, skip)) {
yield { filename, info };
yield { filename, info: dirEntry };
}
} else {
yield* walk(filename, {
@ -123,7 +120,7 @@ export function* walkSync(
match = undefined,
skip = undefined,
}: WalkOptions = {}
): IterableIterator<WalkInfo> {
): IterableIterator<WalkEntry> {
if (maxDepth < 0) {
return;
}
@ -133,9 +130,8 @@ export function* walkSync(
if (maxDepth < 1 || !include(root, undefined, undefined, skip)) {
return;
}
const ls: FileInfo[] = readdirSync(root);
for (const info of ls) {
if (info.isSymlink()) {
for (const dirEntry of readdirSync(root)) {
if (dirEntry.isSymlink) {
if (followSymlinks) {
unimplemented();
} else {
@ -143,12 +139,12 @@ export function* walkSync(
}
}
assert(info.name != null);
const filename = join(root, info.name);
assert(dirEntry.name != null);
const filename = join(root, dirEntry.name);
if (info.isFile()) {
if (dirEntry.isFile) {
if (includeFiles && include(filename, exts, match, skip)) {
yield { filename, info };
yield { filename, info: dirEntry };
}
} else {
yield* walkSync(filename, {

View file

@ -1,6 +1,6 @@
const { cwd, chdir, makeTempDir, mkdir, open, symlink } = Deno;
const { remove } = Deno;
import { walk, walkSync, WalkOptions, WalkInfo } from "./walk.ts";
import { walk, walkSync, WalkOptions, WalkEntry } from "./walk.ts";
import { assert, assertEquals, assertThrowsAsync } from "../testing/asserts.ts";
const isWindows = Deno.build.os == "win";
@ -26,7 +26,7 @@ export function testWalk(
Deno.test({ ignore, name: `[walk] ${name}`, fn });
}
function normalize({ filename }: WalkInfo): string {
function normalize({ filename }: WalkEntry): string {
return filename.replace(/\\/g, "/");
}

View file

@ -140,11 +140,10 @@ async function serveDir(
): Promise<Response> {
const dirUrl = `/${posix.relative(target, dirPath)}`;
const listEntry: EntryInfo[] = [];
const fileInfos = await readdir(dirPath);
for (const fileInfo of fileInfos) {
const filePath = posix.join(dirPath, fileInfo.name ?? "");
const fileUrl = posix.join(dirUrl, fileInfo.name ?? "");
if (fileInfo.name === "index.html" && fileInfo.isFile()) {
for await (const dirEntry of readdir(dirPath)) {
const filePath = posix.join(dirPath, dirEntry.name);
const fileUrl = posix.join(dirUrl, dirEntry.name);
if (dirEntry.name === "index.html" && dirEntry.isFile) {
// in case index.html as dir...
return serveFile(req, filePath);
}
@ -154,9 +153,9 @@ async function serveDir(
mode = (await stat(filePath)).mode;
} catch (e) {}
listEntry.push({
mode: modeToString(fileInfo.isDirectory(), mode),
size: fileInfo.isFile() ? fileLenToString(fileInfo.size) : "",
name: fileInfo.name ?? "",
mode: modeToString(dirEntry.isDirectory, mode),
size: dirEntry.isFile ? fileLenToString(dirEntry.size) : "",
name: dirEntry.name,
url: fileUrl,
});
}
@ -333,7 +332,7 @@ function main(): void {
let response: Response | undefined;
try {
const info = await stat(fsPath);
if (info.isDirectory()) {
if (info.isDirectory) {
response = await serveDir(req, fsPath);
} else {
response = await serveFile(req, fsPath);

View file

@ -29,7 +29,10 @@ export default class Dir {
return new Promise(async (resolve, reject) => {
try {
if (this.initializationOfDirectoryFilesIsRequired()) {
const denoFiles: Deno.FileInfo[] = await Deno.readdir(this.path);
const denoFiles: Deno.DirEntry[] = [];
for await (const dirEntry of Deno.readdir(this.path)) {
denoFiles.push(dirEntry);
}
this.files = denoFiles.map((file) => new Dirent(file));
}
const nextFile = this.files.pop();
@ -55,7 +58,7 @@ export default class Dir {
readSync(): Dirent | null {
if (this.initializationOfDirectoryFilesIsRequired()) {
this.files.push(
...Deno.readdirSync(this.path).map((file) => new Dirent(file))
...[...Deno.readdirSync(this.path)].map((file) => new Dirent(file))
);
}
const dirent: Dirent | undefined = this.files.pop();

View file

@ -1,7 +1,7 @@
import { notImplemented } from "../_utils.ts";
export default class Dirent {
constructor(private entry: Deno.FileInfo) {}
constructor(private entry: Deno.DirEntry) {}
isBlockDevice(): boolean {
return this.entry.blocks != null;
@ -12,7 +12,7 @@ export default class Dirent {
}
isDirectory(): boolean {
return this.entry.isDirectory();
return this.entry.isDirectory;
}
isFIFO(): boolean {
@ -23,7 +23,7 @@ export default class Dirent {
}
isFile(): boolean {
return this.entry.isFile();
return this.entry.isFile;
}
isSocket(): boolean {
@ -32,7 +32,7 @@ export default class Dirent {
}
isSymbolicLink(): boolean {
return this.entry.isSymlink();
return this.entry.isSymlink;
}
get name(): string | null {

View file

@ -2,7 +2,10 @@ const { test } = Deno;
import { assert, assertEquals, assertThrows } from "../../testing/asserts.ts";
import Dirent from "./_fs_dirent.ts";
class FileInfoMock implements Deno.FileInfo {
class DirEntryMock implements Deno.DirEntry {
isFile = false;
isDirectory = false;
isSymlink = false;
size = -1;
modified = -1;
accessed = -1;
@ -17,26 +20,12 @@ class FileInfoMock implements Deno.FileInfo {
rdev = -1;
blksize = -1;
blocks: number | null = null;
isFileMock = false;
isDirectoryMock = false;
isSymlinkMock = false;
isFile(): boolean {
return this.isFileMock;
}
isDirectory(): boolean {
return this.isDirectoryMock;
}
isSymlink(): boolean {
return this.isSymlinkMock;
}
}
test({
name: "Block devices are correctly identified",
fn() {
const fileInfo: FileInfoMock = new FileInfoMock();
const fileInfo: DirEntryMock = new DirEntryMock();
fileInfo.blocks = 5;
assert(new Dirent(fileInfo).isBlockDevice());
assert(!new Dirent(fileInfo).isCharacterDevice());
@ -46,7 +35,7 @@ test({
test({
name: "Character devices are correctly identified",
fn() {
const fileInfo: FileInfoMock = new FileInfoMock();
const fileInfo: DirEntryMock = new DirEntryMock();
fileInfo.blocks = null;
assert(new Dirent(fileInfo).isCharacterDevice());
assert(!new Dirent(fileInfo).isBlockDevice());
@ -56,10 +45,10 @@ test({
test({
name: "Directories are correctly identified",
fn() {
const fileInfo: FileInfoMock = new FileInfoMock();
fileInfo.isDirectoryMock = true;
fileInfo.isFileMock = false;
fileInfo.isSymlinkMock = false;
const fileInfo: DirEntryMock = new DirEntryMock();
fileInfo.isDirectory = true;
fileInfo.isFile = false;
fileInfo.isSymlink = false;
assert(new Dirent(fileInfo).isDirectory());
assert(!new Dirent(fileInfo).isFile());
assert(!new Dirent(fileInfo).isSymbolicLink());
@ -69,10 +58,10 @@ test({
test({
name: "Files are correctly identified",
fn() {
const fileInfo: FileInfoMock = new FileInfoMock();
fileInfo.isDirectoryMock = false;
fileInfo.isFileMock = true;
fileInfo.isSymlinkMock = false;
const fileInfo: DirEntryMock = new DirEntryMock();
fileInfo.isDirectory = false;
fileInfo.isFile = true;
fileInfo.isSymlink = false;
assert(!new Dirent(fileInfo).isDirectory());
assert(new Dirent(fileInfo).isFile());
assert(!new Dirent(fileInfo).isSymbolicLink());
@ -82,10 +71,10 @@ test({
test({
name: "Symlinks are correctly identified",
fn() {
const fileInfo: FileInfoMock = new FileInfoMock();
fileInfo.isDirectoryMock = false;
fileInfo.isFileMock = false;
fileInfo.isSymlinkMock = true;
const fileInfo: DirEntryMock = new DirEntryMock();
fileInfo.isDirectory = false;
fileInfo.isFile = false;
fileInfo.isSymlink = true;
assert(!new Dirent(fileInfo).isDirectory());
assert(!new Dirent(fileInfo).isFile());
assert(new Dirent(fileInfo).isSymbolicLink());
@ -95,7 +84,7 @@ test({
test({
name: "File name is correct",
fn() {
const fileInfo: FileInfoMock = new FileInfoMock();
const fileInfo: DirEntryMock = new DirEntryMock();
fileInfo.name = "my_file";
assertEquals(new Dirent(fileInfo).name, "my_file");
},
@ -104,7 +93,7 @@ test({
test({
name: "Socket and FIFO pipes aren't yet available",
fn() {
const fileInfo: FileInfoMock = new FileInfoMock();
const fileInfo: DirEntryMock = new DirEntryMock();
assertThrows(
() => {
new Dirent(fileInfo).isFIFO();

View file

@ -54,7 +54,7 @@ function stat(filename: string): StatResult {
}
try {
const info = Deno.statSync(filename);
const result = info.isFile() ? 0 : 1;
const result = info.isFile ? 0 : 1;
if (statCache !== null) statCache.set(filename, result);
return result;
} catch (e) {