Open-source project
seattlerb/debride avatar
seattlerb/debride

debride: finding Ruby methods that nothing calls

Analyze code for potentially uncalled / dead methods, now with auto-removal.

776 stars19 forksRubyLicense varies

At a glance

What is it?
debride is a static analyser that reports methods with no callers, lets you whitelist the ones that are called indirectly, and ships debride_rm to delete what it finds. It is a good fit for a Rails or Ruby codebase that has grown dead methods, while the removal mode is deliberately blunt and needs a whitelist you trust.
Who is it for?
Use debride when you want a report of methods with no visible callers in a Ruby or Rails codebase and you are prepared to build a whitelist from routes and production logs, since the tool is only as accurate as that whitelist. Do not point debride_rm at a codebase you do not understand, since it removes source files and the README itself warns about it and about attr_accessor lists, and start with a high --minimum value rather than a low one.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A report of methods with no visible caller

debride analyses code for potentially uncalled or dead methods, and the project description adds that it now does auto-removal as well. It is written in Ruby, the homepage is the project page on zenspider.com, and the documentation lives at docs.seattlerb.org.

The basic invocation is a path, and the output is grouped by class with the file and line of each suspect method:

bash
debride lib

Two properties are stated in the feature list and both matter. The analysis is static, which means the project says it can be easily hooked up to a CI, so it can run on every commit rather than as a one-off cleanup. And, as with all static analysis tools for dynamic languages, it cannot be 100% correct. That caveat is not a throwaway line, because the entire design of the tool is built around it: the whitelist exists precisely because the analyser cannot see calls that happen through reflection, through a framework, or through configuration.

So the realistic output is a list of methods that might not be called, not a list of methods that are dead. A tool that claimed otherwise would be lying about what static analysis of Ruby can do.

The whitelist is the real interface

Once you have a list of suspects, the question becomes which of them are in fact called. The documented way to answer that is a whitelist, and the workflow in the synopsis is short: write the names of methods you know are called into a file, then pass it with --whitelist.

bash
debride --whitelist whitelist.txt lib

The example makes the intent clear. good_method is called, perhaps because it is public API, so it goes into the file and drops out of the report, while bad_method stays. The reason the method was called does not need to be visible to the tool. A whitelist entry is a claim that somebody, somewhere, calls this.

Whitelisting works by name or by regular expression. The README notes you can use regexps in your whitelist by delimiting them with forward slashes, which is what you need when a whole family of methods is called from a template or a metaprogrammed name.

The consequences of this design run through the rest of the tool. Every mode, including the removal mode, takes a --whitelist. The whitelist is not an optional refinement, it is the mechanism by which the tool becomes usable, and a whitelist that is too small will produce a report full of false positives while a whitelist that is too large will hide the dead code you were looking for.

Rails: routes and production logs as the source of truth

The Rails example in the README is the most useful part of the documentation, because it shows where the whitelist entries come from instead of leaving you to guess.

The method is to derive the whitelist from two real sources: the routes the application declares, and the log of what the running application actually did. First you dump the routes:

bash
rake routes > routes.txt
debride_rails_whitelist routes.txt log/production.log | sort -u > whitelist.txt

The debride_rails_whitelist helper reads the routes file and the production log, and produces the list of method names that those two sources imply are called. Because the log is a record of real requests, a method that was invoked in production appears in the whitelist even though no static call site exists.

Two more entries are added by hand, because migrations are called by the framework rather than by your code:

bash
echo up >> whitelist.txt
echo down >> whitelist.txt
echo change >> whitelist.txt

And then the analysis runs with the Rails extensions enabled, the whitelist applied, and the current directory as the target:

bash
debride --rails --whitelist whitelist.txt .

The --rails flag turns on Rails-specific domain knowledge, so the tool knows the conventions of the framework instead of reporting framework methods as dead.

Building a whitelist from remote logs

The README also gives a recipe for the case where your logs are not on the machine you are working on, using Papertrail. It builds a whitelist from the last 28 days of archives:

bash
seq 2 29 | xargs -I {} date -u -v-{}d +%Y-%m-%d | \
  xargs -I {} curl --progress-bar -f --no-include -L -H "X-Papertrail-Token: $PAPERTRAIL_APIKEY" https://papertrailapp.com/api/v1/archives/{}/download | \
  gzip -dc | grep production.log | cut -f 10- | \
  debride_rails_whitelist routes.txt - | sort -u > whitelist.txt

Three things are worth noticing. The date arithmetic uses the BSD date syntax of macOS, with -v-{}d, so the command as written is a macOS one. The Papertrail API key is passed in a header from an environment variable rather than on the command line. And the log data is piped into debride_rails_whitelist with a dash for the log argument, so the same helper works for a stream rather than a file.

This is the most interesting idea in the tool, and it is worth stating plainly: the analyser is static, but the whitelist it consults is dynamic, built from observed behaviour. That combination is what makes it more useful than a purely static pass, and it is also why a log window of 28 days is a meaningful parameter. A method that was never called in the last month may still be called occasionally, and it will look dead.

debride_rm and the case for starting large

