debugger-xml 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/rdebug-ide +12 -9
  4. data/bin/rdebug-vim +30 -13
  5. data/debugger-xml.gemspec +7 -3
  6. data/lib/byebug/commands/frame.rb +16 -0
  7. data/lib/byebug/commands/help.rb +13 -0
  8. data/lib/byebug/commands/info.rb +13 -0
  9. data/lib/byebug/commands/inspect.rb +30 -0
  10. data/lib/byebug/commands/kill.rb +13 -0
  11. data/lib/byebug/commands/start.rb +25 -0
  12. data/lib/byebug/commands/threads.rb +10 -0
  13. data/lib/byebug/commands/trace.rb +13 -0
  14. data/lib/byebug/commands/variables.rb +54 -0
  15. data/lib/byebug/context_xml.rb +29 -0
  16. data/lib/byebug/printers/texts/xml.yml +122 -0
  17. data/lib/byebug/printers/xml.rb +197 -0
  18. data/lib/debugger/{xml/extensions/processor.rb → command_processor.rb} +0 -0
  19. data/lib/debugger/{xml/extensions/commands → commands}/edit.rb +0 -0
  20. data/lib/debugger/{xml/extensions/commands → commands}/frame.rb +0 -1
  21. data/lib/debugger/{xml/extensions/commands → commands}/help.rb +0 -0
  22. data/lib/debugger/{xml/extensions/commands → commands}/info.rb +0 -0
  23. data/lib/debugger/{xml/extensions/commands → commands}/inspect.rb +0 -0
  24. data/lib/debugger/{xml/extensions/commands → commands}/irb.rb +0 -0
  25. data/lib/debugger/{xml/extensions/commands → commands}/kill.rb +0 -0
  26. data/lib/debugger/commands/start.rb +25 -0
  27. data/lib/debugger/{xml/extensions/commands → commands}/threads.rb +0 -0
  28. data/lib/debugger/{xml/extensions/commands → commands}/tmate.rb +0 -0
  29. data/lib/debugger/{xml/extensions/commands → commands}/trace.rb +0 -0
  30. data/lib/debugger/{xml/extensions/commands → commands}/variables.rb +14 -0
  31. data/lib/debugger_xml.rb +91 -0
  32. data/lib/debugger_xml/byebug_proxy.rb +108 -0
  33. data/lib/debugger_xml/debugger_proxy.rb +115 -0
  34. data/lib/debugger_xml/fake_logger.rb +9 -0
  35. data/lib/debugger_xml/ide/control_command_processor.rb +69 -0
  36. data/lib/debugger_xml/ide/interface.rb +74 -0
  37. data/lib/debugger_xml/ide/logger.rb +9 -0
  38. data/lib/debugger_xml/ide/processor.rb +118 -0
  39. data/lib/debugger_xml/multiprocess/monkey.rb +47 -0
  40. data/lib/debugger_xml/multiprocess/pre_child.rb +79 -0
  41. data/lib/{debugger/xml → debugger_xml}/multiprocess/starter.rb +2 -2
  42. data/lib/debugger_xml/version.rb +3 -0
  43. data/lib/debugger_xml/vim/control_command_processor.rb +23 -0
  44. data/lib/debugger_xml/vim/interface.rb +46 -0
  45. data/lib/debugger_xml/vim/logger.rb +16 -0
  46. data/lib/debugger_xml/vim/notification.rb +35 -0
  47. data/lib/debugger_xml/vim/processor.rb +20 -0
  48. data/test/breakpoints_test.rb +0 -1
  49. data/test/ide/control_command_processor_test.rb +18 -13
  50. data/test/ide/processor_test.rb +11 -25
  51. data/test/printers/xml_test.rb +1 -0
  52. data/test/test_helper.rb +12 -3
  53. data/test/variables_test.rb +0 -1
  54. data/test/vim/control_command_processor_test.rb +4 -5
  55. data/test/vim/interface_test.rb +6 -6
  56. data/test/vim/notification_test.rb +3 -3
  57. data/test/vim/processor_test.rb +8 -8
  58. metadata +61 -48
  59. data/lib/debugger/xml.rb +0 -11
  60. data/lib/debugger/xml/extensions/ide_server.rb +0 -33
  61. data/lib/debugger/xml/extensions/vim_server.rb +0 -56
  62. data/lib/debugger/xml/fake_logger.rb +0 -11
  63. data/lib/debugger/xml/ide/control_command_processor.rb +0 -81
  64. data/lib/debugger/xml/ide/interface.rb +0 -72
  65. data/lib/debugger/xml/ide/logger.rb +0 -11
  66. data/lib/debugger/xml/ide/processor.rb +0 -94
  67. data/lib/debugger/xml/multiprocess/monkey.rb +0 -49
  68. data/lib/debugger/xml/multiprocess/pre_child.rb +0 -81
  69. data/lib/debugger/xml/version.rb +0 -5
  70. data/lib/debugger/xml/vim/control_command_processor.rb +0 -19
  71. data/lib/debugger/xml/vim/interface.rb +0 -42
  72. data/lib/debugger/xml/vim/logger.rb +0 -18
  73. data/lib/debugger/xml/vim/notification.rb +0 -37
  74. data/lib/debugger/xml/vim/processor.rb +0 -22
