Skip to content

Commit 46c24f8

Browse files
committed
fs: move rmdir recursive option to end-of-life
Has been runtime deprecated for ~ 5 years now. It's time.
1 parent 0b3fc0d commit 46c24f8

12 files changed

+70
-378
lines changed

doc/api/deprecations.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3057,6 +3057,9 @@ The [`crypto.Certificate()` constructor][] is deprecated. Use
30573057

30583058
<!-- YAML
30593059
changes:
3060+
- version: REPLACEME
3061+
pr-url: https://github.com/nodejs/node/pull/58616
3062+
description: End-of-Life.
30603063
- version: v16.0.0
30613064
pr-url: https://github.com/nodejs/node/pull/37302
30623065
description: Runtime deprecation.
@@ -3068,10 +3071,10 @@ changes:
30683071
description: Documentation-only deprecation.
30693072
-->
30703073

3071-
Type: Runtime
3074+
Type: End-of-Life
30723075

3073-
In future versions of Node.js, `recursive` option will be ignored for
3074-
`fs.rmdir`, `fs.rmdirSync`, and `fs.promises.rmdir`.
3076+
The `fs.rmdir`, `fs.rmdirSync`, and `fs.promises.rmdir` methods used
3077+
to support a `recursive` option. That option has been removed.
30753078

30763079
Use `fs.rm(path, { recursive: true, force: true })`,
30773080
`fs.rmSync(path, { recursive: true, force: true })` or

lib/fs.js

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ const {
101101
},
102102
copyObject,
103103
Dirent,
104-
emitRecursiveRmdirWarning,
105104
getDirent,
106105
getDirents,
107106
getOptions,
@@ -1122,35 +1121,21 @@ function rmdir(path, options, callback) {
11221121
options = undefined;
11231122
}
11241123

1124+
if (options?.recursive !== undefined) {
1125+
throw new ERR_INVALID_ARG_VALUE(
1126+
'options.recursive',
1127+
options.recursive,
1128+
'is no longer supported',
1129+
);
1130+
}
1131+
11251132
callback = makeCallback(callback);
11261133
path = getValidatedPath(path);
11271134

1128-
if (options?.recursive) {
1129-
emitRecursiveRmdirWarning();
1130-
validateRmOptions(
1131-
path,
1132-
{ ...options, force: false },
1133-
true,
1134-
(err, options) => {
1135-
if (err === false) {
1136-
const req = new FSReqCallback();
1137-
req.oncomplete = callback;
1138-
binding.rmdir(path, req);
1139-
return;
1140-
}
1141-
if (err) {
1142-
return callback(err);
1143-
}
1144-
1145-
lazyLoadRimraf();
1146-
rimraf(path, options, callback);
1147-
});
1148-
} else {
1149-
validateRmdirOptions(options);
1150-
const req = new FSReqCallback();
1151-
req.oncomplete = callback;
1152-
binding.rmdir(path, req);
1153-
}
1135+
validateRmdirOptions(options);
1136+
const req = new FSReqCallback();
1137+
req.oncomplete = callback;
1138+
binding.rmdir(path, req);
11541139
}
11551140

