1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-29 16:30:56 -05:00

refactor: move existing fs implementation to internal _fs directory (#4381)

This commit is contained in:
Chris Knight 2020-03-15 15:48:46 +00:00 committed by GitHub
parent dc6e0c3591
commit 620dd9724d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 320 additions and 185 deletions

View file

@ -0,0 +1,23 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { CallbackWithError } from "./_fs_common.ts";
import { notImplemented } from "../_utils.ts";
/** Revist once https://github.com/denoland/deno/issues/4017 lands */
//TODO - 'path' can also be a Buffer or URL. Neither of these polyfills
//is available yet. See https://github.com/denoland/deno/issues/3403
export function access(
path: string, // eslint-disable-line @typescript-eslint/no-unused-vars
modeOrCallback: number | Function, // eslint-disable-line @typescript-eslint/no-unused-vars
callback?: CallbackWithError // eslint-disable-line @typescript-eslint/no-unused-vars
): void {
notImplemented("Not yet available");
}
//TODO - 'path' can also be a Buffer or URL. Neither of these polyfills
//is available yet. See https://github.com/denoland/deno/issues/3403
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function accessSync(path: string, mode?: number): void {
notImplemented("Not yet available");
}

View file

@ -4,41 +4,8 @@ import { fail, assert } from "../../testing/asserts.ts";
import { chmod, chmodSync } from "./_fs_chmod.ts";
test({
name: "ASYNC: Error passed in callback function when bad mode passed in",
async fn() {
await new Promise((resolve, reject) => {
chmod("some_pretend_file.txt", "999", err => {
if (err) reject(err);
else resolve();
});
})
.then(() => {
fail("Expected exception to be thrown");
})
.catch(err => {
assert(err);
});
}
});
test({
name: "SYNC: Error thrown when bad mode passed in",
fn() {
let caughtError: Error | undefined;
try {
chmodSync("some_pretend_file.txt", "999");
} catch (err) {
caughtError = err;
}
assert(caughtError);
}
});
const skip = Deno.build.os == "win";
test({
skip,
name: "ASYNC: Permissions are changed (non-Windows)",
skip: Deno.build.os === "win",
async fn() {
const tempFile: string = await Deno.makeTempFile();
const originalFileMode: number | null = (await Deno.lstat(tempFile)).mode;
@ -63,8 +30,8 @@ test({
});
test({
skip,
name: "SYNC: Permissions are changed (non-Windows)",
skip: Deno.build.os === "win",
fn() {
const tempFile: string = Deno.makeTempFileSync();
const originalFileMode: number | null = Deno.lstatSync(tempFile).mode;

View file

@ -0,0 +1,80 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
notImplemented,
intoCallbackAPIWithIntercept,
MaybeEmpty
} from "../_utils.ts";
const { readFile: denoReadFile, readFileSync: denoReadFileSync } = Deno;
type ReadFileCallback = (
err: MaybeEmpty<Error>,
data: MaybeEmpty<string | Uint8Array>
) => void;
interface ReadFileOptions {
encoding?: string | null;
flag?: string;
}
function getEncoding(
optOrCallback?: ReadFileOptions | ReadFileCallback
): string | null {
if (!optOrCallback || typeof optOrCallback === "function") {
return null;
} else {
if (optOrCallback.encoding) {
if (
optOrCallback.encoding === "utf8" ||
optOrCallback.encoding === "utf-8"
) {
return "utf8";
} else if (optOrCallback.encoding === "buffer") {
return "buffer";
} else {
notImplemented();
}
}
return null;
}
}
function maybeDecode(
data: Uint8Array,
encoding: string | null
): string | Uint8Array {
if (encoding === "utf8") {
return new TextDecoder().decode(data);
}
return data;
}
export function readFile(
path: string,
optOrCallback: ReadFileCallback | ReadFileOptions,
callback?: ReadFileCallback
): void {
let cb: ReadFileCallback | undefined;
if (typeof optOrCallback === "function") {
cb = optOrCallback;
} else {
cb = callback;
}
const encoding = getEncoding(optOrCallback);
intoCallbackAPIWithIntercept<Uint8Array, string | Uint8Array>(
denoReadFile,
(data: Uint8Array): string | Uint8Array => maybeDecode(data, encoding),
cb,
path
);
}
export function readFileSync(
path: string,
opt?: ReadFileOptions
): string | Uint8Array {
return maybeDecode(denoReadFileSync(path), getEncoding(opt));
}

View file

@ -0,0 +1,48 @@
const { test } = Deno;
import { readFile, readFileSync } from "./_fs_readFile.ts";
import * as path from "../../path/mod.ts";
import { assertEquals, assert } from "../../testing/asserts.ts";
const testData = path.resolve(
path.join("node", "_fs", "testdata", "hello.txt")
);
test(async function readFileSuccess() {
const data = await new Promise((res, rej) => {
readFile(testData, (err, data) => {
if (err) {
rej(err);
}
res(data);
});
});
assert(data instanceof Uint8Array);
assertEquals(new TextDecoder().decode(data as Uint8Array), "hello world");
});
test(async function readFileEncodeUtf8Success() {
const data = await new Promise((res, rej) => {
readFile(testData, { encoding: "utf8" }, (err, data) => {
if (err) {
rej(err);
}
res(data);
});
});
assertEquals(typeof data, "string");
assertEquals(data as string, "hello world");
});
test(function readFileSyncSuccess() {
const data = readFileSync(testData);
assert(data instanceof Uint8Array);
assertEquals(new TextDecoder().decode(data as Uint8Array), "hello world");
});
test(function readFileEncodeUtf8Success() {
const data = readFileSync(testData, { encoding: "utf8" });
assertEquals(typeof data, "string");
assertEquals(data as string, "hello world");
});

View file

@ -0,0 +1,78 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
intoCallbackAPIWithIntercept,
MaybeEmpty,
notImplemented
} from "../_utils.ts";
const { readlink: denoReadlink, readlinkSync: denoReadlinkSync } = Deno;
type ReadlinkCallback = (
err: MaybeEmpty<Error>,
linkString: MaybeEmpty<string | Uint8Array>
) => void;
interface ReadlinkOptions {
encoding?: string | null;
}
function maybeEncode(
data: string,
encoding: string | null
): string | Uint8Array {
if (encoding === "buffer") {
return new TextEncoder().encode(data);
}
return data;
}
function getEncoding(
optOrCallback?: ReadlinkOptions | ReadlinkCallback
): string | null {
if (!optOrCallback || typeof optOrCallback === "function") {
return null;
} else {
if (optOrCallback.encoding) {
if (
optOrCallback.encoding === "utf8" ||
optOrCallback.encoding === "utf-8"
) {
return "utf8";
} else if (optOrCallback.encoding === "buffer") {
return "buffer";
} else {
notImplemented();
}
}
return null;
}
}
export function readlink(
path: string,
optOrCallback: ReadlinkCallback | ReadlinkOptions,
callback?: ReadlinkCallback
): void {
let cb: ReadlinkCallback | undefined;
if (typeof optOrCallback === "function") {
cb = optOrCallback;
} else {
cb = callback;
}
const encoding = getEncoding(optOrCallback);
intoCallbackAPIWithIntercept<string, Uint8Array | string>(
denoReadlink,
(data: string): string | Uint8Array => maybeEncode(data, encoding),
cb,
path
);
}
export function readlinkSync(
path: string,
opt?: ReadlinkOptions
): string | Uint8Array {
return maybeEncode(denoReadlinkSync(path), getEncoding(opt));
}

View file

@ -0,0 +1,67 @@
const { test } = Deno;
import { readlink, readlinkSync } from "./_fs_readlink.ts";
import { assertEquals, assert } from "../../testing/asserts.ts";
const testDir = Deno.makeTempDirSync();
const oldname = testDir + "/oldname";
const newname = testDir + "/newname";
if (Deno.build.os !== "win") {
Deno.symlinkSync(oldname, newname);
}
test({
name: "readlinkSuccess",
skip: Deno.build.os === "win",
async fn() {
const data = await new Promise((res, rej) => {
readlink(newname, (err, data) => {
if (err) {
rej(err);
}
res(data);
});
});
assertEquals(typeof data, "string");
assertEquals(data as string, oldname);
}
});
test({
name: "readlinkEncodeBufferSuccess",
skip: Deno.build.os === "win",
async fn() {
const data = await new Promise((res, rej) => {
readlink(newname, { encoding: "buffer" }, (err, data) => {
if (err) {
rej(err);
}
res(data);
});
});
assert(data instanceof Uint8Array);
assertEquals(new TextDecoder().decode(data as Uint8Array), oldname);
}
});
test({
name: "readlinkSyncSuccess",
skip: Deno.build.os === "win",
fn() {
const data = readlinkSync(newname);
assertEquals(typeof data, "string");
assertEquals(data as string, oldname);
}
});
test({
name: "readlinkEncodeBufferSuccess",
skip: Deno.build.os === "win",
fn() {
const data = readlinkSync(newname, { encoding: "buffer" });
assert(data instanceof Uint8Array);
assertEquals(new TextDecoder().decode(data as Uint8Array), oldname);
}
});

View file

@ -1,156 +1,28 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
notImplemented,
intoCallbackAPIWithIntercept,
MaybeEmpty
} from "./_utils.ts";
import { access, accessSync } from "./_fs/_fs_access.ts";
import { appendFile, appendFileSync } from "./_fs/_fs_appendFile.ts";
export { appendFile, appendFileSync };
import { chmod, chmodSync } from "./_fs/_fs_chmod.ts";
export { chmod, chmodSync };
import { chown, chownSync } from "./_fs/_fs_chown.ts";
import { close, closeSync } from "./_fs/_fs_close.ts";
import * as constants from "./_fs/_fs_constants.ts";
export { constants };
import { readFile, readFileSync } from "./_fs/_fs_readFile.ts";
import { readlink, readlinkSync } from "./_fs/_fs_readlink.ts";
const {
readFile: denoReadFile,
readFileSync: denoReadFileSync,
readlink: denoReadlink,
readlinkSync: denoReadlinkSync
} = Deno;
type ReadFileCallback = (
err: MaybeEmpty<Error>,
data: MaybeEmpty<string | Uint8Array>
) => void;
interface ReadFileOptions {
encoding?: string | null;
flag?: string;
}
type ReadlinkCallback = (
err: MaybeEmpty<Error>,
linkString: MaybeEmpty<string | Uint8Array>
) => void;
interface ReadlinkOptions {
encoding?: string | null;
}
function getEncoding(
optOrCallback?: ReadFileOptions | ReadFileCallback
): string | null {
if (!optOrCallback || typeof optOrCallback === "function") {
return null;
} else {
if (optOrCallback.encoding) {
if (
optOrCallback.encoding === "utf8" ||
optOrCallback.encoding === "utf-8"
) {
return "utf8";
} else if (optOrCallback.encoding === "buffer") {
return "buffer";
} else {
notImplemented();
}
}
return null;
}
}
function maybeDecode(
data: Uint8Array,
encoding: string | null
): string | Uint8Array {
if (encoding === "utf8") {
return new TextDecoder().decode(data);
}
return data;
}
function maybeEncode(
data: string,
encoding: string | null
): string | Uint8Array {
if (encoding === "buffer") {
return new TextEncoder().encode(data);
}
return data;
}
export function readFile(
path: string,
optOrCallback: ReadFileCallback | ReadFileOptions,
callback?: ReadFileCallback
): void {
let cb: ReadFileCallback | undefined;
if (typeof optOrCallback === "function") {
cb = optOrCallback;
} else {
cb = callback;
}
const encoding = getEncoding(optOrCallback);
intoCallbackAPIWithIntercept<Uint8Array, string | Uint8Array>(
denoReadFile,
(data: Uint8Array): string | Uint8Array => maybeDecode(data, encoding),
cb,
path
);
}
export function readFileSync(
path: string,
opt?: ReadFileOptions
): string | Uint8Array {
return maybeDecode(denoReadFileSync(path), getEncoding(opt));
}
export function readlink(
path: string,
optOrCallback: ReadlinkCallback | ReadlinkOptions,
callback?: ReadlinkCallback
): void {
let cb: ReadlinkCallback | undefined;
if (typeof optOrCallback === "function") {
cb = optOrCallback;
} else {
cb = callback;
}
const encoding = getEncoding(optOrCallback);
intoCallbackAPIWithIntercept<string, Uint8Array | string>(
denoReadlink,
(data: string): string | Uint8Array => maybeEncode(data, encoding),
cb,
path
);
}
export function readlinkSync(
path: string,
opt?: ReadlinkOptions
): string | Uint8Array {
return maybeEncode(denoReadlinkSync(path), getEncoding(opt));
}
/** Revist once https://github.com/denoland/deno/issues/4017 lands */
export function access(
path: string, // eslint-disable-line @typescript-eslint/no-unused-vars
modeOrCallback: number | Function, // eslint-disable-line @typescript-eslint/no-unused-vars
callback?: Function // eslint-disable-line @typescript-eslint/no-unused-vars
): void {
notImplemented("Not yet available");
}
/** Revist once https://github.com/denoland/deno/issues/4017 lands */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function accessSync(path: string, mode?: number): undefined {
notImplemented("Not yet available");
}
export {
access,
accessSync,
appendFile,
appendFileSync,
chmod,
chmodSync,
chown,
chownSync,
close,
closeSync,
constants,
readFile,
readFileSync,
readlink,
readlinkSync
};