replace-in-file
replace-in-file copied to clipboard
Parenthesis in replacement from string breaks match/replacement counting
Steps to reproduce:
Setup a from string with parenthesis ie.
app.setVersion('${sourceVersion}');
Run the replacement
Check the output value for numReplacements and numMatches, it will be 0, however the change was made
Change the from string to remove the parenthesis ie.
'${sourceVersion}'
Run the replacement
Check the output value for numReplacements and numMatches, it will be 1 and the change was made
Note that including a single parenthesis seems to cause errors to be thrown
replace-in-file/lib/helpers/make-replacements.js:58
const matches = contents.match(item);
^
SyntaxError: Invalid regular expression: /'1.0.0');/: Unmatched ')'
at String.match (<anonymous>)
at node_modules/replace-in-file/lib/helpers/make-replacements.js:58:32
at Array.reduce (<anonymous>)
at makeReplacements (node_modules/replace-in-file/lib/helpers/make-replacements.js:37:28)
at node_modules/replace-in-file/lib/helpers/replace-async.js:26:37
at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3)
```
Can you please supply an example with full options config that you're using, including from/to strings. It looks to me like you're perhaps supplying a regex but not escaping parenthesis properly.
@adamreisnz @cnatis
I met same issue either.
After check the source code, seems this is because the count matches function use String.match() to get the number of matches, in which will try to convert the plain string of option from to a RegExp by using new RegExp(from).
So if the string in from option can not be converted to a RegExp, it will throw an error.
And if the from string contains some special character of regexp, there might have chance that the replacement was made but the number of matches is 0.
Check below code snippets for details:
const originStr = "app.setVersion('${sourceVersion}');"
const to = "1.0.0";
let from;
// Case 1: String can be converted to RegExp
from = "sourceVersion";
console.log(originStr.replace(from, to)); // output: app.setVersion('${1.0.0}');
console.log(originStr.match(from)); // matches length is 1
// Case 2: String can be converted to RegExp, but with char need to escaped
from = "${sourceVersion}"
console.log(originStr.replace(from, to)); // output: app.setVersion('1.0.0');
console.log(originStr.match(from)); // null, replacement made, but got 0 matches
// Case 3: String can not be converted to RegExp
from = "${sourceVersion}')";
console.log(originStr.replace(from, to)); // output: app.setVersion('1.0.0;
console.log(originStr.match(from)); // throw error
Thanks, this has been fixed in 7.0.0