11561141
/**
@@ -1166,16 +1151,15 @@ function rmdir(path, options, callback) {
11661151
function rmdirSync(path, options) {
11671152
path = getValidatedPath(path);
11681153

1169-
if (options?.recursive) {
1170-
emitRecursiveRmdirWarning();
1171-
options = validateRmOptionsSync(path, { ...options, force: false }, true);
1172-
if (options !== false) {
1173-
return binding.rmSync(path, options.maxRetries, options.recursive, options.retryDelay);
1174-
}
1175-
} else {
1176-
validateRmdirOptions(options);
1154+
if (options?.recursive !== undefined) {
1155+
throw new ERR_INVALID_ARG_VALUE(
1156+
'options.recursive',
1157+
options.recursive,
1158+
'is no longer supported',
1159+
);
11771160
}
11781161

1162+
validateRmdirOptions(options);
11791163
binding.rmdir(path);
11801164
}
11811165

lib/internal/fs/promises.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ const {
5656
kWriteFileMaxChunkSize,
5757
},
5858
copyObject,
59-
emitRecursiveRmdirWarning,
6059
getDirents,
6160
getOptions,
6261
getStatFsFromBinding,
@@ -812,16 +811,17 @@ async function rm(path, options) {
812811

813812
async function rmdir(path, options) {
814813
path = getValidatedPath(path);
815-
options = validateRmdirOptions(options);
816814

817-
if (options.recursive) {
818-
emitRecursiveRmdirWarning();
819-
const stats = await stat(path);
820-
if (stats.isDirectory()) {
821-
return lazyRimRaf()(path, options);
822-
}
815+
if (options?.recursive !== undefined) {
816+
throw new ERR_INVALID_ARG_VALUE(
817+
'options.recursive',
818+
options.recursive,
819+
'is no longer supported',
820+
);
823821
}
824822

823+
options = validateRmdirOptions(options);
824+
825825
return await PromisePrototypeThen(
826826
binding.rmdir(path, kUsePromises),
827827
undefined,

lib/internal/fs/utils.js

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,6 @@ const defaultRmOptions = {
781781
const defaultRmdirOptions = {
782782
retryDelay: 100,
783783
maxRetries: 0,
784-
recursive: false,
785784
};
786785

787786
const validateCpOptions = hideStackFrames((options) => {
@@ -839,6 +838,7 @@ const validateRmOptions = hideStackFrames((path, options, expectDir, cb) => {
839838
const validateRmOptionsSync = hideStackFrames((path, options, expectDir) => {
840839
options = validateRmdirOptions.withoutStackTrace(options, defaultRmOptions);
841840
validateBoolean.withoutStackTrace(options.force, 'options.force');
841+
validateBoolean.withoutStackTrace(options.recursive, 'options.recursive');
842842

843843
if (!options.force || expectDir || !options.recursive) {
844844
const isDirectory = lazyLoadFs()
@@ -862,23 +862,6 @@ const validateRmOptionsSync = hideStackFrames((path, options, expectDir) => {
862862
return options;
863863
});
864864

865-
let recursiveRmdirWarned;
866-
function emitRecursiveRmdirWarning() {
867-
if (recursiveRmdirWarned === undefined) {
868-
// TODO(joyeecheung): use getOptionValue('--no-deprecation') instead.
869-
recursiveRmdirWarned = process.noDeprecation;
870-
}
871-
if (!recursiveRmdirWarned) {
872-
process.emitWarning(
873-
'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' +
874-
'will be removed. Use fs.rm(path, { recursive: true }) instead',
875-
'DeprecationWarning',
876-
'DEP0147',
877-
);
878-
recursiveRmdirWarned = true;
879-
}
880-
}
881-
882865
const validateRmdirOptions = hideStackFrames(
883866
(options, defaults = defaultRmdirOptions) => {
884867
if (options === undefined)
@@ -887,7 +870,6 @@ const validateRmdirOptions = hideStackFrames(
887870

888871
options = { ...defaults, ...options };
889872

890-
validateBoolean.withoutStackTrace(options.recursive, 'options.recursive');
891873
validateInt32.withoutStackTrace(options.retryDelay, 'options.retryDelay', 0);
892874
validateUint32.withoutStackTrace(options.maxRetries, 'options.maxRetries');
893875

@@ -950,7 +932,6 @@ module.exports = {
950932
copyObject,
951933
Dirent,
952934
DirentFromStats,
953-
emitRecursiveRmdirWarning,
954935
getDirent,
955936
getDirents,
956937
getOptions,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const {
6+
rmdir,
7+
rmdirSync,
8+
promises: { rmdir: rmdirPromise }
9+
} = require('fs');
10+
11+
assert.throws(() => {
12+
rmdir('nonexistent', {
13+
recursive: true,
14+
}, common.mustNotCall());
15+
}, {
16+
code: 'ERR_INVALID_ARG_VALUE',
17+
});
18+
19+
assert.throws(() => {
20+
rmdirSync('nonexistent', {
21+
recursive: true,
22+
});
23+
}, {
24+
code: 'ERR_INVALID_ARG_VALUE',
25+
});
26+
27+
rmdirPromise('nonexistent', {
28+
recursive: true,
29+
}).then(common.mustNotCall(), common.mustCall((err) => {
30+
assert.strictEqual(err.code, 'ERR_INVALID_ARG_VALUE');
31+
}));

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

Lines changed: 0 additions & 22 deletions
This file was deleted.

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

Lines changed: 0 additions & 22 deletions
This file was deleted.

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

Lines changed: 0 additions & 21 deletions
This file was deleted.

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

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)