facebookincubator / fastmod

A fast partial replacement for the codemod tool
Apache License 2.0
1.66k stars 41 forks source link

Find a way to match on complex, multiline patterns #10

Closed felipesere closed 6 years ago

felipesere commented 6 years ago

Hi and thank you for open sourcing fastmod!

I was trying to use it to replace

try {
  await thing.start()
} catch (e) {
  console.error(e)
}

with just

await thing.start()

I assume giving enough effort with the multiline regex I could solve it, but I was wondering there would be interest to have a parameter that would accept a simpler pattern in a file?

Something like fastmod -p pattern-file "replacement \${1}"

pattern-file could contain something like

try {
  $1
} catch (e) {
  console.error(e)
}

Everything else would remain the same 😄

swolchok commented 6 years ago

You can do this with fastmod today. The only trick is that curly braces are special characters to the regex crate, so you need to escape them:

bash-3.2$ cat replace.pat
try \{
(.*)
\} catch \(e\) \{
  console.error\(e\)
\}bash-3.2$ cat haystack.txt
try {
  await thing.start()
} catch (e) {
  console.error(e)
}
bash-3.2$ fastmod "$(< replace.pat)" "\${1}" haystack.txt
haystack.txt:1-5
- try {
    await thing.start()
- } catch (e) {
-   console.error(e)
- }
Accept change (y = yes [default], n = no, e = edit, A = yes to all, E = yes+edit, q = quit)?
felipesere commented 6 years ago

Awesome! I tried this with $(cat replace.pat) initially... I might replace a PR for all of fastmod with a small utility that adequately escapes my pattern for me 🤓 Thank you!

swolchok commented 6 years ago

AFAIK $(cat replace.pat) should be equivalent to $(< replace.pat), and man bash agrees:

The command substitution $(cat file) can be replaced by the equivalent but faster $(< file)