diff --git a/.changeset/blue-carrots-think.md b/.changeset/blue-carrots-think.md new file mode 100644 index 00000000000..964bf60b770 --- /dev/null +++ b/.changeset/blue-carrots-think.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-patching": patch +"pnpm": patch +--- + +`pnpm patch` should work on files that don't have an end of line [#5320](https://github.com/pnpm/pnpm/issues/5320). diff --git a/packages/plugin-commands-patching/src/patchCommit.ts b/packages/plugin-commands-patching/src/patchCommit.ts index 4c22b4102f0..cc4666d9991 100644 --- a/packages/plugin-commands-patching/src/patchCommit.ts +++ b/packages/plugin-commands-patching/src/patchCommit.ts @@ -98,4 +98,5 @@ async function diffFolders (folderA: string, folderB: string) { .replace(new RegExp(`(a|b)${escapeStringRegexp(`/${normalizePath(folderBN)}/`)}`, 'g'), '$1/') .replace(new RegExp(escapeStringRegexp(`${folderAN}/`), 'g'), '') .replace(new RegExp(escapeStringRegexp(`${folderBN}/`), 'g'), '') + .replace(/\n\\ No newline at end of file$/, '') } diff --git a/packages/plugin-commands-patching/test/patch.test.ts b/packages/plugin-commands-patching/test/patch.test.ts index c6b6169166a..949081c30bf 100644 --- a/packages/plugin-commands-patching/test/patch.test.ts +++ b/packages/plugin-commands-patching/test/patch.test.ts @@ -94,3 +94,80 @@ describe('patch and commit', () => { .rejects.toThrow(`The target directory already exists: '${editDir}'`) }) }) + +describe('patching should work when there is a no EOL in the patched file', () => { + let defaultPatchOption: patch.PatchCommandOptions + + beforeEach(() => { + prepare({ + dependencies: { + 'safe-execa': '0.1.2', + }, + }) + + const cacheDir = path.resolve('cache') + const storeDir = path.resolve('store') + + defaultPatchOption = { + cacheDir, + dir: process.cwd(), + pnpmHomeDir: '', + rawConfig: { + registry: `http://localhost:${REGISTRY_MOCK_PORT}/`, + }, + registries: { default: `http://localhost:${REGISTRY_MOCK_PORT}/` }, + storeDir, + userConfig: {}, + } + }) + it('should work when adding content on a newline', async () => { + const output = await patch.handler(defaultPatchOption, ['safe-execa@0.1.2']) + const userPatchDir = output.substring(output.indexOf(':') + 1).trim() + const tempDir = os.tmpdir() + + expect(userPatchDir).toContain(tempDir) + expect(fs.existsSync(userPatchDir)).toBe(true) + expect(fs.existsSync(path.join(userPatchDir, 'lib/index.js'))).toBe(true) + + fs.appendFileSync(path.join(userPatchDir, 'lib/index.js'), '\n// test patching', 'utf8') + + await patchCommit.handler({ + ...DEFAULT_OPTS, + dir: process.cwd(), + }, [userPatchDir]) + + const { manifest } = await readProjectManifest(process.cwd()) + expect(manifest.pnpm?.patchedDependencies).toStrictEqual({ + 'safe-execa@0.1.2': 'patches/safe-execa@0.1.2.patch', + }) + const patchContent = fs.readFileSync('patches/safe-execa@0.1.2.patch', 'utf8') + expect(patchContent).toContain('diff --git') + expect(patchContent).toContain('// test patching') + expect(patchContent).not.toContain('No newline at end of file') + expect(fs.readFileSync('node_modules/safe-execa/lib/index.js', 'utf8')).toContain('// test patching') + }) + it('should work fine when new content is appended', async () => { + const output = await patch.handler(defaultPatchOption, ['safe-execa@0.1.2']) + const userPatchDir = output.substring(output.indexOf(':') + 1).trim() + const tempDir = os.tmpdir() + + expect(userPatchDir).toContain(tempDir) + expect(fs.existsSync(userPatchDir)).toBe(true) + expect(fs.existsSync(path.join(userPatchDir, 'lib/index.js'))).toBe(true) + + fs.appendFileSync(path.join(userPatchDir, 'lib/index.js'), '// patch without newline', 'utf8') + + await patchCommit.handler({ + ...DEFAULT_OPTS, + dir: process.cwd(), + }, [userPatchDir]) + + const { manifest } = await readProjectManifest(process.cwd()) + expect(manifest.pnpm?.patchedDependencies).toStrictEqual({ + 'safe-execa@0.1.2': 'patches/safe-execa@0.1.2.patch', + }) + const patchContent = fs.readFileSync('patches/safe-execa@0.1.2.patch', 'utf8') + expect(patchContent).toContain('No newline at end of file') + expect(fs.readFileSync('node_modules/safe-execa/lib/index.js', 'utf8')).toContain('//# sourceMappingURL=index.js.map// patch without newline') + }) +})