Spoom
Useful tools for Sorbet projects.
Spoom provides a CLI and a Ruby API to inspect Sorbet projects, improve typing coverage, translate signatures, query Sorbet LSP, and find dead code.
Installation
Add Spoom to your application's Gemfile:
gem "spoom"Then install it:
bundle installOr install it directly:
gem install spoomSpoom requires Ruby 3.3 or newer.
Command line interface
Run spoom help or spoom help COMMAND to list all available commands.
Typechecking errors
spoom srb tc runs srb tc and can sort, filter, format, and export errors.
List errors sorted by location:
spoom srb tc --sort locList errors sorted by error code:
spoom srb tc --sort codeList only errors with a specific code:
spoom srb tc --code 7004Limit the number of displayed errors:
spoom srb tc --limit 10Options can be combined:
spoom srb tc --sort code --code 7004 --limit 10Remove duplicated error lines:
spoom srb tc --uniqFormat each error line:
spoom srb tc --format "%C - %F:%L: %M"Format tokens:
-
%C: error code -
%F: file path -
%L: line number -
%M: error message
Hide the final Errors: X count:
spoom srb tc --no-countList only errors from specific files or directories:
spoom srb tc file1.rb path1/ path2/Write errors to a JUnit XML file:
spoom srb tc --junit-output-path junit.xmlPass extra options to Sorbet:
spoom srb tc --sorbet-options="--typed=true"Typing coverage
spoom srb coverage collects Sorbet coverage metrics and can generate an HTML report from Sorbet and Git data.
Show a coverage snapshot:
spoom srb coverageSave a snapshot under spoom_data/:
spoom srb coverage --saveSave a snapshot under a specific directory:
spoom srb coverage --save my_data/Show typing coverage evolution based on Git history:
spoom srb coverage timelineReplay a specific date range:
spoom srb coverage timeline --from YYYY-MM-DD --to YYYY-MM-DDSave timeline snapshots under spoom_data/:
spoom srb coverage timeline --saveSave timeline snapshots under a specific directory:
spoom srb coverage timeline --save my_data/Run bundle install before collecting each timeline snapshot:
spoom srb coverage timeline --bundle-installGenerate an HTML coverage report from saved snapshots:
spoom srb coverage reportThe report is generated at spoom_report.html by default.
Generate a report from a custom data directory:
spoom srb coverage report --data my_data/Change the generated report path:
spoom srb coverage report --file coverage.htmlChange report colors:
spoom srb coverage report \
--color-true "#648ffe" \
--color-false "#fe6002" \
--color-ignore "#feb000" \
--color-strict "#795ef0" \
--color-strong "#6444f1"Open the HTML coverage report:
spoom srb coverage openOpen a report at a custom path:
spoom srb coverage open coverage.htmlSorbet sigils
spoom srb bump changes # typed: sigils when the change does not introduce typechecking errors.
Bump files from typed: false to typed: true:
spoom srb bump --from false --to trueForce the change without typechecking:
spoom srb bump --from false --to true --forceBump only files listed in a file, one path per line:
spoom srb bump --from false --to true --only list.txtCheck which files can be bumped without applying changes:
spoom srb bump --from false --to true --dryThis command exits with a non-zero status when files can be bumped, which is useful in CI.
Use a custom Sorbet executable:
spoom srb bump --from false --to true --sorbet /path/to/sorbet/binCount typechecking errors if all files were bumped:
spoom srb bump --from false --to true --count-errors --drySignatures and type assertions
spoom srb sigs translates signatures between Sorbet RBI syntax and RBS comments.
Translate signatures from RBI to RBS comments:
spoom srb sigs translateTranslate signatures from RBS comments to RBI:
spoom srb sigs translate --from rbs --to rbi path/to/file.rbStrip Sorbet signatures from files:
spoom srb sigs strip path/to/file.rbExport gem signatures to an RBI file:
spoom srb sigs exportCheck that the exported RBI file is up to date:
spoom srb sigs export --check-syncspoom srb assertions translates Sorbet type assertions to RBS comments:
spoom srb assertions translate path/to/file.rbSorbet LSP
spoom srb lsp sends requests to Sorbet LSP.
This command group is experimental.
Find symbols matching Foo:
spoom srb lsp find FooList symbols in a file:
spoom srb lsp symbols file.rbList definitions for a code location:
spoom srb lsp defs file.rb 10 4List references for a code location:
spoom srb lsp refs file.rb 10 4Show hover information for a code location:
spoom srb lsp hover file.rb 10 4Show signature information for a code location:
spoom srb lsp sigs file.rb 10 4Show type information for a code location:
spoom srb lsp types file.rb 10 4Sorbet code metrics
spoom srb metrics collects metrics about Sorbet usage in Ruby files.
Show metrics for the current project:
spoom srb metricsShow metrics for specific files or directories:
spoom srb metrics lib/ test/foo_test.rbDump raw metric keys and values:
spoom srb metrics --dumpDead code
spoom deadcode indexes a project and reports definitions that do not appear to be referenced.
Analyze the current project:
spoom deadcodeAnalyze specific paths:
spoom deadcode lib/ app/models/Show files, loaded plugins, definitions, or references used during analysis:
spoom deadcode --show-files
spoom deadcode --show-plugins
spoom deadcode --show-defs
spoom deadcode --show-refsRemove a reported dead code candidate:
spoom deadcode remove path/to/file.rb:42:18-47:23Ruby API
Parsing Sorbet config
Parse a Sorbet config file:
config = Spoom::Sorbet::Config.parse_file("sorbet/config")
puts config.pathsParse a Sorbet config string:
config = Spoom::Sorbet::Config.parse_string(<<~CONFIG)
a
--file=b
--ignore=c
CONFIG
puts config.paths
puts config.ignoreList all files typechecked by Sorbet:
config = Spoom::Sorbet::Config.parse_file("sorbet/config")
puts Spoom::Context.new(".").srb_files(with_config: config)Parsing Sorbet metrics
Display metrics collected during typechecking:
puts Spoom::Context.new(".").srb_metrics(capture_err: false)Interacting with LSP
Create an LSP client:
client = Spoom::LSP::Client.new(
Spoom::Sorbet::BIN_PATH,
"--lsp",
"--enable-all-experimental-lsp-features",
"--disable-watchman",
)
client.open(".")Find symbols matching a string:
puts client.symbols("Foo")Find symbols in a file:
puts client.document_symbols("file://path/to/my/file.rb")Backtrace filtering
Spoom provides a Minitest backtrace filter that removes Sorbet frames from test failures.
Enable it in your test helper:
# test/test_helper.rb
require "spoom/backtrace_filter/minitest"
Minitest.backtrace_filter = Spoom::BacktraceFilter::Minitest.newDevelopment
After checking out the repo, install dependencies:
bin/setupRun the tests:
bin/testRun an interactive console:
bin/consoleRun the full local sanity check before pushing:
bin/sanityInstall this gem locally:
bundle exec rake installReleasing
Bump the gem version
- Update the version number in
lib/spoom/version.rb - Run
bundle installto update the version number inGemfile.lock - Commit the change with
Bump version to vx.y.z - Push the change directly to
mainor open a pull request
Create a new tag
- Create a tag with the new version number:
git tag vx.y.z - Push the tag:
git push origin vx.y.z
Publish the release
The release workflow publishes new gem versions to RubyGems through Trusted Publishing.
A member of the Ruby and Rails Infrastructure team at Shopify must approve the workflow before it runs. Once approved, it publishes the gem and creates a GitHub release.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/spoom.
This project is intended to be a safe, welcoming space for collaboration. Contributors are expected to follow the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in Spoom's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the code of conduct.
