For Java, IntelliJ has a built-in version of this called "structural search and replace" [0]. This is incredibly useful when a library changes an API or you need to refactor a lot of similar code.<p>This feels relatively safe in Java because tooling can staticly know a lot about your code (and can know for sure that a particular call site is the method or class you're targeting). I've be terrified to do it in python without a very thorough test suite.<p>[0] <a href="https://www.jetbrains.com/help/idea/2016.2/structural-search-and-replace.html" rel="nofollow">https://www.jetbrains.com/help/idea/2016.2/structural-search...</a>
"...time that could be better spent working on new features and shipping new code"<p>Can we please stop putting forth this idea that features >>> reliable product? The amount of dev time that a company will save from removing technical debt will likely be more than the extra sales the company will get from a new feature. I look forward to the day where the executive team comes to the developers and ask why they are working on features instead of cutting down technical debt.
How do web applications explode out to 3 Million lines of code? Yelp, to me, looks like a typical CRUD app and I would have been surprised if it were more than 100,000 lines of code. The software I develop is pretty large and typically doesn't surpass 40,000 sloc written in-house (i.e. excluding third party libs).<p>Does anyone here maintain such large codebases? Are they truly that big or are people just counting third party code and generated stuff?
It would be nice if some research institution would pay for the rehabilitation of some huge, bloated, ancient, but relatively unimportant app. Ideally by independent teams in parallel.<p>Just to get some real data on what works, rather than anecdotes from veterans.
I have my doubts that a refactor that consists merely of more complex search and replace actions is a true refactor. Also, this reads more like an ad for their Python tool than about any lessons learned during this refactoring.
It seems to me this is only going to handle the most trivial kind of technical debt. This kind of tool can't manage the way you organized your codebase, for instance. There's more to refactoring than find-and-replace.
I would also be interested the thought process in deciding what functionality to refactor. Did you review the code and identify areas before unleashing your tool on it?<p>With 3M lines of code gone, it must be terrifying to feel that it may have broken something. How did you ensure that it is still working as before?<p>Edit: Grammatic corrections.
This smells as being a need that comes as a consequence of using a dynamically-typed language. Because the example given seems to be just getting rid of the usage of a certain method, to replace with a new one. In a statically typed language, e.g. C#, you just mark the old method with an [Obsolete] attribute and go fix all the warnings. (Granted, a tool that replaces all these usages is also useful, but to me, there are much more complex ways of technical debt than just obsolete methods.)
IMO a much better approach is JSCodeShift, which works based on the AST: <a href="https://github.com/facebook/jscodeshift" rel="nofollow">https://github.com/facebook/jscodeshift</a>
“Let a 1,000 flowers bloom. Then rip 999 of them out by the roots.”<p>This is paraphrasing of Chairman Mao:<p>"The policy of letting a hundred flowers bloom and a hundred schools of thought contend is designed to promote the flourishing of the arts and the progress of science"<p>And the ripping out by roots part brings labor camps to mind:<p>"After this brief period of liberalization, Mao abruptly changed course. The crackdown continued through 1957 as an Anti-Rightist Campaign against those who were critical of the regime and its ideology. Those targeted were publicly criticized and condemned to prison labor camps."<p><a href="https://en.wikipedia.org/wiki/Hundred_Flowers_Campaign" rel="nofollow">https://en.wikipedia.org/wiki/Hundred_Flowers_Campaign</a>
Related: <a href="http://coccinelle.lip6.fr/" rel="nofollow">http://coccinelle.lip6.fr/</a><p>Coccinelle is used extensively by Linux kernel developers for a whole tonne of things like this.
Refactoring... "puts a massive drain on developer time; time that could be better spent working on new features and shipping new code"<p>This is the wrong way to think. Refactoring will save time by making code faster, more reliable and making it easier to build those new features in the first place. Looks like their biggest issue is bad technical management, not deprecated code.
A funny and relevant tweet:<p><a href="https://twitter.com/php_ceo/status/765298072691806209" rel="nofollow">https://twitter.com/php_ceo/status/765298072691806209</a>
Google has a similar tool called Refaster<p><a href="https://github.com/google/Refaster" rel="nofollow">https://github.com/google/Refaster</a>
The patterns that Undebt removes could be non-existent in the code base, but the conceptual, algorithmic design decisions and architecture could be all bad and that is what the actual technical debt is. Bad code patterns are just a tiny slice of the problem in most cases.
If any of you guys are interested plotting total lines of code changes, do checkout <a href="https://github.com/kaihendry/graphsloc" rel="nofollow">https://github.com/kaihendry/graphsloc</a>