debride_rm automatically removes dead code and can optionally run a command in between each removal. The command substitutes NAME and PATH with the name and path of the thing being removed. The documented invocation looks like this:

bash
debride_rm -C="git commit -m 'debride NAME in PATH'" . \
    --rails \
    --whitelist whitelist.txt \
    --exclude test \
    --exclude script \
    --exclude bin \
    --minimum 30

The README then spells out what that does: it runs with the Rails extensions on, treats anything named in whitelist.txt as called, excludes directories that should not be scanned or mutated, and excludes anything under 30 lines long.

That last exclusion is the interesting one, because it is a proxy for confidence. A short method is more likely to be a callback, a hook or a dynamically invoked entry point that the static pass cannot see, and a long method is more likely to be genuinely abandoned code. The stated strategy is to start large, at 40 or more, and work your way down.

There is one specific warning. debride_rm does not do terribly well with things like attr_accessor lists, so running it with --minimum 2 or more is wise. The README also describes the removal mode with the phrase remove all unused methods, and warns about it in capitals, which is a fair summary of the risk in a tool that edits your source.

Path handling borrowed from path_expander

debride uses path_expander, and the feature list calls out three behaviours that come from it. It is worth knowing them because they change how you invoke the tool on a large project.

The first is dir_arg, which expands a directory automatically. The second is the @file_of_args convention, which persists arguments in a file, so a long list of paths and options can be kept in one place and referenced from the command line. The third is -path_to_subtract, which ignores intersecting subsets of files and directories, so you can scan a tree while excluding a subdirectory without reorganising it.

That last one matters in practice. When you analyse a repository that contains vendored code, generated files, or a subtree with its own conventions, the subtract option avoids having to copy the tree elsewhere first.

The remaining feature in the list is the Rails flag, --rails, which is debride's own domain knowledge rather than a path_expander feature, and it is what keeps framework methods from showing up as dead code in a Rails application.

The plugin system extends the same idea to templates. debride-erb extends debride to analyse erb files via erubis, debride-haml parses Haml, debride-slim handles Slim, and debride-curly supports the Curly templating language. The common thread is that template files contain method calls that a Ruby parser on its own would never see, and each plugin teaches debride to look inside one of them.

Installing the gem and running the test suite

Installation is a gem install, and the README is unapologetic about the privileges involved:

bash
sudo gem install debride

The requirements are three gems, listed separately in the README: sexp_processor, ruby_parser and path_expander. The first two are what make the static analysis of Ruby source possible, and the third handles the path behaviours described earlier.

If you want to work on the project itself rather than just use it, the contributing section adds minitest and a direct invocation of the test file:

bash
sudo gem install minitest
ruby -Ilib:test test/test_debride.rb

The repository layout is the conventional Ruby one. The lib directory holds the library, bin holds the executables, test holds the test suite, and the top level carries a Rakefile, a Manifest.txt and a History.rdoc changelog. The README itself is README.rdoc rather than Markdown, and the documentation is generated with rdoc.

On activity, the repository is not archived and the last push was on 2026-04-20, with no GitHub releases published, so the gem version on rubygems.org is the version to reason about. The README carries the MIT licence text with copyright attributed to Ryan Davis, seattle.rb, although the repository's own licence field is not classified, so check the licence file in the tree if the distinction matters to your compliance process.

Editorial conclusion

Use debride when you want a report of methods with no visible callers in a Ruby or Rails codebase and you are prepared to build a whitelist from routes and production logs, since the tool is only as accurate as that whitelist. Do not point debride_rm at a codebase you do not understand, since it removes source files and the README itself warns about it and about attr_accessor lists, and start with a high --minimum value rather than a low one. Before your first run, check that the three dependencies are present, confirm you can run the test suite with ruby -Ilib:test test/test_debride.rb, and remember that the last push to this repository was on 2026-04-20, so the gem version you install may predate your Ruby.

Frequently asked questions

What does debride do in a Ruby codebase?

debride performs static analysis to find methods that might not be called anywhere, and it reports them grouped by class with the file and line of each suspect. The README notes that, as with any static analysis of a dynamic language, it cannot be 100% correct.

How do I install debride and what does it need?

The README gives sudo gem install debride, and lists three requirements: sexp_processor, ruby_parser and path_expander. To work on the project itself you also need minitest and run ruby -Ilib:test test/test_debride.rb.

How do I stop debride from reporting methods that are called indirectly?

You whitelist them, either by name or by regular expression delimited with forward slashes, and pass the file with --whitelist whitelist.txt. In a Rails app the README shows generating that whitelist from rake routes output and the production log with debride_rails_whitelist.

Is it safe to run debride_rm on a real codebase?

It removes source files and the README warns about it. The documented safe approach is to exclude directories such as test, script and bin, set a high --minimum value, start at 40 or more and work downwards, and remember that the tool does not do well with attr_accessor lists, so --minimum 2 or more is wise.

Official sources

  1. Issues
  2. Project website
  3. README
  4. seattlerb/debride on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/seattlerb-debride.svg)](https://hysenlabs.com/projects/seattlerb-debride)