(filePath: string)
| 250 | * Resolves symlinks to handle /tmp vs /private/tmp on macOS. |
| 251 | */ |
| 252 | export function normalizeFilePath(filePath: string): string { |
| 253 | const fs = getFsImplementation() |
| 254 | const cwd = getAttributionRepoRoot() |
| 255 | |
| 256 | if (!isAbsolute(filePath)) { |
| 257 | return filePath |
| 258 | } |
| 259 | |
| 260 | // Resolve symlinks in both paths for consistent comparison |
| 261 | // (e.g., /tmp -> /private/tmp on macOS) |
| 262 | let resolvedPath = filePath |
| 263 | let resolvedCwd = cwd |
| 264 | |
| 265 | try { |
| 266 | resolvedPath = fs.realpathSync(filePath) |
| 267 | } catch { |
| 268 | // File may not exist yet, use original path |
| 269 | } |
| 270 | |
| 271 | try { |
| 272 | resolvedCwd = fs.realpathSync(cwd) |
| 273 | } catch { |
| 274 | // Keep original cwd |
| 275 | } |
| 276 | |
| 277 | if ( |
| 278 | resolvedPath.startsWith(resolvedCwd + sep) || |
| 279 | resolvedPath === resolvedCwd |
| 280 | ) { |
| 281 | // Normalize to forward slashes so keys match git diff output on Windows |
| 282 | return relative(resolvedCwd, resolvedPath).replaceAll(sep, '/') |
| 283 | } |
| 284 | |
| 285 | // Fallback: try original comparison |
| 286 | if (filePath.startsWith(cwd + sep) || filePath === cwd) { |
| 287 | return relative(cwd, filePath).replaceAll(sep, '/') |
| 288 | } |
| 289 | |
| 290 | return filePath |
| 291 | } |
| 292 | |
| 293 | /** |
| 294 | * Expand a relative path to absolute path. |
no test coverage detected