|
1 | 1 | import { pathExists, stat, readdir, opendir } from "fs-extra";
|
2 |
| -import { isAbsolute, join, relative, resolve, sep } from "path"; |
3 |
| -import { tmpdir as osTmpdir, platform } from "os"; |
| 2 | +import { dirname, isAbsolute, join, relative, resolve } from "path"; |
| 3 | +import { tmpdir as osTmpdir } from "os"; |
4 | 4 |
|
5 | 5 | /**
|
6 | 6 | * Recursively finds all .ql files in this set of Uris.
|
@@ -147,40 +147,21 @@ export function findCommonParentDir(...paths: string[]): string {
|
147 | 147 | throw new Error("All paths must be absolute");
|
148 | 148 | }
|
149 | 149 |
|
150 |
| - const normalizedPaths = paths.map((path) => normalizePath(path)); |
| 150 | + paths = paths.map((path) => normalizePath(path)); |
151 | 151 |
|
152 |
| - const pathParts = normalizedPaths.map((path) => getPathParts(path)); |
153 |
| - |
154 |
| - const commonParts = []; |
155 |
| - |
156 |
| - // Iterate over the components of the first path and check if the same |
157 |
| - // component exists at the same position in all the other paths. If it does, |
158 |
| - // add the component to the common directory. If it doesn't, stop the |
159 |
| - // iteration and returns the common directory found so far. |
160 |
| - for (const [i, part] of pathParts[0].entries()) { |
161 |
| - if (pathParts.every((parts) => parts[i] === part)) { |
162 |
| - commonParts.push(part); |
163 |
| - } else { |
164 |
| - break; |
| 152 | + let commonDir = paths[0]; |
| 153 | + while (!paths.every((path) => containsPath(commonDir, path))) { |
| 154 | + if (isTopLevelPath(commonDir)) { |
| 155 | + throw new Error( |
| 156 | + "Reached filesystem root and didn't find a common parent directory", |
| 157 | + ); |
165 | 158 | }
|
| 159 | + commonDir = dirname(commonDir); |
166 | 160 | }
|
167 | 161 |
|
168 |
| - const commonDir = join(...commonParts); |
169 |
| - return ensureAbsolutePath(commonDir); |
170 |
| -} |
171 |
| - |
172 |
| -function getPathParts(path: string): string[] { |
173 |
| - // On Windows, keep the drive letter with the first part of the path |
174 |
| - if (platform() === "win32" && path.includes(":")) { |
175 |
| - const [driveLetter, ...restOfPath] = path.split(sep); |
176 |
| - restOfPath[0] = driveLetter + sep + restOfPath[0]; |
177 |
| - return restOfPath; |
178 |
| - } |
179 |
| - |
180 |
| - // On other platforms, just split the path normally |
181 |
| - return path.split(sep); |
| 162 | + return commonDir; |
182 | 163 | }
|
183 | 164 |
|
184 |
| -function ensureAbsolutePath(path: string): string { |
185 |
| - return platform() === "win32" ? path : `${sep}${path}`; |
| 165 | +function isTopLevelPath(path: string): boolean { |
| 166 | + return dirname(path) === path; |
186 | 167 | }
|
0 commit comments