1 | import path from 'path';
|
2 | import fs from 'fs';
|
3 | import { promisify } from 'util';
|
4 |
|
5 | import rimraf from 'rimraf';
|
6 | import { isErrnoException } from '@stryker-mutator/util';
|
7 |
|
8 | export const fileUtils = {
|
9 | deleteDir: promisify(rimraf),
|
10 |
|
11 | async cleanFolder(folderName: string): Promise<string | undefined> {
|
12 | try {
|
13 | await fs.promises.lstat(folderName);
|
14 | await this.deleteDir(folderName);
|
15 | return fs.promises.mkdir(folderName, { recursive: true });
|
16 | } catch (e) {
|
17 | return fs.promises.mkdir(folderName, { recursive: true });
|
18 | }
|
19 | },
|
20 |
|
21 | async exists(fileName: string): Promise<boolean> {
|
22 | try {
|
23 | await fs.promises.stat(fileName);
|
24 | return true;
|
25 | } catch (err) {
|
26 | if (isErrnoException(err) && err.code === 'ENOENT') {
|
27 | return false;
|
28 | } else {
|
29 |
|
30 | throw err;
|
31 | }
|
32 | }
|
33 | },
|
34 |
|
35 | |
36 |
|
37 |
|
38 | importModule(moduleName: string): Promise<unknown> {
|
39 | return import(moduleName);
|
40 | },
|
41 |
|
42 | |
43 |
|
44 |
|
45 |
|
46 |
|
47 | moveDirectoryRecursiveSync(from: string, to: string): void {
|
48 | if (!fs.existsSync(from)) {
|
49 | return;
|
50 | }
|
51 | if (!fs.existsSync(to)) {
|
52 | fs.mkdirSync(to);
|
53 | }
|
54 | const files = fs.readdirSync(from);
|
55 | for (const file of files) {
|
56 | const fromFileName = path.join(from, file);
|
57 | const toFileName = path.join(to, file);
|
58 | const stats = fs.lstatSync(fromFileName);
|
59 | if (stats.isFile()) {
|
60 | fs.renameSync(fromFileName, toFileName);
|
61 | } else {
|
62 | this.moveDirectoryRecursiveSync(fromFileName, toFileName);
|
63 | }
|
64 | }
|
65 | fs.rmdirSync(from);
|
66 | },
|
67 |
|
68 | |
69 |
|
70 |
|
71 |
|
72 |
|
73 | async symlinkJunction(to: string, from: string): Promise<void> {
|
74 | await fs.promises.mkdir(path.dirname(from), { recursive: true });
|
75 | return fs.promises.symlink(to, from, 'junction');
|
76 | },
|
77 |
|
78 | |
79 |
|
80 |
|
81 |
|
82 |
|
83 | async findNodeModulesList(basePath: string, tempDirName?: string): Promise<string[]> {
|
84 | const nodeModulesList: string[] = [];
|
85 | const dirBfsQueue: string[] = ['.'] ?? [];
|
86 |
|
87 | let dir: string | undefined;
|
88 | while ((dir = dirBfsQueue.pop())) {
|
89 | if (path.basename(dir) === tempDirName) {
|
90 | continue;
|
91 | }
|
92 |
|
93 | if (path.basename(dir) === 'node_modules') {
|
94 | nodeModulesList.push(dir);
|
95 | continue;
|
96 | }
|
97 |
|
98 | const parentDir = dir;
|
99 | const filesWithType = await fs.promises.readdir(path.join(basePath, dir), { withFileTypes: true });
|
100 | const dirs = filesWithType.filter((file) => file.isDirectory()).map((childDir) => path.join(parentDir, childDir.name));
|
101 | dirBfsQueue.push(...dirs);
|
102 | }
|
103 |
|
104 | return nodeModulesList;
|
105 | },
|
106 | };
|