| 743 | } |
| 744 | |
| 745 | public async patchFile( |
| 746 | filename: string, |
| 747 | content: string | ((content: string | undefined) => string), |
| 748 | runWithTempContent?: (context: { newFile: boolean }) => Promise<void> |
| 749 | ): Promise<{ newFile: boolean }> { |
| 750 | const outputPath = path.join(this.testDir, filename) |
| 751 | const newFile = !existsSync(outputPath) |
| 752 | await fs.mkdir(path.dirname(outputPath), { recursive: true }) |
| 753 | const previousContent = newFile ? undefined : await this.readFile(filename) |
| 754 | |
| 755 | await fs.writeFile( |
| 756 | outputPath, |
| 757 | typeof content === 'function' ? content(previousContent) : content, |
| 758 | { |
| 759 | flush: true, |
| 760 | } |
| 761 | ) |
| 762 | |
| 763 | if (runWithTempContent) { |
| 764 | try { |
| 765 | await runWithTempContent({ newFile }) |
| 766 | } finally { |
| 767 | if (previousContent === undefined) { |
| 768 | await fs.rm(outputPath) |
| 769 | } else { |
| 770 | await fs.writeFile(outputPath, previousContent, { |
| 771 | flush: true, |
| 772 | }) |
| 773 | } |
| 774 | } |
| 775 | } |
| 776 | |
| 777 | return { newFile } |
| 778 | } |
| 779 | |
| 780 | public async renameFile(filename: string, newFilename: string) { |
| 781 | await fs.rename( |