![Debt Ceiling Chat](https://badges.gitter.im/Join Chat.svg)
Main goal is to track and/or enforce a technical debt ceiling and tech debt reduction deadlines for your Ruby project, however you choose to define and quantify technical debt. Uses a configurable combination of static analysis and/or manual assignment/recognition from explicit source code references as part of your application's test suite, or from CLI.
Travis tests are running on MRI 2.1.1, 2.2.5, and 2.3.1, JRuby (1.9 mode and JRuby 9120), and Rubinius (3.2.0) Versions up through 0.4.0 supported Ruby 1.9.3, but JSON gem now requires ruby 2.0 or later, so v0.5.0 and up are Ruby 2+ only
debt_ceiling todo
--details
flag to include author/date info, or set todo_author_date_info
to true in config to always show.report_todos
to true in config.#TECH DEBT +100
or custom word/phraseDebtCeiling::ArcheologicalDig
object if called via DebtCeiling.dig(path)
, which has an array of hashes available via #results
method representing the individual commit results at the specified level of detail per commit.ENV['REDIS_HOST']
and ENV['REDIS_PORT']
or uses defaults of localhost and 6379) or by creating git notes associated with each commit if not. Also supports Mercurial in theory, but haven't tested it, and requires Redis for Mercurial since no git notes option there.debt_ceiling dig
, defaulting to current directory.To integrate in a test suite, set a value for debt_ceiling
, max_debt_per_module
and/or reduction_target
and reduction_date
in your configuration and call DebtCeiling.audit
from your test helper as an additional test, or drop the call and/or configuration directly in your spec helper:
require 'debt_ceiling'
config.after(:all) do
DebtCeiling.configure do |c|
c.whitelist = %w(app lib)
c.max_debt_per_module = 150
c.debt_ceiling = 250
end
DebtCeiling.audit(preconfigured: true)
end
audit
defaults to '.' as root directory, since specs are usually run from root, but you can pass it a relative path as an argument, i.e. DebtCeiling.audit('./lib')
It will exit with a non-zero failure, failing the test suite, if you exceed your ceiling(s) or miss your target and print the failure and reason for failure. If you wish debt ceiling to run and print the failures, but not fail the test suite when thresholds are exceeded or targets are missed, call the audit method with the warn_only
option, i.e.: DebtCeiling.audit(warn_only: true)
These features are largely demonstrated/discussed in examples/.debt_ceiling.rb.example or below snippet which demonstrates configuring debt ceiling around a team or maintainer's agreed ideas about how to quantify debt automatically and/or manually in the project source code.
Additional customization is supported via two method hooks in the debt class, which DebtCeiling will load from a provided extension_path in the main config file, which should look like the example file
You can configure/customize the debt calculated using a few simple commands in a .debt_ceiling.rb file in the project's home directory:
DebtCeiling.configure do |c|
#exceeding this will fail a test, if you run debt_ceiling binary/calculate method from test suite
c.debt_ceiling = 250
#exceeding this target will fail after the reduction date (parsed by Chronic)
c.reduction_target = 100
c.reduction_date = 'Jan 1 2016'
#set the multipliers per line of code in a file with each letter grade, these are the current defaults
c.grade_points = { a: 0, b: 10, c: 20, d: 40, f: 100 }
#load custom debt calculations (see examples/custom_debt.rb) from this path
c.extension_path = "./custom_debt.rb"
#below two both use same mechanic, todo just assumes capital TODO as string, cost_per_todo defaults to 0
c.cost_per_todo = 50
c.deprecated_reference_pairs = { 'DEPRECATED_API' => 20}
#manually assign debt to code sections with these or with default "TECH DEBT", as a comment like #TECH DEBT +50
c.manual_callouts += ["REFACTOR THIS", "HORRIBLE HACK"]
#only count debt scores for files/folders matching these strings (converted to regexes)
c.whitelist = %w(app lib)
#or
#exclude debt scores for files/folders matching these strings (commented as mutually exclusive)
#c.blacklist = %w(config schema routes)
end
As mentioned/linked above, additional customization is supported via a custom_debt.rb file which may define one or both of two methods DebtCeiling will call if defined when calculating debt for each module scanned (if it passes the whitelist/blacklist stage of filtering).
As shown in example file, set a path for extension_path
pointing to a file defining DebtCeiling::CustomDebt
like the one in examples directory, and define its methods for your own additional calculation per file.
rubocop/cane integration debt for style violations
multipliers for important files
command line options to configure options per run/without a .debt_ceiling.rb
file (could be done with ENVied gem perhaps, or commander or one of these
visualization/history of debt would be nice, but unclear how to best support... one possibility is running it against each commit in a repo, and using git-notes to add score data (and some metadata perhaps?) to store it for comparing/graphing, and for comparing branches etc. optionally configured could do this for every commit that doesn't already have a note attached, or for which the note's metadata/version is out of sync with current definitions.
optionally include/integrate with one of these JS analysis libraries, or another if anyone had another suggestion: plato jsprime doctorjs Could also create a plugin architecture and do JS that way, and allow any other language to add plugin handling so it could be a multi-language standard tool.
debt_ceiling
is MIT licensed. See the accompanying file for
the full text.