How to debug single file with Rails environment loaded - ruby-on-rails

I've been learning Ruby and now Rails.
I know in VS Code you configure the debugger with the following config
{
"name": "Debug Ruby",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "${file}",
},
It works just like ruby xxx.rb and pauses at breakpoints.
But I want to be able to do the same for any file in my rails project. For example, I just wrote a model user.rb for my project and i want to test and debug some functions.I tried the following:
{
"name": "Rails run",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "${workspaceRoot}/bin/rails",
"args": [
"runner",
"${file}"
]
},
but this wont stop at the breakpoints. there's also rails server option but that's for running the whole app but i just want to test&debug one single piece of code.

I think it doesnt work because rdebug doesnt attach to any subprocesses that the runner spins up to run the script. You could try launching the debugger directly from the ruby file you want the runner to use. You'd need to add an attach use-case in the debugger options:
For example:
.vscode/launch.json:
{
"name" : "Attach to rdebug-ide",
"type": "Ruby",
"request": "attach",
"cwd": "${workspaceRoot}",
"remoteHost": "127.0.0.1",
"remotePort": "1234",
"remoteWorkspaceRoot": "${workspaceRoot}"
},
Than in xxx.rb add the following to the top of the file:
require 'ruby-debug-ide'
require 'resource-struct'
options = ResourceStruct::FlexStruct.new({
host: '127.0.0.1',
port: '1234'
})
### Anything above this line will get run twice
Debugger.debug_program(options) unless Debugger.started?
### Rest of code you want to debug
Next run rails r xxx.rb it displays something like:
Fast Debugger (ruby-debug-ide 0.7.3, debase 0.2.4.1, file filtering is supported) listens on 127.0.0.1:1234
Lastly attached your debugger.

Related

Configuring vimspector with ruby on rails app running passenger

My question is how do i get vimspector running with a ruby on rails app running passenger (I think)
I'm trying to set up vimspector with some ruby on rails projects I'm working on. Basically the problem is that vimspector doesn't stop at breakpoints in some apps. the apps are using passenger. In a very basic sample app vimspector works fine, but not in the ones where i actually need to debug.
Description:
when i call vimspector#Launch all the splits/windows come up, and a passenger application server gets launched. I don't work alone on some projects so i cannot really change this to another one.
I set some breakpoints and do actions that should stop at them but they run through like without a debugger. Also nothing except for threads running and the console output of the rails server shows up in the splits. In my processes 2 processes show up. Once the Passenger Ruby app and once a node process going to my cust_vscode-ruby directory which is needed for the debugger. The node process has the subprocess rdebug-ide and rdebug-ide has passenger start.
As vimspector works fine with the sample rails app, I don't think its a problem of the install or something like that.
I tried switching to attach but when configuring it for attach i get an endless loading without getting a timeout in the browser. the terminal window where i run rdebug-ide starts of without any repsonse, i launch vimspector and the server is being booted up. It stops at this however and never goes past booting Run rails server -h for more startup options. After which passenger normally starts up. With switching to attach mode only the rdebug controlled rails server shows up in my processes.
I think this should be possible as i'm usind ruby-debug-ide which is being used by RubyMine on which i could debug the apps running passenger just fine. I'm pretty sure that is has to do with passenger as calling it up in launch config leads to it escaping and using attach config leads to it blocking the rails server boot. But I don't know how to fix it.
.vimspector.json
same for both sample app and actual app :
{
"configurations": {
"rails": {
"adapter": "cust_vscode-ruby",
"default": true,
"configuration": {
"name": "Debug Rails server",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"pathToBundler": "/Users/username/.rvm/rubies/ruby-version/bin/bundler",
"pathToRDebugIDE": "/Users/username/.rvm/gems/ruby-version/gems/ruby-debug-ide-0.7.3",
"program": "${workspaceRoot}/bin/rails",
"args": [
"server"
]
}
}
}
}
vimspector configuration output
Vimspector Debug Info
--------------------------------------------------------------------------------
ConnectionType: job
Adapter:
--------------------------------------------------------------------------------
{
"command": [
"node",
"/Users/username/.vim/plugged/vimspector/gadgets/macos/cust_vscode-ruby/dist/debugger/main.js"
],
"configuration": {
"cwd": "/Users/username/Folder/app-name",
"showDebugOutput": false,
"trace": false
},
"name": "vscode-ruby-debug",
"env": {},
"cwd": "/Users/username/Folder/app-name"
}
--------------------------------------------------------------------------------
Configuration:
--------------------------------------------------------------------------------
{
"adapter": "cust_vscode-ruby",
"default": true,
"configuration": {
"name": "Debug Rails server",
"type": "Ruby",
"request": "launch",
"cwd": "/Users/username/Folder/app-name",
"pathToBundler": "/Users/username/.rvm/rubies/ruby-version/bin/bundler",
"pathToRDebugIDE": "/Users/username/.rvm/gems/ruby-version/gems/ruby-debug-ide-0.7.3",
"program": "/Users/username/Folder/app-name/bin/rails",
"args": [
"server"
]
}
}
--------------------------------------------------------------------------------
API Prefix:
Launch/Init: True / True
Workspace Root: /Users/username/Folder/app-name
Launch Config:
--------------------------------------------------------------------------------
{
"cwd": "/Users/username/Folder/app-name",
"showDebugOutput": false,
"trace": false,
"name": "Debug Rails server",
"type": "Ruby",
"request": "launch",
"pathToBundler": "/Users/username/.rvm/rubies/ruby-version/bin/bundler",
"pathToRDebugIDE": "/Users/username/.rvm/gems/ruby-version/gems/ruby-debug-ide-0.7.3",
"program": "/Users/username/Folder/app-name/bin/rails",
"args": [
"server"
]
}
--------------------------------------------------------------------------------
Server Capabilities:
--------------------------------------------------------------------------------
{
"supportsConfigurationDoneRequest": true,
"supportsConditionalBreakpoints": true
}
--------------------------------------------------------------------------------
Line Breakpoints:
--------------------------------------------------------------------------------
{
"/Users/username/Folder/app-name/app/controllers/.../somethings_controller.rb": [
{
"state": "ENABLED",
"line": 83,
"options": {},
"sign_id": 1,
"server_bp": {
"verified": true,
"line": 83,
"id": 1
}
}
]
}
--------------------------------------------------------------------------------
Func Breakpoints:
--------------------------------------------------------------------------------
[]
--------------------------------------------------------------------------------
Ex Breakpoints:
None
so i got it to work not with passenger itself.
i changed my vimspector config to the following, switching up some paths to the used binaries by trial and error (i think the one that matters is calling the rails binary in the project root). The important thing is to call in the args server -u puma. Make sure to write each part of the command as a single argument. puma being the default rails server (i found it to be in my sample app), so this gets picked up by rdebug-ide and debase.
{
"configurations": {
"rails": {
"adapter": "cust_vscode-ruby",
"default": true,
"configuration": {
"name": "Debug Rails server",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"pathToBundler": "/Users/username/.rvm/rubies/ruby-RUBYVERSION/bin/bundler",
"pathToRDebugIDE": "/Users/username/.rvm/gems/ruby-RUBYVERSION/gems/ruby-debug-ide-RUBYDEBUGIDEVERSION",
"program": "${workspaceRoot}/bin/rails",
"args": [
"server", "-u", "puma"
]
}
}
}
}
There are some options I found for using passenger, it probably has to do something with writing the config as attach.
What seemed closest (but it doesn't work) to the answer seemed to copy the rubymine config that calls:
/bin/bash -c "~/.rvm/bin/rvm _RUBYVERSION_ do ~/.rvm/rubies/ruby-_RUBYVERSION_/bin/ruby ~/.rvm/gems/ruby-_VERSION_/gems/ruby-debug-ide-_RUBYDEBUG-IDEVERSION_/bin/rdebug-ide --key-value --disable-int-handler --evaluation-timeout 10 --evaluation-control --time-limit 100 --memory-limit 0 --rubymine-protocol-extensions --port 42371 --host 0.0.0.0 --dispatcher-port 38403 -- ~/Folder/project/bin/rails server -b 0.0.0.0 -p 3000 -e development"
I think a point where it could be failing, and why it's not working is that passenger needs to be set to allow debugging (PassengerDebugger on), although i might just be confusing everything here. However this passenger option is reserved for the Enterprise version (https://www.phusionpassenger.com/library/admin/apache/debugging_console/ruby/).
Where this left me off was i launched this debug config but couldn't connect to the socket. Maybe this is to some security measure i made to tight for my own good on my system or more likely a fault in the config.
I think it's possible to attach to the passenger server properly somehow some ideas could maybe be found here but i didn't get anywhere with them.
https://mondotondo.com/2012/08/23/how-to-remotely-debug-rails-in-apache-passenger-rubymine/
How can I get ruby-debug-ide to work?
If you are struggeling like me with this, hang in there you will get it some day!

How do I add environment variables to launch.json in VSCode for a rails

I am using ruby-debug-ide and debase for debugging in vs code in that when i start debugging by default server is started in development environment, how to debug in a different environment like test/qa? how to configure this launch.json
My launch.json file
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Rails server",
"type": "Ruby",
"request": "launch",
"program": "${workspaceRoot}/bin/rails",
"args": [
"server"
],
"showDebuggerOutput": true,
"env": {
"PATH": "/Users/giri.shankar/.rvm/gems/ruby-2.6.3#codeforkout/bin:/Users/giri.shankar/.rvm/gems/ruby-2.6.3#global/bin:/Users/giri.shankar/.rvm/rubies/ruby-2.6.3/bin:/Users/giri.shankar/.rvm/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
"GEM_HOME": "/Users/giri.shankar/.rvm/gems/ruby-2.6.3#codeforkout",
"GEM_PATH": "/Users/giri.shankar/.rvm/gems/ruby-2.6.3#codeforkout:/Users/giri.shankar/.rvm/gems/ruby-2.6.3#global",
"RUBY_VERSION": "ruby-2.6.3"
}
}
]
}
For time being i changed the default environment to qa by adding the below line in boot.rb, so now whenever i run rails s qa environment is booted by default
ENV["RACK_ENV"] = "qa"
You just have to add -e test to the rails server command:
{
...
"args": [
"server -e test"
]
}

How to autorun webpack-dev-server when starting debugging RoR session?

Since Rails 5.1, It's possible to run rails server next to webpack-dev-server. I have configured debugger in launch.json to run rails server. When I start rails server throught vscode, I want it to automatically run ./bin/webpack-dev-server on background for autocompile javascript changes as another process, but I can't figure out how to achieve this.
I have created task in tasks.json to run webpacker but I can't figure out how to combine it with launch.json.
Here is my launch.json:
{
"version": "0.2.0",
"configurations": [
{
"preLaunchTask": "webpack-dev-server",
"name": "Rails server",
"type": "Ruby",
"request": "launch",
"program": "${workspaceRoot}/bin/rails",
"args": [
"server"
]
}
]
}
And here is tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "webpack-dev-server",
"type": "shell",
"command": "${workspaceRoot}/webpack-dev-server",
"isBackground": true,
}
]
}
When I run debugging and task separately, It's working as expected, but run then automatically when starting debugging not working.
Things I've tried:
run webpack-dev-server with "preLaunchTask" - problem with this is that "preLaunchTask" waits until webpack-dev-server stop running and after that runs debugging. I need them to run simultaneously next to each other.
Specify webpack-dev-server as another launch configuration and combine these two launches through compond in launch.json - this isn't working, because vscode needs to specify type of launch and shell isn't supported
run task with & at the end to suppress waiting for process finish - not working
If anybody solved this or know how to achieve running both processes simultaneously through one click, It would be helpful to share this knowledge.
Thank you.
So I found the solution thanks to https://stackoverflow.com/a/54017304/3442759.
In tasks.json there needs to be specified problemMatcher even when it's not used. Without problemMatcher specified, task will not run in the background even when isBackground is set to true.
I've created gist with setup steps. https://gist.github.com/tomkra/b1d67a7ae96af34cba78935f15b755b6
So final configuration is:
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Rails server",
"type": "Ruby",
"request": "launch",
"program": "${workspaceRoot}/bin/rails",
"args": [
"server"
],
"preLaunchTask": "webpack-dev-server"
}
]
}
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "webpack-dev-server",
"type": "shell",
"isBackground": true,
"command": "./bin/webpack-dev-server",
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": ".",
}
}
]
}
]
}

How to get RSpec working with debugger IDE in VSCode

