diff options
author | Ali Hasani <a.hassssani@gmail.com> | 2020-05-19 03:16:02 +0430 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-19 00:46:02 +0200 |
commit | 6072755eadb7342a409f43260e5a17b956703a1c (patch) | |
tree | 35ec9b10eddafdc2b0dacecc439aa8d9f785529a /cli/js | |
parent | 88b24261ba467c20d4ef90224b07c19a71398f0f (diff) |
Implement Deno.symlink() for windows (#5533)
Diffstat (limited to 'cli/js')
-rw-r--r-- | cli/js/lib.deno.unstable.d.ts | 28 | ||||
-rw-r--r-- | cli/js/ops/fs/symlink.ts | 20 | ||||
-rw-r--r-- | cli/js/tests/remove_test.ts | 128 | ||||
-rw-r--r-- | cli/js/tests/symlink_test.ts | 62 |
4 files changed, 84 insertions, 154 deletions
diff --git a/cli/js/lib.deno.unstable.d.ts b/cli/js/lib.deno.unstable.d.ts index d27a3da9e..38260c8ff 100644 --- a/cli/js/lib.deno.unstable.d.ts +++ b/cli/js/lib.deno.unstable.d.ts @@ -41,48 +41,44 @@ declare namespace Deno { * Requires `allow-read` and `allow-write` permissions. */ export function link(oldpath: string, newpath: string): Promise<void>; - /** **UNSTABLE**: `type` argument type may be changed to `"dir" | "file"`. - * - * **UNSTABLE**: needs security review. + export type SymlinkOptions = { + type: "file" | "dir"; + }; + + /** **UNSTABLE**: needs security review. * * Creates `newpath` as a symbolic link to `oldpath`. * - * The type argument can be set to `dir` or `file`. This argument is only + * The options.type parameter can be set to `file` or `dir`. This argument is only * available on Windows and ignored on other platforms. * - * NOTE: This function is not yet implemented on Windows. - * * ```ts * Deno.symlinkSync("old/name", "new/name"); * ``` * - * Requires `allow-read` and `allow-write` permissions. */ + * Requires `allow-write` permission. */ export function symlinkSync( oldpath: string, newpath: string, - type?: string + options?: SymlinkOptions ): void; - /** **UNSTABLE**: `type` argument may be changed to `"dir" | "file"` - * - * **UNSTABLE**: needs security review. + /** **UNSTABLE**: needs security review. * * Creates `newpath` as a symbolic link to `oldpath`. * - * The type argument can be set to `dir` or `file`. This argument is only + * The options.type parameter can be set to `file` or `dir`. This argument is only * available on Windows and ignored on other platforms. * - * NOTE: This function is not yet implemented on Windows. - * * ```ts * await Deno.symlink("old/name", "new/name"); * ``` * - * Requires `allow-read` and `allow-write` permissions. */ + * Requires `allow-write` permission. */ export function symlink( oldpath: string, newpath: string, - type?: string + options?: SymlinkOptions ): Promise<void>; /** **UNSTABLE** */ diff --git a/cli/js/ops/fs/symlink.ts b/cli/js/ops/fs/symlink.ts index 64074ec2d..fde611b55 100644 --- a/cli/js/ops/fs/symlink.ts +++ b/cli/js/ops/fs/symlink.ts @@ -1,26 +1,22 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendSync, sendAsync } from "../dispatch_json.ts"; -import * as util from "../../util.ts"; -import { build } from "../../build.ts"; + +export type symlinkOptions = { + type: "file" | "dir"; +}; export function symlinkSync( oldpath: string, newpath: string, - type?: string + options?: symlinkOptions ): void { - if (build.os === "windows" && type) { - return util.notImplemented(); - } - sendSync("op_symlink", { oldpath, newpath }); + sendSync("op_symlink", { oldpath, newpath, options }); } export async function symlink( oldpath: string, newpath: string, - type?: string + options?: symlinkOptions ): Promise<void> { - if (build.os === "windows" && type) { - return util.notImplemented(); - } - await sendAsync("op_symlink", { oldpath, newpath }); + await sendAsync("op_symlink", { oldpath, newpath, options }); } diff --git a/cli/js/tests/remove_test.ts b/cli/js/tests/remove_test.ts index 8de577838..35e5c821e 100644 --- a/cli/js/tests/remove_test.ts +++ b/cli/js/tests/remove_test.ts @@ -83,27 +83,23 @@ unitTest( { perms: { write: true, read: true } }, function removeSyncDanglingSymlinkSuccess(): void { const danglingSymlinkPath = Deno.makeTempDirSync() + "/dangling_symlink"; - // TODO(#3832): Remove "not Implemented" error checking when symlink creation is implemented for Windows - let errOnWindows; - try { - Deno.symlinkSync("unexistent_file", danglingSymlinkPath); - } catch (err) { - errOnWindows = err; - } if (Deno.build.os === "windows") { - assertEquals(errOnWindows.message, "not implemented"); + Deno.symlinkSync("unexistent_file", danglingSymlinkPath, { + type: "file", + }); } else { - const pathInfo = Deno.lstatSync(danglingSymlinkPath); - assert(pathInfo.isSymlink); - Deno.removeSync(danglingSymlinkPath); - let err; - try { - Deno.lstatSync(danglingSymlinkPath); - } catch (e) { - err = e; - } - assert(err instanceof Deno.errors.NotFound); + Deno.symlinkSync("unexistent_file", danglingSymlinkPath); + } + const pathInfo = Deno.lstatSync(danglingSymlinkPath); + assert(pathInfo.isSymlink); + Deno.removeSync(danglingSymlinkPath); + let err; + try { + Deno.lstatSync(danglingSymlinkPath); + } catch (e) { + err = e; } + assert(err instanceof Deno.errors.NotFound); } ); @@ -116,28 +112,22 @@ unitTest( const filePath = tempDir + "/test.txt"; const validSymlinkPath = tempDir + "/valid_symlink"; Deno.writeFileSync(filePath, data, { mode: 0o666 }); - // TODO(#3832): Remove "not Implemented" error checking when symlink creation is implemented for Windows - let errOnWindows; - try { - Deno.symlinkSync(filePath, validSymlinkPath); - } catch (err) { - errOnWindows = err; - } if (Deno.build.os === "windows") { - assertEquals(errOnWindows.message, "not implemented"); + Deno.symlinkSync(filePath, validSymlinkPath, { type: "file" }); } else { - const symlinkPathInfo = Deno.statSync(validSymlinkPath); - assert(symlinkPathInfo.isFile); - Deno.removeSync(validSymlinkPath); - let err; - try { - Deno.statSync(validSymlinkPath); - } catch (e) { - err = e; - } - Deno.removeSync(filePath); - assert(err instanceof Deno.errors.NotFound); + Deno.symlinkSync(filePath, validSymlinkPath); + } + const symlinkPathInfo = Deno.statSync(validSymlinkPath); + assert(symlinkPathInfo.isFile); + Deno.removeSync(validSymlinkPath); + let err; + try { + Deno.statSync(validSymlinkPath); + } catch (e) { + err = e; } + Deno.removeSync(filePath); + assert(err instanceof Deno.errors.NotFound); } ); @@ -319,27 +309,23 @@ unitTest( { perms: { write: true, read: true } }, async function removeDanglingSymlinkSuccess(): Promise<void> { const danglingSymlinkPath = Deno.makeTempDirSync() + "/dangling_symlink"; - // TODO(#3832): Remove "not Implemented" error checking when symlink creation is implemented for Windows - let errOnWindows; - try { - Deno.symlinkSync("unexistent_file", danglingSymlinkPath); - } catch (e) { - errOnWindows = e; - } if (Deno.build.os === "windows") { - assertEquals(errOnWindows.message, "not implemented"); + Deno.symlinkSync("unexistent_file", danglingSymlinkPath, { + type: "file", + }); } else { - const pathInfo = Deno.lstatSync(danglingSymlinkPath); - assert(pathInfo.isSymlink); - await Deno.remove(danglingSymlinkPath); - let err; - try { - Deno.lstatSync(danglingSymlinkPath); - } catch (e) { - err = e; - } - assert(err instanceof Deno.errors.NotFound); + Deno.symlinkSync("unexistent_file", danglingSymlinkPath); + } + const pathInfo = Deno.lstatSync(danglingSymlinkPath); + assert(pathInfo.isSymlink); + await Deno.remove(danglingSymlinkPath); + let err; + try { + Deno.lstatSync(danglingSymlinkPath); + } catch (e) { + err = e; } + assert(err instanceof Deno.errors.NotFound); } ); @@ -352,28 +338,22 @@ unitTest( const filePath = tempDir + "/test.txt"; const validSymlinkPath = tempDir + "/valid_symlink"; Deno.writeFileSync(filePath, data, { mode: 0o666 }); - // TODO(#3832): Remove "not Implemented" error checking when symlink creation is implemented for Windows - let errOnWindows; - try { - Deno.symlinkSync(filePath, validSymlinkPath); - } catch (e) { - errOnWindows = e; - } if (Deno.build.os === "windows") { - assertEquals(errOnWindows.message, "not implemented"); + Deno.symlinkSync(filePath, validSymlinkPath, { type: "file" }); } else { - const symlinkPathInfo = Deno.statSync(validSymlinkPath); - assert(symlinkPathInfo.isFile); - await Deno.remove(validSymlinkPath); - let err; - try { - Deno.statSync(validSymlinkPath); - } catch (e) { - err = e; - } - Deno.removeSync(filePath); - assert(err instanceof Deno.errors.NotFound); + Deno.symlinkSync(filePath, validSymlinkPath); + } + const symlinkPathInfo = Deno.statSync(validSymlinkPath); + assert(symlinkPathInfo.isFile); + await Deno.remove(validSymlinkPath); + let err; + try { + Deno.statSync(validSymlinkPath); + } catch (e) { + err = e; } + Deno.removeSync(filePath); + assert(err instanceof Deno.errors.NotFound); } ); diff --git a/cli/js/tests/symlink_test.ts b/cli/js/tests/symlink_test.ts index 681ace1db..505a49bab 100644 --- a/cli/js/tests/symlink_test.ts +++ b/cli/js/tests/symlink_test.ts @@ -8,22 +8,12 @@ unitTest( const oldname = testDir + "/oldname"; const newname = testDir + "/newname"; Deno.mkdirSync(oldname); - let errOnWindows; // Just for now, until we implement symlink for Windows. - try { - Deno.symlinkSync(oldname, newname); - } catch (e) { - errOnWindows = e; - } - if (errOnWindows) { - assertEquals(Deno.build.os, "windows"); - assertEquals(errOnWindows.message, "not implemented"); - } else { - const newNameInfoLStat = Deno.lstatSync(newname); - const newNameInfoStat = Deno.statSync(newname); - assert(newNameInfoLStat.isSymlink); - assert(newNameInfoStat.isDirectory); - } + Deno.symlinkSync(oldname, newname); + const newNameInfoLStat = Deno.lstatSync(newname); + const newNameInfoStat = Deno.statSync(newname); + assert(newNameInfoLStat.isSymlink); + assert(newNameInfoStat.isDirectory); } ); @@ -38,28 +28,6 @@ unitTest(function symlinkSyncPerm(): void { assertEquals(err.name, "PermissionDenied"); }); -// Just for now, until we implement symlink for Windows. -// Symlink with type should succeed on other platforms with type ignored -unitTest( - { perms: { write: true } }, - function symlinkSyncNotImplemented(): void { - const testDir = Deno.makeTempDirSync(); - const oldname = testDir + "/oldname"; - const newname = testDir + "/newname"; - let err; - try { - Deno.symlinkSync(oldname, newname, "dir"); - } catch (e) { - err = e; - } - if (err) { - assertEquals(Deno.build.os, "windows"); - // from cli/js/util.ts:notImplemented - assertEquals(err.message, "not implemented"); - } - } -); - unitTest( { perms: { read: true, write: true } }, async function symlinkSuccess(): Promise<void> { @@ -67,20 +35,10 @@ unitTest( const oldname = testDir + "/oldname"; const newname = testDir + "/newname"; Deno.mkdirSync(oldname); - let errOnWindows; - // Just for now, until we implement symlink for Windows. - try { - await Deno.symlink(oldname, newname); - } catch (e) { - errOnWindows = e; - } - if (errOnWindows) { - assertEquals(errOnWindows.message, "not implemented"); - } else { - const newNameInfoLStat = Deno.lstatSync(newname); - const newNameInfoStat = Deno.statSync(newname); - assert(newNameInfoLStat.isSymlink); - assert(newNameInfoStat.isDirectory); - } + await Deno.symlink(oldname, newname); + const newNameInfoLStat = Deno.lstatSync(newname); + const newNameInfoStat = Deno.statSync(newname); + assert(newNameInfoLStat.isSymlink, "NOT SYMLINK"); + assert(newNameInfoStat.isDirectory, "NOT DIRECTORY"); } ); |