From 92cd0b65d255428d823ee8f04b56984457a58d8d Mon Sep 17 00:00:00 2001 From: Mathias Wulff Date: Fri, 23 Oct 2026 23:30:22 +1100 Subject: [PATCH] Use the path of --replacement-file as it is, with no escapes and no aliases --- src/alias.ts | 5 ++++- src/cli.ts | 3 ++- test/fix/817.test.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/fix/817.test.js diff --git a/src/alias.ts b/src/alias.ts index e872b519..8eace72c 100644 --- a/src/alias.ts +++ b/src/alias.ts @@ -15,7 +15,10 @@ export function alias(config) { }; config.pattern = swap(config.pattern); - config.replacement = swap(config.replacement); + // With --replacement-file the replacement is the name of a file, unless --js code gives the name + if (!config.replacementFile || config.replacementJs) { + config.replacement = swap(config.replacement); + } config.excludeRe = config.excludeRe.map(swap); config.delimiter = swap(config.delimiter); config.nameDelimiter = swap(config.nameDelimiter); diff --git a/src/cli.ts b/src/cli.ts index 8b1b73d2..5b568196 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -623,7 +623,8 @@ const unescape = (key, name) => { } }; -if (!config.replacementJs) { +// The path of --replacement-file is the name of a file, so it has no escapes +if (!config.replacementJs && !config.replacementFile) { unescape('replacement', 'replacement'); } diff --git a/test/fix/817.test.js b/test/fix/817.test.js new file mode 100644 index 00000000..35d54fdc --- /dev/null +++ b/test/fix/817.test.js @@ -0,0 +1,32 @@ +// https://github.com/mathiasrw/rexreplace/issues/817 +// The path of --replacement-file went through the escapes and the € and § aliases of a typed replacement, +// so a backslash in a Windows path was lost, and price€.txt was looked for as price$.txt. +import {describe, test, expect} from 'bun:test'; +import fs from 'fs'; +import {$} from 'bun'; +import {cli, sh} from '../helper.js'; + +describe('#817 the path of --replacement-file', () => { + test('keeps a backslash', async () => { + fs.mkdirSync('my\\dir'); + fs.writeFileSync('my\\dir/new.txt', 'NEW'); + fs.writeFileSync('page.txt', 'X'); + const result = await sh($`bun ${cli} X ${'my\\dir/new.txt'} page.txt -o --replacement-file`); + expect(result).toEqual({out: 'NEW\n', err: 'page.txt\n', exit: 0}); + }); + + test('keeps € and §, as the aliases are not used in file names', async () => { + fs.writeFileSync('price€§.txt', 'PRICE'); + fs.writeFileSync('page.txt', 'X'); + const result = await sh($`bun ${cli} X ${'price€§.txt'} page.txt -o --replacement-file`); + expect(result.out).toBe('PRICE\n'); + }); + + test('still uses the aliases in the code of --js, which gives the path', async () => { + fs.writeFileSync('new.txt', 'NEW'); + fs.writeFileSync('page.txt', 'X'); + const code = '"new" + €0.replace("X", ".txt")'; + const result = await sh($`bun ${cli} X ${code} page.txt -o --replacement-file --js`); + expect(result.out).toBe('NEW\n'); + }); +});