Class: Byebug::Runner

Inherits:
Object
  • Object
show all
Includes:
Helpers::ParseHelper
Defined in:
lib/byebug/runner.rb

Overview

Responsible for starting the debugger when started from the command line.

Defined Under Namespace

Classes: InvalidScript, NoScript, NonExistentScript

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers::ParseHelper

#get_int, #parse_steps, #syntax_valid?

Constructor Details

#initialize(stop = true, quit = true) ⇒ Runner

starting the program.

finishing the program.

Parameters:

  • stop (Boolean) (defaults to: true)

    Whether the runner should stop right before

  • quit (Boolean) (defaults to: true)

    Whether the runner should quit right after



58
59
60
61
# File 'lib/byebug/runner.rb', line 58

def initialize(stop = true, quit = true)
  @stop = stop
  @quit = quit
end

Instance Attribute Details

#helpObject

Special working modes that don’t actually start the debugger.



34
35
36
# File 'lib/byebug/runner.rb', line 34

def help
  @help
end

#init_scriptObject



79
80
81
# File 'lib/byebug/runner.rb', line 79

def init_script
  defined?(@init_script) ? @init_script : true
end

#interfaceObject



123
124
125
# File 'lib/byebug/runner.rb', line 123

def interface
  @interface ||= LocalInterface.new
end

#quitObject

Signals that we should exit after the debugged program is finished.



39
40
41
# File 'lib/byebug/runner.rb', line 39

def quit
  @quit
end

#remoteObject

Special working modes that don’t actually start the debugger.



34
35
36
# File 'lib/byebug/runner.rb', line 34

def remote
  @remote
end

#stopObject

Signals that we should stop before program starts



44
45
46
# File 'lib/byebug/runner.rb', line 44

def stop
  @stop
end

#versionObject

Special working modes that don’t actually start the debugger.



34
35
36
# File 'lib/byebug/runner.rb', line 34

def version
  @version
end

Instance Method Details

Usage banner.



86
87
88
89
90
91
92
93
94
# File 'lib/byebug/runner.rb', line 86

def banner
  <<-EOB.gsub(/^ {8}/, '')

      byebug #{Byebug::VERSION}

      Usage: byebug [options] <script.rb> -- <script.rb parameters>

  EOB
end

#debug_programObject

Debugs a script only if syntax checks okay.

Raises:



156
157
158
159
160
161
162
# File 'lib/byebug/runner.rb', line 156

def debug_program
  ok = syntax_valid?(File.read($PROGRAM_NAME))
  raise(InvalidScript, 'The script has incorrect syntax') unless ok

  error = Byebug.debug_load($PROGRAM_NAME, stop)
  puts "#{error}\n#{error.backtrace}" if error
end

#prepare_optionsObject

Processes options passed from the command line.



130
131
132
133
134
135
136
# File 'lib/byebug/runner.rb', line 130

def prepare_options
  OptionParser.new(banner, 25) do |opts|
    opts.banner = banner

    OptionSetter.new(self, opts).setup
  end
end

#runObject

Starts byebug to debug a program.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/byebug/runner.rb', line 99

def run
  prepare_options.order!($ARGV)
  return if version || help

  if remote
    Byebug.start_client(*remote)
    return
  end

  Byebug.run_init_script if init_script

  setup_cmd_line_args

  loop do
    debug_program

    break if quit

    ControlProcessor.new.process_commands
  end
end

#setup_cmd_line_argsObject

Extracts debugged program from command line args.

Raises:



141
142
143
144
145
146
147
148
149
150
151
# File 'lib/byebug/runner.rb', line 141

def setup_cmd_line_args
  Byebug.mode = :standalone

  raise(NoScript, 'You must specify a program to debug...') if $ARGV.empty?

  program = which($ARGV.shift)
  program = which($ARGV.shift) if program == which('ruby')
  raise(NonExistentScript, "The script doesn't exist") unless program

  $PROGRAM_NAME = program
end

#which(cmd) ⇒ Object

Cross-platform way of finding an executable in the $PATH. Borrowed from: stackoverflow.com/questions/2108727



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/byebug/runner.rb', line 168

def which(cmd)
  return File.expand_path(cmd) if File.exist?(cmd)

  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each do |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return exe if File.executable?(exe) && !File.directory?(exe)
    end
  end

  nil
end