1 | import fs from 'fs';
|
2 | import nodePathModule from 'path';
|
3 |
|
4 | function getStatForPath(path, indiscriminateOfSymlinks) {
|
5 |
|
6 | const statMethodName = indiscriminateOfSymlinks ? 'statSync' : 'lstatSync';
|
7 | const stat = Object.assign(fs[statMethodName](path), { path });
|
8 |
|
9 | return {
|
10 | path: stat.path,
|
11 | symlink: stat.isSymbolicLink()
|
12 | ? nodePathModule.resolve(
|
13 | nodePathModule.dirname(stat.path),
|
14 | fs.readlinkSync(stat.path)
|
15 | )
|
16 | : false,
|
17 | file: stat.isFile(),
|
18 | directory: stat.isDirectory(),
|
19 | size: stat.size,
|
20 | accessed: stat.atime,
|
21 | modified: stat.mtime,
|
22 | changed: stat.ctime,
|
23 | created: stat.birthtime,
|
24 | };
|
25 | }
|
26 |
|
27 | function getAllStatsInPath(dir, indiscriminateOfSymlinks) {
|
28 | return fs
|
29 | .readdirSync(dir)
|
30 | .map((file) => nodePathModule.resolve(dir, file))
|
31 | .map((path) => {
|
32 | try {
|
33 | return getStatForPath(path, indiscriminateOfSymlinks);
|
34 | } catch (_error) {
|
35 |
|
36 | }
|
37 | })
|
38 | .filter((result) => !!result);
|
39 | }
|
40 |
|
41 | export default function getParentDirectoryContainingFileSync(
|
42 | cwd,
|
43 | configFileName
|
44 | ) {
|
45 | const rootDir = nodePathModule.parse(cwd).root;
|
46 | const pathHasConfigFile = getAllStatsInPath(cwd, false).some(
|
47 | (stat) =>
|
48 | stat.file && nodePathModule.basename(stat.path) === configFileName
|
49 | );
|
50 |
|
51 |
|
52 | return pathHasConfigFile
|
53 | ? cwd
|
54 | : cwd === rootDir
|
55 | ? null
|
56 | : getParentDirectoryContainingFileSync(
|
57 | nodePathModule.dirname(cwd),
|
58 | configFileName
|
59 | );
|
60 | }
|