@@ -0,0 +1,79 @@
1
+ module DebuggerXml
2
+ module MultiProcess
3
+ class << self
4
+ def pre_child
5
+ return unless ENV['IDE_PROCESS_DISPATCHER']
6
+
7
+ require 'socket'
8
+ require 'ostruct'
9
+
10
+ host = ENV['DEBUGGER_HOST']
11
+ port = find_free_port(host)
12
+
13
+ options = OpenStruct.new(
14
+ host: host,
15
+ port: port,
16
+ stop: false,
17
+ tracing: false,
18
+ wait_for_start: true,
19
+ int_handler: true,
20
+ debug_mode: (ENV['DEBUGGER_DEBUG_MODE'] == 'true'),
21
+ dispatcher_port: ENV['IDE_PROCESS_DISPATCHER']
22
+ )
23
+
24
+ acceptor_host, acceptor_port = ENV['IDE_PROCESS_DISPATCHER'].split(":")
25
+ acceptor_host, acceptor_port = '127.0.0.1', acceptor_host unless acceptor_port
26
+
27
+ connected = false
28
+ 3.times do |i|
29
+ begin
30
+ s = TCPSocket.open(acceptor_host, acceptor_port)
31
+ s.print(port)
32
+ s.close
33
+ connected = true
34
+ start_debugger(options)
35
+ return
36
+ rescue => bt
37
+ $stderr.puts "#{Process.pid}: connection failed(#{i+1})"
38
+ $stderr.puts "Exception: #{bt}"
39
+ $stderr.puts bt.backtrace.map { |l| "\t#{l}" }.join("\n")
40
+ sleep 0.3
41
+ end unless connected
42
+ end
43
+ end
44
+
45
+ def start_debugger(options)
46
+ if Debugger.started?
47
+ # we're in forked child, only need to restart control thread
48
+ Debugger.breakpoints.clear
49
+ Debugger.control_thread = nil
50
+ end
51
+
52
+ if options.int_handler
53
+ # install interruption handler
54
+ trap('INT') { Debugger.interrupt_last }
55
+ end
56
+
57
+ # set options
58
+ Debugger.tracing = options.tracing
59
+ Debugger.wait_for_start = options.wait_for_start
60
+ Debugger.wait_connection = true
61
+ Debugger.printer = Printers::Xml.new
62
+ DebuggerXml.logger = if options.debug_mode
63
+ Debugger::Xml::Ide::Logger.new
64
+ else
65
+ Debugger::Xml::FakeLogger.new
66
+ end
67
+ DebuggerXml.start_remote_ide(options.host, options.port)
68
+ end
69
+
70
+
71
+ def find_free_port(host)
72
+ server = TCPServer.open(host, 0)
73
+ port = server.addr[1]
74
+ server.close
75
+ port
76
+ end
77
+ end
78
+ end
79
+ end
@@ -5,6 +5,6 @@ if ENV['IDE_PROCESS_DISPATCHER']
5
5
  next unless path =~ /debugger-xml|\/debugger\/|linecache/
6
6
  $LOAD_PATH << path
7
7
  end
8
- require 'debugger/xml'
9
- Debugger::Xml::MultiProcess.pre_child
8
+ require 'debugger_xml'
9
+ DebuggerXml::MultiProcess.pre_child
10
10
  end
@@ -0,0 +1,3 @@
1
+ module DebuggerXml
2
+ VERSION = "0.4.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'debugger_xml/ide/control_command_processor'
2
+
3
+ module DebuggerXml
4
+ module Vim
5
+
6
+ class ControlCommandProcessor < Ide::ControlCommandProcessor
7
+ def initialize(*args)
8
+ super(*args)
9
+ @mutex = Mutex.new
10
+ end
11
+
12
+ private
13
+
14
+ def process_command(*args)
15
+ @mutex.synchronize do
16
+ super(*args)
17
+ @interface.send_response
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,46 @@
1
+ require 'debugger_xml/ide/interface'
2
+
3
+ module DebuggerXml
4
+ module Vim
5
+ class Interface < Ide::Interface
6
+ def initialize(socket, options)
7
+ super(socket)
8
+ @options = options
9
+ @output = []
10
+ end
11
+
12
+ def print(*args)
13
+ escaped_args = escape_input(args)
14
+ value = escaped_args.first % escaped_args[1..-1]
15
+ DebuggerXml.logger.puts("Going to print: #{value}")
16
+ @output << sprintf(value)
17
+ end
18
+
19
+ def send_response
20
+ create_directory(@options.file)
21
+ message = @output.join(@options.separator)
22
+ @output.clear
23
+ unless message.empty?
24
+ File.open(@options.file, 'w') do |f|
25
+ f.puts(message)
26
+ end
27
+ Notification.new("receive_command", @options).send
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def create_directory(file)
34
+ dir = File.dirname(file)
35
+ Dir.mkdir(dir) unless File.exist?(dir) && File.directory?(dir)
36
+ end
37
+
38
+ def escape_input(args)
39
+ new_args = args.dup
40
+ new_args.first.gsub!("%", "%%") if args.first.is_a?(String)
41
+ new_args
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ module DebuggerXml
2
+ module Vim
3
+ class Logger
4
+ def initialize(logger_file)
5
+ @logger_file = logger_file
6
+ end
7
+
8
+ def puts(string)
9
+ File.open(@logger_file, 'a') do |f|
10
+ # match vim redir style new lines, rather than trailing
11
+ f << "\ndebugger-xml, #{Time.now.strftime("%H:%M:%S")} : #{string.chomp}"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ module DebuggerXml
2
+ module Vim
3
+ class Notification
4
+
5
+ def initialize(command, options)
6
+ @command = command
7
+ @executable = options.vim_executable
8
+ @servername = options.vim_servername
9
+ @debug_mode = options.debug_mode
10
+ @logger_file = options.logger_file
11
+ end
12
+
13
+ def send
14
+ command = ":call RubyDebugger.#{@command}()"
15
+ starter = "<C-\\\\>"
16
+ sys_cmd = "#{@executable} --servername #{@servername} -u NONE -U NONE " +
17
+ "--remote-send \"#{starter}<C-N>#{command}<CR>\""
18
+ log("Executing command: #{sys_cmd}")
19
+ system(sys_cmd);
20
+ end
21
+
22
+ private
23
+
24
+ def log(string)
25
+ if @debug_mode
26
+ File.open(@logger_file, 'a') do |f|
27
+ # match vim redir style new lines, rather than trailing
28
+ f << "\ndebugger-xml, #{Time.now.strftime("%H:%M:%S")} : #{string.chomp}"
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ require 'debugger_xml/ide/processor'
2
+
3
+ module DebuggerXml
4
+ module Vim
5
+
6
+ class Processor < Ide::Processor
7
+ def initialize(control_command_processor, *args)
8
+ @control_command_processor = control_command_processor
9
+ super(*args)
10
+ end
11
+
12
+ def stop_thread
13
+ @control_command_processor.process_command("where")
14
+ @control_command_processor.process_command("var ide")
15
+ super
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -2,7 +2,6 @@ require_relative 'test_helper'
2
2
 
3
3
  describe "Breakpoints" do
4
4
  include TestDsl
5
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
6
5
 
7
6
  describe "setting breakpoint in the current file" do
8
7
  it "must return right response" do
@@ -1,21 +1,26 @@
1
1
  require_relative '../test_helper'
2
- require 'debugger/xml/ide/control_command_processor'
2
+ require 'debugger_xml/ide/control_command_processor'
3
3
 
4
- describe Debugger::Xml::Ide::ControlCommandProcessor do
4
+ describe DebuggerXml::Ide::ControlCommandProcessor do
5
5
  include TestDsl
6
6
 
7
- let(:klass) { Debugger::Xml::Ide::ControlCommandProcessor }
8
- let(:interface) { Debugger.handler.interface }
7
+ let(:klass) { DebuggerXml::Ide::ControlCommandProcessor }
8
+ let(:interface) { $proxy.handler.interface }
9
9
  let(:file) { fullpath('jump') }
10
10
  let(:context) { stub(frame_binding: stub, stop_reason: nil, thread: stub, thnum: 1, stack_size: 2, dead?: false) }
11
- subject { klass.new(interface) }
12
- temporary_change_method_value(Debugger, :handler, Debugger::Xml::Ide::Processor.new(TestInterface.new))
11
+ subject { klass.new(interface, $proxy) }
13
12
 
14
13
  before do
15
14
  Thread.stubs(:stop)
16
- Debugger.handler.instance_variable_set("@context", context)
17
- Debugger.handler.instance_variable_set("@file", file)
18
- Debugger.handler.instance_variable_set("@line", 30)
15
+ @handler = $proxy.handler
16
+ $proxy.handler = DebuggerXml::Ide::Processor.new(TestInterface.new, $proxy)
17
+ $proxy.handler.instance_variable_set("@context", context)
18
+ $proxy.handler.instance_variable_set("@file", file)
19
+ $proxy.handler.instance_variable_set("@line", 30)
20
+ end
21
+
22
+ after do
23
+ $proxy.handler = @handler
19
24
  end
20
25
 
21
26
  it "must process a control command" do
@@ -34,22 +39,22 @@ describe Debugger::Xml::Ide::ControlCommandProcessor do
34
39
  it "must show error if there is no such command" do
35
40
  enter 'bla'
36
41
  subject.process_commands
37
- check_output_includes "Unknown command: bla"
42
+ check_output_includes "<error>Unknown command: bla</error>"
38
43
  end
39
44
 
40
45
  it "must show error if context is dead" do
41
46
  context.expects(:dead?).returns(true)
42
47
  enter 'step'
43
48
  subject.process_commands
44
- check_output_includes "Command is unavailable"
49
+ check_output_includes "<error>Command is unavailable</error>"
45
50
  end
46
51
 
47
52
  it "must show error if no suspended thread" do
48
- Debugger.handler.stubs(:at_line?).returns(false)
53
+ $proxy.handler.stubs(:at_line?).returns(false)
49
54
  enter 'step'
50
55
  subject.process_commands
51
56
  check_output_includes(
52
- "There is no thread suspended at the time and therefore no context to execute 'step'",
57
+ "<error>There is no thread suspended at the time and therefore no context to execute 'step'</error>",
53
58
  interface.error_queue)
54
59
  end
55
60
 
@@ -1,17 +1,17 @@
1
1
  require_relative '../test_helper'
2
- require 'debugger/xml/ide/processor'
2
+ require 'debugger_xml/ide/processor'
3
3
 
4
- describe Debugger::Xml::Ide::Processor do
4
+ describe DebuggerXml::Ide::Processor do
5
5
  include TestDsl
6
6
 
7
7
  before { Thread.stubs(:stop) }
8
8
 
9
- let(:klass) { Debugger::Xml::Ide::Processor }
9
+ let(:klass) { DebuggerXml::Ide::Processor }
10
10
  let(:interface) { TestInterface.new }
11
11
  let(:breakpoint) { stub }
12
12
  let(:context) { stub(thread: nil, stop_reason: nil, thnum: 1, stack_size: 2) }
13
13
  let(:file) { fullpath('jump') }
14
- subject { klass.new(interface) }
14
+ subject { klass.new(interface, $proxy) }
15
15
 
16
16
  describe "#at_breakpoint" do
17
17
  it "must assign breakpoint to instance variable" do
@@ -35,20 +35,13 @@ describe Debugger::Xml::Ide::Processor do
35
35
  describe "print current position" do
36
36
  it "must print if context is nil" do
37
37
  subject.at_line(nil, file, 30)
38
- check_output_includes "#{file}:30"
39
- end
40
-
41
- it "must print in xml" do
42
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new) do
43
- subject.at_line(nil, file, 30)
44
- check_output_includes %{<suspended file="#{file}" line="30" threadId="" frames=""/>}
45
- end
38
+ check_output_includes %{<suspended file="#{file}" line="30" threadId="" frames=""/>}
46
39
  end
47
40
 
48
41
  it "must print if stop reason is :step" do
49
42
  context.stubs(:stop_reason).returns(:step)
50
43
  subject.at_line(context, file, 30)
51
- check_output_includes "#{file}:30"
44
+ check_output_includes %{<suspended file="#{file}" line="30" threadId="1" frames="2"/>}
52
45
  end
53
46
 
54
47
  it "must clear instance variables after resuming thread" do
@@ -59,26 +52,19 @@ describe Debugger::Xml::Ide::Processor do
59
52
 
60
53
  describe "print breakpoint after at_breakpoint" do
61
54
  before do
62
- Debugger.stubs(:breakpoints).returns([breakpoint])
63
- Debugger.stubs(:current_context).returns(stub(thnum: 1))
55
+ $proxy.stubs(:breakpoints).returns([breakpoint])
56
+ $proxy.stubs(:current_context).returns(stub(thnum: 1))
64
57
  subject.instance_variable_set("@last_breakpoint", breakpoint)
65
58
  end
66
59
 
67
60
  it "must print in plain text" do
68
61
  subject.at_line(context, file, 30)
69
- check_output_includes "Breakpoint 1 at #{file}:30"
70
- end
71
-
72
- it "must print in xml" do
73
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new) do
74
- subject.at_line(context, file, 30)
75
- check_output_includes %{<breakpoint file="#{file}" line="30" threadId="1"/>}
76
- end
62
+ check_output_includes %{<breakpoint file="#{file}" line="30" threadId="1"/>}
77
63
  end
78
64
  end
79
65
 
80
66
  it "must show error if current thread is DebugThread" do
81
- context.stubs(:thread).returns(Debugger::DebugThread.new {})
67
+ context.stubs(:thread).returns($proxy.debug_thread_class.new {})
82
68
  subject.at_line(context, file, 30)
83
69
  check_output_includes /DebuggerThread are not supposed to be traced/
84
70
  end
@@ -106,7 +92,7 @@ describe Debugger::Xml::Ide::Processor do
106
92
 
107
93
  it "prints current file and line" do
108
94
  subject.at_return(context, file, 30)
109
- check_output_includes "#{file}:30"
95
+ check_output_includes %{<suspended file="#{file}" line="30" threadId="1" frames="2"/>}
110
96
  end
111
97
 
112
98
  it "stops the thread" do
@@ -1,4 +1,5 @@
1
1
  require_relative '../test_helper'
2
+ require 'ostruct'
2
3
 
3
4
  describe "Printers::Xml" do
4
5
  include PrinterHelpers
@@ -1,7 +1,16 @@
1
1
  require 'minitest/autorun'
2
2
 
3
- require 'debugger/xml'
4
- require 'debugger/test'
3
+ DEBUGGER_TYPE = :debugger
4
+ require 'debugger'
5
+ require 'debugger_xml'
5
6
 
6
7
  $debugger_test_dir = File.expand_path("..", __FILE__)
7
- Debugger::Xml.logger = Debugger::Xml::FakeLogger.new
8
+ $proxy = DebuggerXml::DebuggerProxy.new
9
+
10
+ MiniTest::Unit::TestCase.add_setup_hook do
11
+ $proxy.printer = Printers::Xml.new
12
+ end
13
+
14
+ require 'debugger/test'
15
+
16
+ DebuggerXml.logger = DebuggerXml::FakeLogger.new
@@ -2,7 +2,6 @@ require_relative 'test_helper'
2
2
 
3
3
  describe "Variables Command" do
4
4
  include TestDsl
5
- temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
6
5
 
7
6
  describe "constants" do
8
7
  it "must show constants" do
@@ -1,15 +1,14 @@
1
1
  require_relative '../test_helper'
2
- require 'debugger/xml/vim/control_command_processor'
2
+ require 'debugger_xml/vim/control_command_processor'
3
3
 
4
- describe Debugger::Xml::Vim::ControlCommandProcessor do
4
+ describe DebuggerXml::Vim::ControlCommandProcessor do
5
5
  include TestDsl
6
6
 
7
- let(:klass) { Debugger::Xml::Vim::ControlCommandProcessor }
7
+ let(:klass) { DebuggerXml::Vim::ControlCommandProcessor }
8
8
  let(:interface) { Debugger.handler.interface }
9
9
  let(:file) { fullpath('jump') }
10
10
  let(:context) { stub(frame_binding: stub, stop_reason: nil, thread: stub, thnum: 1, stack_size: 2, dead?: false) }
11
- subject { klass.new(interface) }
12
- temporary_change_method_value(Debugger, :handler, Debugger::Xml::Ide::Processor.new(TestInterface.new))
11
+ subject { klass.new(interface, $proxy) }
13
12
 
14
13
  before do
15
14
  Thread.stubs(:stop)