|
1 | 1 | /* eslint-disable node-core/require-common-first, node-core/required-modules */
|
2 | 2 | 'use strict';
|
3 | 3 |
|
| 4 | +const { execSync } = require('child_process'); |
4 | 5 | const fs = require('fs');
|
5 | 6 | const path = require('path');
|
| 7 | +const { debuglog } = require('util'); |
6 | 8 |
|
7 |
| -function rimrafSync(p) { |
8 |
| - let st; |
9 |
| - try { |
10 |
| - st = fs.lstatSync(p); |
11 |
| - } catch (e) { |
12 |
| - if (e.code === 'ENOENT') |
13 |
| - return; |
| 9 | +const debug = debuglog('test/tmpdir'); |
| 10 | + |
| 11 | +function rimrafSync(pathname, { spawn = true } = {}) { |
| 12 | + const st = (() => { |
| 13 | + try { |
| 14 | + return fs.lstatSync(pathname); |
| 15 | + } catch (e) { |
| 16 | + if (fs.existsSync(pathname)) |
| 17 | + throw new Error(`Something wonky happened rimrafing ${pathname}`); |
| 18 | + debug(e); |
| 19 | + } |
| 20 | + })(); |
| 21 | + |
| 22 | + // If (!st) then nothing to do. |
| 23 | + if (!st) { |
| 24 | + return; |
| 25 | + } |
| 26 | + |
| 27 | + // On Windows first try to delegate rmdir to a shell. |
| 28 | + if (spawn && process.platform === 'win32' && st.isDirectory()) { |
| 29 | + try { |
| 30 | + // Try `rmdir` first. |
| 31 | + execSync(`rmdir /q /s ${pathname}`, { timout: 1000 }); |
| 32 | + } catch (e) { |
| 33 | + // Attempt failed. Log and carry on. |
| 34 | + debug(e); |
| 35 | + } |
14 | 36 | }
|
15 | 37 |
|
16 | 38 | try {
|
17 |
| - if (st && st.isDirectory()) |
18 |
| - rmdirSync(p, null); |
| 39 | + if (st.isDirectory()) |
| 40 | + rmdirSync(pathname, null); |
19 | 41 | else
|
20 |
| - fs.unlinkSync(p); |
| 42 | + fs.unlinkSync(pathname); |
21 | 43 | } catch (e) {
|
22 |
| - if (e.code === 'ENOENT') |
23 |
| - return; |
24 |
| - if (e.code === 'EPERM') |
25 |
| - return rmdirSync(p, e); |
26 |
| - if (e.code !== 'EISDIR') |
27 |
| - throw e; |
28 |
| - rmdirSync(p, e); |
| 44 | + debug(e); |
| 45 | + switch (e.code) { |
| 46 | + case 'ENOENT': |
| 47 | + // It's not there anymore. Work is done. Exiting. |
| 48 | + return; |
| 49 | + |
| 50 | + case 'EPERM': |
| 51 | + // This can happen, try again with `rmdirSync`. |
| 52 | + break; |
| 53 | + |
| 54 | + case 'EISDIR': |
| 55 | + // Got 'EISDIR' even after testing `st.isDirectory()`... |
| 56 | + // Try again with `rmdirSync`. |
| 57 | + break; |
| 58 | + |
| 59 | + default: |
| 60 | + throw e; |
| 61 | + } |
| 62 | + rmdirSync(pathname, e); |
29 | 63 | }
|
30 | 64 | }
|
31 | 65 |
|
@@ -62,8 +96,8 @@ if (process.env.TEST_THREAD_ID) {
|
62 | 96 |
|
63 | 97 | const tmpPath = path.join(testRoot, tmpdirName);
|
64 | 98 |
|
65 |
| -function refresh() { |
66 |
| - rimrafSync(this.path); |
| 99 | +function refresh(opts = {}) { |
| 100 | + rimrafSync(this.path, opts); |
67 | 101 | fs.mkdirSync(this.path);
|
68 | 102 | }
|
69 | 103 |
|
|
0 commit comments