Published 2023-01-31.
Last modified 2023-11-04.
Time to read: 3 minutes.
ruby
collection.
Rackup provides a command-line interface for running
rack
-compatible web applications.
Two well-known application servers that adhere to the rack
standard are
Ruby on Rails and
Sinatra.
The rack
gem is a
dependency
of the rackup
gem.
To debug rack-compatible webapps in Visual Studio Code,
you need to somehow launch the Ruby debugger on the rackup
gem in such a way that all the other dependencies (also gems) are loaded.
All the advice I could find on the Interwebs discussed a brittle approach,
which would break every time a different version of the rackup
gem was require
d.
This article discusses how to use a manually created binstub
for reliable debugging.
What is Rackup?
The rackup
command is a short bash script that loads and executes a
gem of the same name.
The bash script is actually packaged within the gem and is deployed when the gem is installed.
#!/usr/bin/env bash set -e [ -n "$RBENV_DEBUG" ] && set -x program="${0##*/}" if [ "$program" = "ruby" ]; then for arg; do case "$arg" in -e* | -- ) break ;; */* ) if [ -f "$arg" ]; then export RBENV_DIR="${arg%/*}" break fi ;; esac done fi export RBENV_ROOT="/home/mslinn/.rbenv" exec "/usr/lib/rbenv/libexec/rbenv" exec "$program" "$@"
This is the rackup
help message:
$ rackup -h Usage: rackup [ruby options] [rack options] [rackup config]
Ruby options: -e, --eval LINE evaluate a LINE of code -d, --debug set debugging flags (set $DEBUG to true) -w, --warn turn warnings on for your script -q, --quiet turn off logging -I, --include PATH specify $LOAD_PATH (may be used more than once) -r, --require LIBRARY require the library, before executing your script
Rack options: -b BUILDER_LINE, evaluate a BUILDER_LINE of code as a builder script --builder -s, --server SERVER serve using SERVER (thin/puma/webrick) -o, --host HOST listen on HOST (default: localhost) -p, --port PORT use PORT (default: 9292) -O NAME[=VALUE], pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run '$HOME/.rbenv/versions/3.1.0/bin/rackup -s SERVER -h' to get a list of options for SERVER --option -E, --env ENVIRONMENT use ENVIRONMENT for defaults (default: development) -D, --daemonize run daemonized in the background -P, --pid FILE file to store PID
Profiling options: --heap HEAPFILE Build the application, then dump the heap to HEAPFILE --profile PROFILE Dump CPU or Memory profile to PROFILE (defaults to a tempfile) --profile-mode MODE Profile mode (cpu|wall|object)
Common options: -h, -?, --help Show this message --version Show version
Server-specific options for Rack::Handler::Puma: -O Threads=MIN:MAX min:max threads to use (default 0:16) -O Verbose Don’t report each request (default: false)
Gem Directory Tree
Gems are either installed system-wide or in user-specific locations.
If you are using
rbenv
to work with Ruby (and you should),
the directory that your gems are installed to is
$HOME/
.
The various versions of each gem reside in sibling directories.
The project I was working on when I ran the following command used Ruby version 3.1.0,
and the rackup
version 1.0.0 gem used by that project was installed at:
$ bundle info rackup
/home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rackup-1.0.0
The entry point is
$HOME/.rbenv/versions/3.1.0/
The rackup
command was installed to:
$ which rackup
/home/mslinn/.rbenv/shims/rackup
The following is the brittle and out-of-date Visual Studio Code launch configuration that you find on the Interwebs.
-
It specifies the out-of-date
rebornix.Ruby
Visual Studio Code extension, which should not be used anymore. -
To amplify what I said before, this launch configuration is brittle.
If you change the Ruby version or the version of the
rackup
gem, theprogram
path will also need to change, or the launch configuration will stop working.
I highlighted the brittle part:
{
"cwd": "${workspaceRoot}",
"name": "Debug rackup application",
"pathToBundler": "${userHome}/.rbenv/shims/bundle",
"pathToRDebugIDE": "${userHome}/.rbenv/shims/rdebug-ide",
"program": "${userHome}/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rackup-1.0.0/lib/rackup.rb",
"request": "launch",
"showDebuggerOutput": true,
"type": "Ruby",
"useBundler": true,
},
VSCode Debugging With Binstubs
We saw earlier that the rackup
command is a Bash script,
and it launches the gem
of the same name.
However, Ruby debuggers are unable to work with Bash scripts.
Binstubs to the rescue! ... well, actually, manually created binstubs to the rescue.
I do not know why the following attempt to automagically create a binstub fails — as we have seen,
rackup
does indeed have an associated bash script.
$ bundle binstubs rackup rackup has no executables, but you may want one from a gem it depends on. rack has: rackup
However, there is a solution:
manually creating a binstub for the rackup
gem.
I wrote a binstub
for rackup
;
save it as bin/rackup
in the directory of your Jekyll project.
#!/usr/bin/env ruby
# Prepares the $LOAD_PATH by adding to it lib directories of all gems in the # project's bundle: require 'bundler/setup'
load Gem.bin_path('rack', 'rackup')
The last line above could be modified to load other gems.
The following is a Visual Studio Code launch configuration for Rackup-compatible webapps using the manually created binstub.
It assumes that rbenv
was used to install Ruby.
Because bundler
is used to load rackup
,
all the dependencies mentioned in the Gemfile
are also loaded before debugging.
{
"debugPort": "0",
"name": "Debug rackup application",
"request": "launch",
"script": "${workspaceRoot}/bin/rackup",
"type": "rdbg",
},
Easy!
To learn more about Ruby LSP and rdebug
, please read
Essential Visual Studio Code Extensions for Ruby.
About the Author
I, Mike Slinn, have been working with Ruby for a long time now. Back in 2005, I was the product marketing manager at CodeGear (the company was formerly known as Borland) for their 3rd Rail IDE. 3rd Rail supported Ruby and Ruby on Rails at launch.
In 2006, I co-chaired the Silicon Valley Ruby Conference on behalf of the SD Forum in Silicon Valley. As you can see, I have the t-shirt. I was the sole chairman of the 2007 Silicon Valley Ruby Conference.
Several court cases have come my way over the years in my capacity as a software expert witness. The court cases featured questions about IP misappropriation for Ruby on Rails programs. You can read about my experience as a software expert if that interests you.
I currently enjoy writing Jekyll plugins in Ruby for this website and others, as well as Ruby utilities.