Despite having spent about the last three hours trying to get this working I cannot for the life of my get RSpec to work with the debugger on VSCode. I can get Rspec to run in the terminal on VSCode but that doesn't give me any of the IDE's debugging functionality for inspecting and stepping.
This is what I've got in my launch.json file:
{
"version": "0.2.0",
"configurations": [
{
"name": "Run RSpec - all",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "/Users/my-home-dir/.rvm/gems/ruby-2.6.5#project-gemset-name/wrappers/rspec",
"pathToRDebugIDE": "/Users/my-home-dir/.rvm/gems/ruby-2.6.5#project-gemset-name/gems/ruby-debug-ide-0.7.2",
"args": [
"--pattern",
"${workspaceRoot}/spec/**/*_rspec.rb"
]
}
]
}
And my gemfile contains:
gem 'ruby-debug-ide', '~>0.7.2'
gem 'debase', '~>0.2.4.1'
I've got a feeling that the errors may be coming about due to in incompatibility between RVM and VSCode but I've no idea how to unwind that issue.
This was all setup as per the Microsoft recipe here: https://github.com/Microsoft/vscode-recipes/tree/master/debugging-Ruby-on-Rails
Every time I run this setup I get the following error in the debug console:
Debugger terminal error: Process failed: spawn rdebug-ide ENOENT
Is there any way to get this to run? Also is there any way to get it to use guard so that it runs automatically?
I got it working. Unfortunately, I don't use RVM. So, my solution involves rbenv. I'm sharing it here anyway in case it helps you, or someone else.
which rspec pointed me to the shim (shell script) that rbenv uses to execute the version of rspec installed under the current version of Ruby. When I configured launch.json with that path rdebug-ide didn't like the shim. I assume it was expecting the executable.
So, I ran rbenv which rspec and got the actual path to the executable. Once I plugged that into launch.json it worked fine. Of course, if I change the version of Ruby I'm running, I'll have to update the file to point to the version of RSpec installed under the new version of Ruby.
Given the prevalence of Ruby version managers among the community, I would think ruby-debug-ide would have considered this. Perhaps it's worth an issue on their GitHub: https://github.com/ruby-debug/ruby-debug-ide.
I added a preLaunchTask to launch rdebug-ide server then looked for a pattern before attaching the debugger.
I used the focus flag for controlling which tests are run or not. Am able to set breakpoints in main script files as well as *_spec.rb files.
Gemfile:
group :test, :development do
gem "ruby-debug-ide", "~> 0.7.2"
gem "debase", "~> 0.2.4"
end
launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for rdebug-ide rspec",
"type": "Ruby",
"request": "attach",
"remoteHost": "127.0.0.1",
"remotePort": "1234",
"preLaunchTask": "run-rdebug-for-rspec",
"remoteWorkspaceRoot": "${workspaceRoot}",
"cwd": "${workspaceFolder}"
}
]
}
tasks.json
{
"version": "2.0.0",
"tasks": [{
"label": "run-rdebug-for-rspec",
"command": "bundle",
// could update these are you see fit
// my tests were located in /spec folder
"args": [
"exec","rdebug-ide",
"--host","0.0.0.0",
"--port","1234",
"--dispatcher-port","26162",
// needed to specify the full path of bundle
// can be found by `which bundle`
"--", "/usr/local/bin/bundle", "exec", "rspec", "spec/"
],
"type": "shell",
"isBackground": true,
// this will look for a pattern to attach to rdebug server
// attaching to the server will start running the tests
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
// once server is up and running it'll display something like:
// Fast Debugger (ruby-debug-ide 0.7.2, debase 0.2.4.1, file filtering is supported) listens on 0.0.0.0:1234
"beginsPattern": "^Fast Debugger.*1234$",
"endsPattern": ".",
}
}
],
// open up a new task window everytime
// if set to default `shared` then previous task window needs to be closed
// otherwise, was having issues getting patternMatcher to work
// and for rdebug to attach within a shared terminal on successive runs, or restarts.
"presentation": {
"panel": "new"
}
}]
}
While the answer above may work, there will be problems as soon as you upgrade your ruby version because the paths are hard coded.
Here is a less brittle approach that should be able to survive a version upgrade without any problem.
I'm on ruby 3.0.3, managed by rvm on mac osx.
Gemfile includes:
group :development do
gem 'ruby-debug-ide'
gem 'debase', "~> 0.2.5.beta2"
end
(the stable version of debase didn't support ruby v3, hence the beta)
Launch config use the GEM_HOME environment variable to specify the rspec binary (vscode default configuration puts this in workspace root for some reason):
{
"name": "RSpec - all",
"type": "Ruby",
"request": "launch",
"program": "${env:GEM_HOME}/bin/rspec",
"args": [
"-I",
"${workspaceRoot}"
]
}

can't attached my ruby on rails project in vs code

I would like to debug in Visual Studio Code my ruby on rails project, with attach debugging, but my Visual Studio Code debugger doesn't stop at breakpoints.
My ruby version:2.4.4
My rails version:5.0.1
My Visual Studio Code version :1.35.1
I did install
ruby extension for Visual Studio Code
gem install debase
gem install ruby-debug-ide
and my configuration in launch.json is
{
"name": "Debug Attach",
"type": "Ruby",
"request": "attach",
"cwd": "${workspaceRoot}",
"remoteWorkspaceRoot": "bin/rails",
"remoteHost": "127.0.0.1",
"remotePort": "3000",
"showDebuggerOutput": true
}
in debug console i get
"Debugger error: Client: Error: write EPIPE"
Thank you :)
Please try to add paths of bundle and ruby-debug-ide in your launch.json :
{
"name": "Debug Attach",
"type": "Ruby",
"request": "attach",
"cwd": "${workspaceRoot}",
"useBundler": true,
"pathToBundler": "/path/to/rubygem/wrappers/bundle",
"pathToRDebugIDE": "/path/to/rubygem/gems/ruby-debug-ide-x.x.x/bin/rdebug-ide",
"remoteWorkspaceRoot": "bin/rails",
"remoteHost": "127.0.0.1",
"remotePort": "3000",
"showDebuggerOutput": true
}
I hope that helpful

Resources