From e0b4988bb4a3c864914e73335c3c3074c0b399d9 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sun, 20 Nov 2022 18:45:38 +0200 Subject: [PATCH] feat: overwrite option --- LICENSE | 2 +- README.md | 6 +++++- src/index.ts | 9 ++++++--- test/index.ts | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/LICENSE b/LICENSE index fd1be1d..9e504a2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016-2021 Zoltan Kochan +Copyright (c) 2016-2022 Zoltan Kochan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index b77997d..226638b 100644 --- a/README.md +++ b/README.md @@ -49,10 +49,14 @@ symlinkDir('src', 'node_modules/src') ## API -### `symlinkDir(src, dest): Promise<{ reused: boolean, warn?: string }>` +### `symlinkDir(src, dest, opts?): Promise<{ reused: boolean, warn?: string }>` Creates a symlink in `dest` that points to `src`. +Options: + +* `overwrite` - *boolean* - is `true` by default. When `false`, existing files at dest are not overwritten. + Result: * `reused` - *boolean* - is `true` if the symlink already existed pointing to the `src`. diff --git a/src/index.ts b/src/index.ts index 9a1f6d2..43a2d72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,7 +19,7 @@ function resolveSrcOnNonWin (src: string, dest: string) { return path.relative(path.dirname(dest), src) } -function symlinkDir (src: string, dest: string): Promise<{ reused: Boolean, warn?: string }> { +function symlinkDir (src: string, dest: string, opts?: { overwrite?: boolean }): Promise<{ reused: Boolean, warn?: string }> { dest = betterPathResolve(dest) src = betterPathResolve(src) @@ -27,14 +27,14 @@ function symlinkDir (src: string, dest: string): Promise<{ reused: Boolean, warn src = resolveSrc(src, dest) - return forceSymlink(src, dest) + return forceSymlink(src, dest, opts) } /** * Creates a symlink. Re-link if a symlink already exists at the supplied * srcPath. API compatible with [`fs#symlink`](https://nodejs.org/api/fs.html#fs_fs_symlink_srcpath_dstpath_type_callback). */ -async function forceSymlink (src: string, dest: string): Promise<{ reused: Boolean, warn?: string }> { +async function forceSymlink (src: string, dest: string, opts?: { overwrite?: boolean }): Promise<{ reused: Boolean, warn?: string }> { try { await fs.symlink(src, dest, symlinkType) return { reused: false } @@ -53,6 +53,9 @@ async function forceSymlink (src: string, dest: string): Promise<{ reused: Boole return { reused: false } case 'EEXIST': case 'EISDIR': + if (opts?.overwrite === false) { + throw err + } // If the target file already exists then we proceed. // Additional checks are done below. break diff --git a/test/index.ts b/test/index.ts index ab5daa4..764a05b 100644 --- a/test/index.ts +++ b/test/index.ts @@ -21,6 +21,25 @@ test('rename target folder if it exists', async (t) => { t.end() }) +test('do not rename target folder if overwrite is set to false', async (t) => { + const temp = tempy.directory() + t.comment(`testing in ${temp}`) + process.chdir(temp) + + await fs.mkdir('src') + await fs.mkdir('dest') + + let err!: Error + try { + await symlink('src', 'dest', { overwrite: false }) + } catch (_err) { + err = _err + } + + t.equals(err['code'], 'EEXIST', 'dest folder not ignored') + t.end() +}) + test('rename target file if it exists', async (t) => { const temp = tempy.directory() t.comment(`testing in ${temp}`) @@ -86,3 +105,19 @@ test('concurrently creating the same symlink twice', async (t) => { t.end() }) + +test('reusing the existing symlink if it already points to the needed location', async (t) => { + const temp = tempy.directory() + t.comment(`testing in ${temp}`) + process.chdir(temp) + + await writeJsonFile('src/file.json', { ok: true }) + + await symlink('src', 'dest/subdir') + const { reused } = await symlink('src', 'dest/subdir') + + t.equal(reused, true) + t.deepEqual(await import(path.resolve('dest/subdir/file.json')), { ok: true }) + + t.end() +})