| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent cfafe43 commit a54e898
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -966,6 +966,10 @@ try { | |||
| 966 | 966 | <!-- YAML | |
| 967 | 967 | added: v16.7.0 | |
| 968 | 968 | changes: | |
| 969 | + - version: REPLACEME | ||
| 970 | + pr-url: https://github.com/nodejs/node/pull/47084 | ||
| 971 | + description: Accept an additional `mode` option to specify | ||
| 972 | + the copy behavior as the `mode` argument of `fs.copyFile()`. | ||
| 969 | 973 | - version: | |
| 970 | 974 | - v17.6.0 | |
| 971 | 975 | - v16.15.0 | |
@@ -992,6 +996,8 @@ changes: | |||
| 992 | 996 | operation will ignore errors if you set this to false and the destination | |
| 993 | 997 | exists. Use the `errorOnExist` option to change this behavior. | |
| 994 | 998 | **Default:** `true`. | |
| 999 | + * `mode` {integer} modifiers for copy operation. **Default:** `0`. | ||
| 1000 | + See `mode` flag of [`fsPromises.copyFile()`][]. | ||
| 995 | 1001 | * `preserveTimestamps` {boolean} When `true` timestamps from `src` will | |
| 996 | 1002 | be preserved. **Default:** `false`. | |
| 997 | 1003 | * `recursive` {boolean} copy directories recursively **Default:** `false` | |
@@ -2286,6 +2292,10 @@ copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback); | |||
| 2286 | 2292 | <!-- YAML | |
| 2287 | 2293 | added: v16.7.0 | |
| 2288 | 2294 | changes: | |
| 2295 | + - version: REPLACEME | ||
| 2296 | + pr-url: https://github.com/nodejs/node/pull/47084 | ||
| 2297 | + description: Accept an additional `mode` option to specify | ||
| 2298 | + the copy behavior as the `mode` argument of `fs.copyFile()`. | ||
| 2289 | 2299 | - version: v18.0.0 | |
| 2290 | 2300 | pr-url: https://github.com/nodejs/node/pull/41678 | |
| 2291 | 2301 | description: Passing an invalid callback to the `callback` argument | |
@@ -2317,6 +2327,8 @@ changes: | |||
| 2317 | 2327 | operation will ignore errors if you set this to false and the destination | |
| 2318 | 2328 | exists. Use the `errorOnExist` option to change this behavior. | |
| 2319 | 2329 | **Default:** `true`. | |
| 2330 | + * `mode` {integer} modifiers for copy operation. **Default:** `0`. | ||
| 2331 | + See `mode` flag of [`fs.copyFile()`][]. | ||
| 2320 | 2332 | * `preserveTimestamps` {boolean} When `true` timestamps from `src` will | |
| 2321 | 2333 | be preserved. **Default:** `false`. | |
| 2322 | 2334 | * `recursive` {boolean} copy directories recursively **Default:** `false` | |
@@ -5191,6 +5203,10 @@ copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL); | |||
| 5191 | 5203 | <!-- YAML | |
| 5192 | 5204 | added: v16.7.0 | |
| 5193 | 5205 | changes: | |
| 5206 | + - version: REPLACEME | ||
| 5207 | + pr-url: https://github.com/nodejs/node/pull/47084 | ||
| 5208 | + description: Accept an additional `mode` option to specify | ||
| 5209 | + the copy behavior as the `mode` argument of `fs.copyFile()`. | ||
| 5194 | 5210 | - version: | |
| 5195 | 5211 | - v17.6.0 | |
| 5196 | 5212 | - v16.15.0 | |
@@ -5216,6 +5232,8 @@ changes: | |||
| 5216 | 5232 | operation will ignore errors if you set this to false and the destination | |
| 5217 | 5233 | exists. Use the `errorOnExist` option to change this behavior. | |
| 5218 | 5234 | **Default:** `true`. | |
| 5235 | + * `mode` {integer} modifiers for copy operation. **Default:** `0`. | ||
| 5236 | + See `mode` flag of [`fs.copyFileSync()`][]. | ||
| 5219 | 5237 | * `preserveTimestamps` {boolean} When `true` timestamps from `src` will | |
| 5220 | 5238 | be preserved. **Default:** `false`. | |
| 5221 | 5239 | * `recursive` {boolean} copy directories recursively **Default:** `false` | |
@@ -8004,6 +8022,7 @@ the file contents. | |||
| 8004 | 8022 | [`fs.chmod()`]: #fschmodpath-mode-callback | |
| 8005 | 8023 | [`fs.chown()`]: #fschownpath-uid-gid-callback | |
| 8006 | 8024 | [`fs.copyFile()`]: #fscopyfilesrc-dest-mode-callback | |
| 8025 | + [`fs.copyFileSync()`]: #fscopyfilesyncsrc-dest-mode | ||
| 8007 | 8026 | [`fs.createReadStream()`]: #fscreatereadstreampath-options | |
| 8008 | 8027 | [`fs.createWriteStream()`]: #fscreatewritestreampath-options | |
| 8009 | 8028 | [`fs.exists()`]: #fsexistspath-callback | |
@@ -8037,6 +8056,7 @@ the file contents. | |||
| 8037 | 8056 | [`fs.writeFile()`]: #fswritefilefile-data-options-callback | |
| 8038 | 8057 | [`fs.writev()`]: #fswritevfd-buffers-position-callback | |
| 8039 | 8058 | [`fsPromises.access()`]: #fspromisesaccesspath-mode | |
| 8059 | + [`fsPromises.copyFile()`]: #fspromisescopyfilesrc-dest-mode | ||
| 8040 | 8060 | [`fsPromises.open()`]: #fspromisesopenpath-flags-mode | |
| 8041 | 8061 | [`fsPromises.opendir()`]: #fspromisesopendirpath-options | |
| 8042 | 8062 | [`fsPromises.rm()`]: #fspromisesrmpath-options | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -226,7 +226,7 @@ function mayCopyFile(srcStat, src, dest, opts) { | |||
| 226 | 226 | } | |
| 227 | 227 | ||
| 228 | 228 | function copyFile(srcStat, src, dest, opts) { | |
| 229 | - copyFileSync(src, dest); | ||
| 229 | + copyFileSync(src, dest, opts.mode); | ||
| 230 | 230 | if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest); | |
| 231 | 231 | return setDestMode(dest, srcStat.mode); | |
| 232 | 232 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -257,7 +257,7 @@ async function mayCopyFile(srcStat, src, dest, opts) { | |||
| 257 | 257 | } | |
| 258 | 258 | ||
| 259 | 259 | async function _copyFile(srcStat, src, dest, opts) { | |
| 260 | - await copyFile(src, dest); | ||
| 260 | + await copyFile(src, dest, opts.mode); | ||
| 261 | 261 | if (opts.preserveTimestamps) { | |
| 262 | 262 | return handleTimestampsAndMode(srcStat.mode, src, dest); | |
| 263 | 263 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -787,6 +787,7 @@ const validateCpOptions = hideStackFrames((options) => { | |||
| 787 | 787 | validateBoolean(options.preserveTimestamps, 'options.preserveTimestamps'); | |
| 788 | 788 | validateBoolean(options.recursive, 'options.recursive'); | |
| 789 | 789 | validateBoolean(options.verbatimSymlinks, 'options.verbatimSymlinks'); | |
| 790 | + options.mode = getValidMode(options.mode, 'copyFile'); | ||
| 790 | 791 | if (options.dereference === true && options.verbatimSymlinks === true) { | |
| 791 | 792 | throw new ERR_INCOMPATIBLE_OPTION_PAIR('dereference', 'verbatimSymlinks'); | |
| 792 | 793 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,6 +38,30 @@ function nextdir() { | |||
| 38 | 38 | assertDirEquivalent(src, dest); | |
| 39 | 39 | } | |
| 40 | 40 | ||
| 41 | + // It copies a nested folder structure with mode flags. | ||
| 42 | + // This test is based on fs.promises.copyFile() with `COPYFILE_FICLONE_FORCE`. | ||
| 43 | + (() => { | ||
| 44 | + const src = './test/fixtures/copy/kitchen-sink'; | ||
| 45 | + const dest = nextdir(); | ||
| 46 | + try { | ||
| 47 | + cpSync(src, dest, mustNotMutateObjectDeep({ | ||
| 48 | + recursive: true, | ||
| 49 | + mode: fs.constants.COPYFILE_FICLONE_FORCE, | ||
| 50 | + })); | ||
| 51 | + } catch (err) { | ||
| 52 | + // If the platform does not support `COPYFILE_FICLONE_FORCE` operation, | ||
| 53 | + // it should enter this path. | ||
| 54 | + assert.strictEqual(err.syscall, 'copyfile'); | ||
| 55 | + assert(err.code === 'ENOTSUP' || err.code === 'ENOTTY' || | ||
| 56 | + err.code === 'ENOSYS' || err.code === 'EXDEV'); | ||
| 57 | + return; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + // If the platform support `COPYFILE_FICLONE_FORCE` operation, | ||
| 61 | + // it should reach to here. | ||
| 62 | + assertDirEquivalent(src, dest); | ||
| 63 | + })(); | ||
| 64 | + | ||
| 41 | 65 | // It does not throw errors when directory is copied over and force is false. | |
| 42 | 66 | { | |
| 43 | 67 | const src = nextdir(); | |
@@ -107,6 +131,14 @@ function nextdir() { | |||
| 107 | 131 | }); | |
| 108 | 132 | } | |
| 109 | 133 | ||
| 134 | + // It rejects if options.mode is invalid. | ||
| 135 | + { | ||
| 136 | + assert.throws( | ||
| 137 | + () => cpSync('a', 'b', { mode: -1 }), | ||
| 138 | + { code: 'ERR_OUT_OF_RANGE' } | ||
| 139 | + ); | ||
| 140 | + } | ||
| 141 | + | ||
| 110 | 142 | ||
| 111 | 143 | // It throws an error when both dereference and verbatimSymlinks are enabled. | |
| 112 | 144 | { | |
@@ -425,6 +457,31 @@ if (!isWindows) { | |||
| 425 | 457 | })); | |
| 426 | 458 | } | |
| 427 | 459 | ||
| 460 | + // It copies a nested folder structure with mode flags. | ||
| 461 | + // This test is based on fs.promises.copyFile() with `COPYFILE_FICLONE_FORCE`. | ||
| 462 | + { | ||
| 463 | + const src = './test/fixtures/copy/kitchen-sink'; | ||
| 464 | + const dest = nextdir(); | ||
| 465 | + cp(src, dest, mustNotMutateObjectDeep({ | ||
| 466 | + recursive: true, | ||
| 467 | + mode: fs.constants.COPYFILE_FICLONE_FORCE, | ||
| 468 | + }), mustCall((err) => { | ||
| 469 | + if (!err) { | ||
| 470 | + // If the platform support `COPYFILE_FICLONE_FORCE` operation, | ||
| 471 | + // it should reach to here. | ||
| 472 | + assert.strictEqual(err, null); | ||
| 473 | + assertDirEquivalent(src, dest); | ||
| 474 | + return; | ||
| 475 | + } | ||
| 476 | + | ||
| 477 | + // If the platform does not support `COPYFILE_FICLONE_FORCE` operation, | ||
| 478 | + // it should enter this path. | ||
| 479 | + assert.strictEqual(err.syscall, 'copyfile'); | ||
| 480 | + assert(err.code === 'ENOTSUP' || err.code === 'ENOTTY' || | ||
| 481 | + err.code === 'ENOSYS' || err.code === 'EXDEV'); | ||
| 482 | + })); | ||
| 483 | + } | ||
| 484 | + | ||
| 428 | 485 | // It does not throw errors when directory is copied over and force is false. | |
| 429 | 486 | { | |
| 430 | 487 | const src = nextdir(); | |
@@ -799,6 +856,14 @@ if (!isWindows) { | |||
| 799 | 856 | ); | |
| 800 | 857 | } | |
| 801 | 858 | ||
| 859 | + // It throws if options is not object. | ||
| 860 | + { | ||
| 861 | + assert.throws( | ||
| 862 | + () => cp('a', 'b', { mode: -1 }, () => {}), | ||
| 863 | + { code: 'ERR_OUT_OF_RANGE' } | ||
| 864 | + ); | ||
| 865 | + } | ||
| 866 | + | ||
| 802 | 867 | // Promises implementation of copy. | |
| 803 | 868 | ||
| 804 | 869 | // It copies a nested folder structure with files and folders. | |
@@ -810,6 +875,35 @@ if (!isWindows) { | |||
| 810 | 875 | assertDirEquivalent(src, dest); | |
| 811 | 876 | } | |
| 812 | 877 | ||
| 878 | + // It copies a nested folder structure with mode flags. | ||
| 879 | + // This test is based on fs.promises.copyFile() with `COPYFILE_FICLONE_FORCE`. | ||
| 880 | + { | ||
| 881 | + const src = './test/fixtures/copy/kitchen-sink'; | ||
| 882 | + const dest = nextdir(); | ||
| 883 | + let p = null; | ||
| 884 | + let successFiClone = false; | ||
| 885 | + try { | ||
| 886 | + p = await fs.promises.cp(src, dest, mustNotMutateObjectDeep({ | ||
| 887 | + recursive: true, | ||
| 888 | + mode: fs.constants.COPYFILE_FICLONE_FORCE, | ||
| 889 | + })); | ||
| 890 | + successFiClone = true; | ||
| 891 | + } catch (err) { | ||
| 892 | + // If the platform does not support `COPYFILE_FICLONE_FORCE` operation, | ||
| 893 | + // it should enter this path. | ||
| 894 | + assert.strictEqual(err.syscall, 'copyfile'); | ||
| 895 | + assert(err.code === 'ENOTSUP' || err.code === 'ENOTTY' || | ||
| 896 | + err.code === 'ENOSYS' || err.code === 'EXDEV'); | ||
| 897 | + } | ||
| 898 | + | ||
| 899 | + if (successFiClone) { | ||
| 900 | + // If the platform support `COPYFILE_FICLONE_FORCE` operation, | ||
| 901 | + // it should reach to here. | ||
| 902 | + assert.strictEqual(p, undefined); | ||
| 903 | + assertDirEquivalent(src, dest); | ||
| 904 | + } | ||
| 905 | + } | ||
| 906 | + | ||
| 813 | 907 | // It accepts file URL as src and dest. | |
| 814 | 908 | { | |
| 815 | 909 | const src = './test/fixtures/copy/kitchen-sink'; | |
@@ -847,6 +941,16 @@ if (!isWindows) { | |||
| 847 | 941 | ); | |
| 848 | 942 | } | |
| 849 | 943 | ||
| 944 | + // It rejects if options.mode is invalid. | ||
| 945 | + { | ||
| 946 | + await assert.rejects( | ||
| 947 | + fs.promises.cp('a', 'b', { | ||
| 948 | + mode: -1, | ||
| 949 | + }), | ||
| 950 | + { code: 'ERR_OUT_OF_RANGE' } | ||
| 951 | + ); | ||
| 952 | + } | ||
| 953 | + | ||
| 850 | 954 | function assertDirEquivalent(dir1, dir2) { | |
| 851 | 955 | const dir1Entries = []; | |
| 852 | 956 | collectEntries(dir1, dir1Entries); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments