Skip to content

Commit 0ddd75b

Browse files
committed
fs: runtime deprecate rmdir recursive option
PR-URL: #37302 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Darshan Sen <[email protected]> Reviewed-By: Anto Aravinth <[email protected]>
1 parent 9fab73c commit 0ddd75b

10 files changed

+53
-42
lines changed

Diff for: doc/api/deprecations.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -2671,19 +2671,25 @@ The [`crypto.Certificate()` constructor][] is deprecated. Use
26712671
### DEP0147: `fs.rmdir(path, { recursive: true })`
26722672
<!-- YAML
26732673
changes:
2674+
- version: REPLACEME
2675+
pr-url: https://github.com/nodejs/node/pull/37302
2676+
description: Runtime deprecation.
26742677
- version: v15.0.0
26752678
pr-url: https://github.com/nodejs/node/pull/35562
2676-
description: Runtime deprecation.
2679+
description: Runtime deprecation for permissive behavior.
26772680
- version: v14.14.0
26782681
pr-url: https://github.com/nodejs/node/pull/35579
26792682
description: Documentation-only deprecation.
26802683
-->
26812684

26822685
Type: Runtime
26832686

2684-
In future versions of Node.js, `fs.rmdir(path, { recursive: true })` will throw
2685-
if `path` does not exist or is a file.
2686-
Use `fs.rm(path, { recursive: true, force: true })` instead.
2687+
In future versions of Node.js, `recursive` option will be ignored for
2688+
`fs.rmdir`, `fs.rmdirSync`, and `fs.promises.rmdir`.
2689+
2690+
Use `fs.rm(path, { recursive: true, force: true })`,
2691+
`fs.rmSync(path, { recursive: true, force: true })` or
2692+
`fs.promises.rm(path, { recursive: true, force: true })` instead.
26872693

26882694
### DEP0148: Folder mappings in `"exports"` (trailing `"/"`)
26892695
<!-- YAML

Diff for: doc/api/fs.md

+21-12
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,10 @@ Renames `oldPath` to `newPath`.
10481048
<!-- YAML
10491049
added: v10.0.0
10501050
changes:
1051+
- version: REPLACEME
1052+
pr-url: https://github.com/nodejs/node/pull/37302
1053+
description: The `recursive` option is deprecated, using it triggers a
1054+
deprecation warning.
10511055
- version:
10521056
- v13.3.0
10531057
- v12.16.0
@@ -1072,7 +1076,7 @@ changes:
10721076
option is not `true`. **Default:** `0`.
10731077
* `recursive` {boolean} If `true`, perform a recursive directory removal. In
10741078
recursive mode, errors are not reported if `path` does not exist, and
1075-
operations are retried on failure. **Default:** `false`.
1079+
operations are retried on failure. **Default:** `false`. **Deprecated**.
10761080
* `retryDelay` {integer} The amount of time in milliseconds to wait between
10771081
retries. This option is ignored if the `recursive` option is not `true`.
10781082
**Default:** `100`.
@@ -1086,9 +1090,8 @@ error on POSIX.
10861090
10871091
Setting `recursive` to `true` results in behavior similar to the Unix command
10881092
`rm -rf`: an error will not be raised for paths that do not exist, and paths
1089-
that represent files will be deleted. The permissive behavior of the
1090-
`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in
1091-
the future.
1093+
that represent files will be deleted. The `recursive` option is deprecated,
1094+
`ENOTDIR` and `ENOENT` will be thrown in the future.
10921095
10931096
### `fsPromises.rm(path[, options])`
10941097
<!-- YAML
@@ -3135,6 +3138,10 @@ rename('oldFile.txt', 'newFile.txt', (err) => {
31353138
<!-- YAML
31363139
added: v0.0.2
31373140
changes:
3141+
- version: REPLACEME
3142+
pr-url: https://github.com/nodejs/node/pull/37302
3143+
description: The `recursive` option is deprecated, using it triggers a
3144+
deprecation warning.
31383145
- version:
31393146
- v13.3.0
31403147
- v12.16.0
@@ -3171,7 +3178,7 @@ changes:
31713178
option is not `true`. **Default:** `0`.
31723179
* `recursive` {boolean} If `true`, perform a recursive directory removal. In
31733180
recursive mode, errors are not reported if `path` does not exist, and
3174-
operations are retried on failure. **Default:** `false`.
3181+
operations are retried on failure. **Default:** `false`. **Deprecated**.
31753182
* `retryDelay` {integer} The amount of time in milliseconds to wait between
31763183
retries. This option is ignored if the `recursive` option is not `true`.
31773184
**Default:** `100`.
@@ -3186,9 +3193,8 @@ Windows and an `ENOTDIR` error on POSIX.
31863193

31873194
Setting `recursive` to `true` results in behavior similar to the Unix command
31883195
`rm -rf`: an error will not be raised for paths that do not exist, and paths
3189-
that represent files will be deleted. The permissive behavior of the
3190-
`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in
3191-
the future.
3196+
that represent files will be deleted. The `recursive` option is deprecated,
3197+
`ENOTDIR` and `ENOENT` will be thrown in the future.
31923198

31933199
### `fs.rm(path[, options], callback)`
31943200
<!-- YAML
@@ -4755,6 +4761,10 @@ See the POSIX rename(2) documentation for more details.
47554761
<!-- YAML
47564762
added: v0.1.21
47574763
changes:
4764+
- version: REPLACEME
4765+
pr-url: https://github.com/nodejs/node/pull/37302
4766+
description: The `recursive` option is deprecated, using it triggers a
4767+
deprecation warning.
47584768
- version:
47594769
- v13.3.0
47604770
- v12.16.0
@@ -4783,7 +4793,7 @@ changes:
47834793
option is not `true`. **Default:** `0`.
47844794
* `recursive` {boolean} If `true`, perform a recursive directory removal. In
47854795
recursive mode, errors are not reported if `path` does not exist, and
4786-
operations are retried on failure. **Default:** `false`.
4796+
operations are retried on failure. **Default:** `false`. **Deprecated**.
47874797
* `retryDelay` {integer} The amount of time in milliseconds to wait between
47884798
retries. This option is ignored if the `recursive` option is not `true`.
47894799
**Default:** `100`.
@@ -4795,9 +4805,8 @@ on Windows and an `ENOTDIR` error on POSIX.
47954805
47964806
Setting `recursive` to `true` results in behavior similar to the Unix command
47974807
`rm -rf`: an error will not be raised for paths that do not exist, and paths
4798-
that represent files will be deleted. The permissive behavior of the
4799-
`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in
4800-
the future.
4808+
that represent files will be deleted. The `recursive` option is deprecated,
4809+
`ENOTDIR` and `ENOENT` will be thrown in the future.
48014810
48024811
### `fs.rmSync(path[, options])`
48034812
<!-- YAML

Diff for: lib/fs.js

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ const internalUtil = require('internal/util');
9191
const {
9292
copyObject,
9393
Dirent,
94+
emitRecursiveRmdirWarning,
9495
getDirents,
9596
getOptions,
9697
getValidatedFd,
@@ -893,6 +894,7 @@ function rmdir(path, options, callback) {
893894
path = pathModule.toNamespacedPath(getValidatedPath(path));
894895

895896
if (options?.recursive) {
897+
emitRecursiveRmdirWarning();
896898
validateRmOptions(
897899
path,
898900
{ ...options, force: true },
@@ -917,6 +919,7 @@ function rmdirSync(path, options) {
917919
path = getValidatedPath(path);
918920

919921
if (options?.recursive) {
922+
emitRecursiveRmdirWarning();
920923
options = validateRmOptionsSync(path, { ...options, force: true }, true);
921924
lazyLoadRimraf();
922925
return rimrafSync(pathModule.toNamespacedPath(path), options);

Diff for: lib/internal/fs/promises.js

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const { isArrayBufferView } = require('internal/util/types');
4646
const { rimrafPromises } = require('internal/fs/rimraf');
4747
const {
4848
copyObject,
49+
emitRecursiveRmdirWarning,
4950
getDirents,
5051
getOptions,
5152
getStatsFromBinding,
@@ -503,6 +504,7 @@ async function rmdir(path, options) {
503504
options = validateRmdirOptions(options);
504505

505506
if (options.recursive) {
507+
emitRecursiveRmdirWarning();
506508
return rimrafPromises(path, options);
507509
}
508510

Diff for: lib/internal/fs/utils.js

+6-18
Original file line numberDiff line numberDiff line change
@@ -705,18 +705,11 @@ const validateRmOptions = hideStackFrames((path, options, warn, callback) => {
705705
lazyLoadFs().stat(path, (err, stats) => {
706706
if (err) {
707707
if (options.force && err.code === 'ENOENT') {
708-
if (warn) {
709-
emitPermissiveRmdirWarning();
710-
}
711708
return callback(null, options);
712709
}
713710
return callback(err, options);
714711
}
715712

716-
if (warn && !stats.isDirectory()) {
717-
emitPermissiveRmdirWarning();
718-
}
719-
720713
if (stats.isDirectory() && !options.recursive) {
721714
return callback(new ERR_FS_EISDIR({
722715
code: 'EISDIR',
@@ -738,10 +731,6 @@ const validateRmOptionsSync = hideStackFrames((path, options, warn) => {
738731
const isDirectory = lazyLoadFs()
739732
.statSync(path, { throwIfNoEntry: !options.force })?.isDirectory();
740733

741-
if (warn && !isDirectory) {
742-
emitPermissiveRmdirWarning();
743-
}
744-
745734
if (isDirectory && !options.recursive) {
746735
throw new ERR_FS_EISDIR({
747736
code: 'EISDIR',
@@ -756,18 +745,16 @@ const validateRmOptionsSync = hideStackFrames((path, options, warn) => {
756745
return options;
757746
});
758747

759-
let permissiveRmdirWarned = false;
760-
761-
function emitPermissiveRmdirWarning() {
762-
if (!permissiveRmdirWarned) {
748+
let recursiveRmdirWarned = process.noDeprecation;
749+
function emitRecursiveRmdirWarning() {
750+
if (!recursiveRmdirWarned) {
763751
process.emitWarning(
764752
'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' +
765-
'will throw if path does not exist or is a file. Use fs.rm(path, ' +
766-
'{ recursive: true, force: true }) instead',
753+
'will be removed. Use fs.rm(path, { recursive: true }) instead',
767754
'DeprecationWarning',
768755
'DEP0147'
769756
);
770-
permissiveRmdirWarned = true;
757+
recursiveRmdirWarned = true;
771758
}
772759
}
773760

@@ -852,6 +839,7 @@ module.exports = {
852839
BigIntStats, // for testing
853840
copyObject,
854841
Dirent,
842+
emitRecursiveRmdirWarning,
855843
getDirent,
856844
getDirents,
857845
getOptions,

Diff for: test/parallel/test-fs-rmdir-recursive-sync-warns-not-found.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ tmpdir.refresh();
1111
common.expectWarning(
1212
'DeprecationWarning',
1313
'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' +
14-
'will throw if path does not exist or is a file. Use fs.rm(path, ' +
15-
'{ recursive: true, force: true }) instead',
14+
'will be removed. Use fs.rm(path, { recursive: true }) instead',
1615
'DEP0147'
1716
);
1817
fs.rmdirSync(path.join(tmpdir.path, 'noexist.txt'), { recursive: true });

Diff for: test/parallel/test-fs-rmdir-recursive-sync-warns-on-file.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ tmpdir.refresh();
1111
common.expectWarning(
1212
'DeprecationWarning',
1313
'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' +
14-
'will throw if path does not exist or is a file. Use fs.rm(path, ' +
15-
'{ recursive: true, force: true }) instead',
14+
'will be removed. Use fs.rm(path, { recursive: true }) instead',
1615
'DEP0147'
1716
);
1817
const filePath = path.join(tmpdir.path, 'rmdir-recursive.txt');

Diff for: test/parallel/test-fs-rmdir-recursive-warns-not-found.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ tmpdir.refresh();
1111
common.expectWarning(
1212
'DeprecationWarning',
1313
'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' +
14-
'will throw if path does not exist or is a file. Use fs.rm(path, ' +
15-
'{ recursive: true, force: true }) instead',
14+
'will be removed. Use fs.rm(path, { recursive: true }) instead',
1615
'DEP0147'
1716
);
1817
fs.rmdir(

Diff for: test/parallel/test-fs-rmdir-recursive-warns-on-file.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ tmpdir.refresh();
1111
common.expectWarning(
1212
'DeprecationWarning',
1313
'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' +
14-
'will throw if path does not exist or is a file. Use fs.rm(path, ' +
15-
'{ recursive: true, force: true }) instead',
14+
'will be removed. Use fs.rm(path, { recursive: true }) instead',
1615
'DEP0147'
1716
);
1817
const filePath = path.join(tmpdir.path, 'rmdir-recursive.txt');

Diff for: test/parallel/test-fs-rmdir-recursive.js

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ const fs = require('fs');
77
const path = require('path');
88
const { validateRmdirOptions } = require('internal/fs/utils');
99

10+
common.expectWarning(
11+
'DeprecationWarning',
12+
'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' +
13+
'will be removed. Use fs.rm(path, { recursive: true }) instead',
14+
'DEP0147'
15+
);
16+
1017
tmpdir.refresh();
1118

1219
let count = 0;

0 commit comments

Comments
 (0)