From e8f639ce53c5a232c84d499b0d6375a2d2ad7131 Mon Sep 17 00:00:00 2001 From: Benny Shi <740004544@qq.com> Date: Mon, 10 Feb 2020 17:38:05 +0800 Subject: Add readlink, readlinkSync for std/node/fs.ts (#3926) --- std/node/fs.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++- std/node/fs_test.ts | 49 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 2 deletions(-) mode change 100644 => 100755 std/node/fs.ts mode change 100644 => 100755 std/node/fs_test.ts (limited to 'std/node') diff --git a/std/node/fs.ts b/std/node/fs.ts old mode 100644 new mode 100755 index 539916c9e..eb6830acb --- a/std/node/fs.ts +++ b/std/node/fs.ts @@ -3,7 +3,12 @@ import { intoCallbackAPIWithIntercept, MaybeEmpty } from "./_utils.ts"; -const { readFile: denoReadFile, readFileSync: denoReadFileSync } = Deno; +const { + readFile: denoReadFile, + readFileSync: denoReadFileSync, + readlink: denoReadlink, + readlinkSync: denoReadlinkSync +} = Deno; type ReadFileCallback = ( err: MaybeEmpty, @@ -15,6 +20,15 @@ interface ReadFileOptions { flag?: string; } +type ReadlinkCallback = ( + err: MaybeEmpty, + linkString: MaybeEmpty +) => void; + +interface ReadlinkOptions { + encoding?: string | null; +} + function getEncoding( optOrCallback?: ReadFileOptions | ReadFileCallback ): string | null { @@ -27,6 +41,8 @@ function getEncoding( optOrCallback.encoding === "utf-8" ) { return "utf8"; + } else if (optOrCallback.encoding === "buffer") { + return "buffer"; } else { notImplemented(); } @@ -45,6 +61,16 @@ function maybeDecode( 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, @@ -73,3 +99,32 @@ export function readFileSync( ): 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( + 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)); +} diff --git a/std/node/fs_test.ts b/std/node/fs_test.ts old mode 100644 new mode 100755 index 81b9594f1..c63891c44 --- a/std/node/fs_test.ts +++ b/std/node/fs_test.ts @@ -1,9 +1,12 @@ -import { readFile, readFileSync } from "./fs.ts"; +import { readFile, readFileSync, readlink, readlinkSync } from "./fs.ts"; import { test } from "../testing/mod.ts"; import * as path from "../path/mod.ts"; import { assertEquals, assert } from "../testing/asserts.ts"; const testData = path.resolve(path.join("node", "testdata", "hello.txt")); +const testDir = Deno.makeTempDirSync(); +const oldname = testDir + "/oldname"; +const newname = testDir + "/newname"; // Need to convert to promises, otherwise test() won't report error correctly. test(async function readFileSuccess() { @@ -45,3 +48,47 @@ test(function readFileEncodeUtf8Success() { assertEquals(typeof data, "string"); assertEquals(data as string, "hello world"); }); + +// Just for now, until we implement symlink for Windows. +if (Deno.build.os !== "win") { + Deno.symlinkSync(oldname, newname); + test(async function readlinkSuccess() { + 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(async function readlinkEncodeBufferSuccess() { + 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(function readlinkSyncSuccess() { + const data = readlinkSync(newname); + assertEquals(typeof data, "string"); + assertEquals(data as string, oldname); + }); + + test(function readlinkEncodeBufferSuccess() { + const data = readlinkSync(newname, { encoding: "buffer" }); + assert(data instanceof Uint8Array); + assertEquals(new TextDecoder().decode(data as Uint8Array), oldname); + }); +} -- cgit v1.2.3