( dir: string, projectsDir: string, projectName: string, )
| 662 | } |
| 663 | |
| 664 | function linkProjectIntoStudioData( |
| 665 | dir: string, |
| 666 | projectsDir: string, |
| 667 | projectName: string, |
| 668 | ): { symlinkPath: string; createdSymlink: boolean } { |
| 669 | const symlinkPath = join(projectsDir, projectName); |
| 670 | mkdirSync(projectsDir, { recursive: true }); |
| 671 | |
| 672 | let createdSymlink = false; |
| 673 | if (dir !== symlinkPath) { |
| 674 | if (existsSync(symlinkPath)) { |
| 675 | try { |
| 676 | const stat = lstatSync(symlinkPath); |
| 677 | if (stat.isSymbolicLink() && resolve(readlinkSync(symlinkPath)) !== resolve(dir)) { |
| 678 | unlinkSync(symlinkPath); |
| 679 | } |
| 680 | } catch { |
| 681 | // Real directories or unreadable paths are left untouched. |
| 682 | } |
| 683 | } |
| 684 | if (!existsSync(symlinkPath)) { |
| 685 | symlinkSync(dir, symlinkPath, "dir"); |
| 686 | createdSymlink = true; |
| 687 | } |
| 688 | } |
| 689 | |
| 690 | return { symlinkPath, createdSymlink }; |
| 691 | } |
| 692 | |
| 693 | function removeSymlinkOnExit(createdSymlink: boolean, symlinkPath: string): void { |
| 694 | if (!createdSymlink) return; |
no test coverage detected