(projectRoot: string)
| 124 | * The returned string is a human phrase that slots into "… looks like {reason}". |
| 125 | */ |
| 126 | export function unsafeIndexRootReason(projectRoot: string): string | null { |
| 127 | const resolve = (p: string): string => { |
| 128 | try { |
| 129 | return fs.realpathSync(path.resolve(p)); |
| 130 | } catch { |
| 131 | return path.resolve(p); |
| 132 | } |
| 133 | }; |
| 134 | const resolved = resolve(projectRoot); |
| 135 | |
| 136 | // Filesystem root: `/` on POSIX, a drive root like `C:\` on Windows. |
| 137 | if (path.parse(resolved).root === resolved) { |
| 138 | return 'the filesystem root'; |
| 139 | } |
| 140 | |
| 141 | const home = resolve(os.homedir()); |
| 142 | // Case-insensitive on macOS/Windows (case-preserving but case-insensitive FS). |
| 143 | const norm = (p: string): string => |
| 144 | process.platform === 'darwin' || process.platform === 'win32' ? p.toLowerCase() : p; |
| 145 | const r = norm(resolved); |
| 146 | const h = norm(home); |
| 147 | |
| 148 | if (r === h) { |
| 149 | return 'your home directory'; |
| 150 | } |
| 151 | // An ancestor of home (e.g. `/Users`, `/home`) — even broader than home. |
| 152 | if (h.startsWith(r + path.sep)) { |
| 153 | return 'a parent of your home directory'; |
| 154 | } |
| 155 | return null; |
| 156 | } |
| 157 | |
| 158 | export function findNearestCodeGraphRoot(startPath: string): string | null { |
| 159 | let current = path.resolve(startPath); |
no test coverage detected