| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 6b88595 commit 214d176
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -876,6 +876,11 @@ try { | |||
| 876 | 876 | ||
| 877 | 877 | <!-- YAML | |
| 878 | 878 | added: v16.7.0 | |
| 879 | + changes: | ||
| 880 | + - version: REPLACEME | ||
| 881 | + pr-url: https://github.com/nodejs/node/pull/41819 | ||
| 882 | + description: Accepts an additional `verbatimSymlinks` option to specify | ||
| 883 | + whether to perform path resolution for symlinks. | ||
| 879 | 884 | --> | |
| 880 | 885 | ||
| 881 | 886 | > Stability: 1 - Experimental | |
@@ -896,6 +901,8 @@ added: v16.7.0 | |||
| 896 | 901 | * `preserveTimestamps` {boolean} When `true` timestamps from `src` will | |
| 897 | 902 | be preserved. **Default:** `false`. | |
| 898 | 903 | * `recursive` {boolean} copy directories recursively **Default:** `false` | |
| 904 | + * `verbatimSymlinks` {boolean} When `true`, path resolution for symlinks will | ||
| 905 | + be skipped. **Default:** `false` | ||
| 899 | 906 | * Returns: {Promise} Fulfills with `undefined` upon success. | |
| 900 | 907 | ||
| 901 | 908 | Asynchronously copies the entire directory structure from `src` to `dest`, | |
@@ -2063,6 +2070,11 @@ copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback); | |||
| 2063 | 2070 | ||
| 2064 | 2071 | <!-- YAML | |
| 2065 | 2072 | added: v16.7.0 | |
| 2073 | + changes: | ||
| 2074 | + - version: REPLACEME | ||
| 2075 | + pr-url: https://github.com/nodejs/node/pull/41819 | ||
| 2076 | + description: Accepts an additional `verbatimSymlinks` option to specify | ||
| 2077 | + whether to perform path resolution for symlinks. | ||
| 2066 | 2078 | --> | |
| 2067 | 2079 | ||
| 2068 | 2080 | > Stability: 1 - Experimental | |
@@ -2083,6 +2095,8 @@ added: v16.7.0 | |||
| 2083 | 2095 | * `preserveTimestamps` {boolean} When `true` timestamps from `src` will | |
| 2084 | 2096 | be preserved. **Default:** `false`. | |
| 2085 | 2097 | * `recursive` {boolean} copy directories recursively **Default:** `false` | |
| 2098 | + * `verbatimSymlinks` {boolean} When `true`, path resolution for symlinks will | ||
| 2099 | + be skipped. **Default:** `false` | ||
| 2086 | 2100 | * `callback` {Function} | |
| 2087 | 2101 | ||
| 2088 | 2102 | Asynchronously copies the entire directory structure from `src` to `dest`, | |
@@ -4646,6 +4660,11 @@ copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL); | |||
| 4646 | 4660 | ||
| 4647 | 4661 | <!-- YAML | |
| 4648 | 4662 | added: v16.7.0 | |
| 4663 | + changes: | ||
| 4664 | + - version: REPLACEME | ||
| 4665 | + pr-url: https://github.com/nodejs/node/pull/41819 | ||
| 4666 | + description: Accepts an additional `verbatimSymlinks` option to specify | ||
| 4667 | + whether to perform path resolution for symlinks. | ||
| 4649 | 4668 | --> | |
| 4650 | 4669 | ||
| 4651 | 4670 | > Stability: 1 - Experimental | |
@@ -4665,6 +4684,8 @@ added: v16.7.0 | |||
| 4665 | 4684 | * `preserveTimestamps` {boolean} When `true` timestamps from `src` will | |
| 4666 | 4685 | be preserved. **Default:** `false`. | |
| 4667 | 4686 | * `recursive` {boolean} copy directories recursively **Default:** `false` | |
| 4687 | + * `verbatimSymlinks` {boolean} When `true`, path resolution for symlinks will | ||
| 4688 | + be skipped. **Default:** `false` | ||
| 4668 | 4689 | ||
| 4669 | 4690 | Synchronously copies the entire directory structure from `src` to `dest`, | |
| 4670 | 4691 | including subdirectories and files. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -182,7 +182,7 @@ function getStats(destStat, src, dest, opts) { | |||
| 182 | 182 | srcStat.isBlockDevice()) { | |
| 183 | 183 | return onFile(srcStat, destStat, src, dest, opts); | |
| 184 | 184 | } else if (srcStat.isSymbolicLink()) { | |
| 185 | - return onLink(destStat, src, dest); | ||
| 185 | + return onLink(destStat, src, dest, opts); | ||
| 186 | 186 | } else if (srcStat.isSocket()) { | |
| 187 | 187 | throw new ERR_FS_CP_SOCKET({ | |
| 188 | 188 | message: `cannot copy a socket file: ${dest}`, | |
@@ -293,9 +293,9 @@ function copyDir(src, dest, opts) { | |||
| 293 | 293 | } | |
| 294 | 294 | } | |
| 295 | 295 | ||
| 296 | - function onLink(destStat, src, dest) { | ||
| 296 | + function onLink(destStat, src, dest, opts) { | ||
| 297 | 297 | let resolvedSrc = readlinkSync(src); | |
| 298 | - if (!isAbsolute(resolvedSrc)) { | ||
| 298 | + if (!opts.verbatimSymlinks && !isAbsolute(resolvedSrc)) { | ||
| 299 | 299 | resolvedSrc = resolve(dirname(src), resolvedSrc); | |
| 300 | 300 | } | |
| 301 | 301 | if (!destStat) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -222,7 +222,7 @@ async function getStatsForCopy(destStat, src, dest, opts) { | |||
| 222 | 222 | srcStat.isBlockDevice()) { | |
| 223 | 223 | return onFile(srcStat, destStat, src, dest, opts); | |
| 224 | 224 | } else if (srcStat.isSymbolicLink()) { | |
| 225 | - return onLink(destStat, src, dest); | ||
| 225 | + return onLink(destStat, src, dest, opts); | ||
| 226 | 226 | } else if (srcStat.isSocket()) { | |
| 227 | 227 | throw new ERR_FS_CP_SOCKET({ | |
| 228 | 228 | message: `cannot copy a socket file: ${dest}`, | |
@@ -335,9 +335,9 @@ async function copyDir(src, dest, opts) { | |||
| 335 | 335 | } | |
| 336 | 336 | } | |
| 337 | 337 | ||
| 338 | - async function onLink(destStat, src, dest) { | ||
| 338 | + async function onLink(destStat, src, dest, opts) { | ||
| 339 | 339 | let resolvedSrc = await readlink(src); | |
| 340 | - if (!isAbsolute(resolvedSrc)) { | ||
| 340 | + if (!opts.verbatimSymlinks && !isAbsolute(resolvedSrc)) { | ||
| 341 | 341 | resolvedSrc = resolve(dirname(src), resolvedSrc); | |
| 342 | 342 | } | |
| 343 | 343 | if (!destStat) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,6 +29,7 @@ const { | |||
| 29 | 29 | codes: { | |
| 30 | 30 | ERR_FS_EISDIR, | |
| 31 | 31 | ERR_FS_INVALID_SYMLINK_TYPE, | |
| 32 | + ERR_INCOMPATIBLE_OPTION_PAIR, | ||
| 32 | 33 | ERR_INVALID_ARG_TYPE, | |
| 33 | 34 | ERR_INVALID_ARG_VALUE, | |
| 34 | 35 | ERR_OUT_OF_RANGE | |
@@ -724,6 +725,7 @@ const defaultCpOptions = { | |||
| 724 | 725 | force: true, | |
| 725 | 726 | preserveTimestamps: false, | |
| 726 | 727 | recursive: false, | |
| 728 | + verbatimSymlinks: false, | ||
| 727 | 729 | }; | |
| 728 | 730 | ||
| 729 | 731 | const defaultRmOptions = { | |
@@ -749,6 +751,10 @@ const validateCpOptions = hideStackFrames((options) => { | |||
| 749 | 751 | validateBoolean(options.force, 'options.force'); | |
| 750 | 752 | validateBoolean(options.preserveTimestamps, 'options.preserveTimestamps'); | |
| 751 | 753 | validateBoolean(options.recursive, 'options.recursive'); | |
| 754 | + validateBoolean(options.verbatimSymlinks, 'options.verbatimSymlinks'); | ||
| 755 | + if (options.dereference === true && options.verbatimSymlinks === true) { | ||
| 756 | + throw new ERR_INCOMPATIBLE_OPTION_PAIR('dereference', 'verbatimSymlinks'); | ||
| 757 | + } | ||
| 752 | 758 | if (options.filter !== undefined) { | |
| 753 | 759 | validateFunction(options.filter, 'options.filter'); | |
| 754 | 760 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -95,6 +95,77 @@ function nextdir() { | |||
| 95 | 95 | } | |
| 96 | 96 | ||
| 97 | 97 | ||
| 98 | + // It throws error when verbatimSymlinks is not a boolean. | ||
| 99 | + { | ||
| 100 | + const src = './test/fixtures/copy/kitchen-sink'; | ||
| 101 | + [1, [], {}, null, 1n, undefined, null, Symbol(), '', () => {}] | ||
| 102 | + .forEach((verbatimSymlinks) => { | ||
| 103 | + assert.throws( | ||
| 104 | + () => cpSync(src, src, { verbatimSymlinks }), | ||
| 105 | + { code: 'ERR_INVALID_ARG_TYPE' } | ||
| 106 | + ); | ||
| 107 | + }); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + | ||
| 111 | + // It throws an error when both dereference and verbatimSymlinks are enabled. | ||
| 112 | + { | ||
| 113 | + const src = './test/fixtures/copy/kitchen-sink'; | ||
| 114 | + assert.throws( | ||
| 115 | + () => cpSync(src, src, { dereference: true, verbatimSymlinks: true }), | ||
| 116 | + { code: 'ERR_INCOMPATIBLE_OPTION_PAIR' } | ||
| 117 | + ); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + | ||
| 121 | + // It resolves relative symlinks to their absolute path by default. | ||
| 122 | + { | ||
| 123 | + const src = nextdir(); | ||
| 124 | + mkdirSync(src, { recursive: true }); | ||
| 125 | + writeFileSync(join(src, 'foo.js'), 'foo', 'utf8'); | ||
| 126 | + symlinkSync('foo.js', join(src, 'bar.js')); | ||
| 127 | + | ||
| 128 | + const dest = nextdir(); | ||
| 129 | + mkdirSync(dest, { recursive: true }); | ||
| 130 | + | ||
| 131 | + cpSync(src, dest, { recursive: true }); | ||
| 132 | + const link = readlinkSync(join(dest, 'bar.js')); | ||
| 133 | + assert.strictEqual(link, join(src, 'foo.js')); | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + | ||
| 137 | + // It resolves relative symlinks when verbatimSymlinks is false. | ||
| 138 | + { | ||
| 139 | + const src = nextdir(); | ||
| 140 | + mkdirSync(src, { recursive: true }); | ||
| 141 | + writeFileSync(join(src, 'foo.js'), 'foo', 'utf8'); | ||
| 142 | + symlinkSync('foo.js', join(src, 'bar.js')); | ||
| 143 | + | ||
| 144 | + const dest = nextdir(); | ||
| 145 | + mkdirSync(dest, { recursive: true }); | ||
| 146 | + | ||
| 147 | + cpSync(src, dest, { recursive: true, verbatimSymlinks: false }); | ||
| 148 | + const link = readlinkSync(join(dest, 'bar.js')); | ||
| 149 | + assert.strictEqual(link, join(src, 'foo.js')); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + | ||
| 153 | + // It does not resolve relative symlinks when verbatimSymlinks is true. | ||
| 154 | + { | ||
| 155 | + const src = nextdir(); | ||
| 156 | + mkdirSync(src, { recursive: true }); | ||
| 157 | + writeFileSync(join(src, 'foo.js'), 'foo', 'utf8'); | ||
| 158 | + symlinkSync('foo.js', join(src, 'bar.js')); | ||
| 159 | + | ||
| 160 | + const dest = nextdir(); | ||
| 161 | + mkdirSync(dest, { recursive: true }); | ||
| 162 | + | ||
| 163 | + cpSync(src, dest, { recursive: true, verbatimSymlinks: true }); | ||
| 164 | + const link = readlinkSync(join(dest, 'bar.js')); | ||
| 165 | + assert.strictEqual(link, 'foo.js'); | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + | ||
| 98 | 169 | // It throws error when src and dest are identical. | |
| 99 | 170 | { | |
| 100 | 171 | const src = './test/fixtures/copy/kitchen-sink'; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments