Skip to content

Commit 1641ff5

Browse files
RaisinTentargos
authored andcommitted
test,fs: add fs.rm() tests for .git directories
Git for Windows creates read-only files inside the .git directory. fs.rm() was built in a way, to work around any EPERM error that can happen while deleting the .git directory by turning the directory into a writable one. This change adds a regression test for that. Refs: isaacs/rimraf#21 Refs: #38810 (comment) Signed-off-by: Darshan Sen <raisinten@gmail.com> PR-URL: #42410 Reviewed-By: Ben Coe <bencoe@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 33b1426 commit 1641ff5

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

test/parallel/test-fs-rm.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const assert = require('assert');
66
const fs = require('fs');
77
const path = require('path');
88
const { pathToFileURL } = require('url');
9+
const { execSync } = require('child_process');
910

1011
const { validateRmOptionsSync } = require('internal/fs/utils');
1112

@@ -15,6 +16,15 @@ let count = 0;
1516
const nextDirPath = (name = 'rm') =>
1617
path.join(tmpdir.path, `${name}-${count++}`);
1718

19+
const isGitPresent = (() => {
20+
try { execSync('git --version'); return true; } catch { return false; }
21+
})();
22+
23+
function gitInit(gitDirectory) {
24+
fs.mkdirSync(gitDirectory);
25+
execSync('git init', { cwd: gitDirectory });
26+
}
27+
1828
function makeNonEmptyDirectory(depth, files, folders, dirname, createSymLinks) {
1929
fs.mkdirSync(dirname, { recursive: true });
2030
fs.writeFileSync(path.join(dirname, 'text.txt'), 'hello', 'utf8');
@@ -129,6 +139,16 @@ function removeAsync(dir) {
129139
}));
130140
}
131141

142+
// Removing a .git directory should not throw an EPERM.
143+
// Refs: https://github.com/isaacs/rimraf/issues/21.
144+
if (isGitPresent) {
145+
const gitDirectory = nextDirPath();
146+
gitInit(gitDirectory);
147+
fs.rm(gitDirectory, { recursive: true }, common.mustSucceed(() => {
148+
assert.strictEqual(fs.existsSync(gitDirectory), false);
149+
}));
150+
}
151+
132152
// Test the synchronous version.
133153
{
134154
const dir = nextDirPath();
@@ -178,6 +198,15 @@ function removeAsync(dir) {
178198
assert.throws(() => fs.rmSync(dir), { syscall: 'stat' });
179199
}
180200

201+
// Removing a .git directory should not throw an EPERM.
202+
// Refs: https://github.com/isaacs/rimraf/issues/21.
203+
if (isGitPresent) {
204+
const gitDirectory = nextDirPath();
205+
gitInit(gitDirectory);
206+
fs.rmSync(gitDirectory, { recursive: true });
207+
assert.strictEqual(fs.existsSync(gitDirectory), false);
208+
}
209+
181210
// Test the Promises based version.
182211
(async () => {
183212
const dir = nextDirPath();
@@ -229,6 +258,17 @@ function removeAsync(dir) {
229258
}
230259
})().then(common.mustCall());
231260

261+
// Removing a .git directory should not throw an EPERM.
262+
// Refs: https://github.com/isaacs/rimraf/issues/21.
263+
if (isGitPresent) {
264+
(async () => {
265+
const gitDirectory = nextDirPath();
266+
gitInit(gitDirectory);
267+
await fs.promises.rm(gitDirectory, { recursive: true });
268+
assert.strictEqual(fs.existsSync(gitDirectory), false);
269+
})().then(common.mustCall());
270+
}
271+
232272
// Test input validation.
233273
{
234274
const dir = nextDirPath();

0 commit comments

Comments
 (0)