pry-moves 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ class PryMoves::Diff
2
+
3
+ @@saved_dump = nil
4
+
5
+ def initialize(pry, binding)
6
+ @pry = pry
7
+ @binding = binding
8
+ end
9
+
10
+ def run_command cmd
11
+ if !@@saved_dump
12
+ @@saved_dump = eval_cmd cmd
13
+ @pry.output.puts "💾 Saved for diff compare:\n".cyan + @@saved_dump
14
+ else
15
+ diff = Diffy.diff @@saved_dump, eval_cmd(cmd)
16
+ @pry.output.puts diff
17
+ @@saved_dump = nil
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def eval_cmd cmd
24
+ "#{@binding.eval(cmd)}"
25
+ end
26
+
27
+ end
@@ -40,7 +40,11 @@ class PryMoves::Formatter
40
40
  end
41
41
 
42
42
  def format_arg binding, arg_name
43
- arg = binding.eval(arg_name.to_s)
43
+ arg = begin
44
+ binding.eval(arg_name.to_s)
45
+ rescue Exception
46
+ "?"
47
+ end
44
48
  format_obj arg
45
49
  end
46
50
 
@@ -56,7 +60,9 @@ class PryMoves::Formatter
56
60
  PATH_TRASH = defined?(Rails) ? Rails.root.to_s : Dir.pwd
57
61
 
58
62
  def shorten_path(path)
59
- path.gsub( /^#{PATH_TRASH}\//, '')
63
+ path = path.gsub( /^#{PATH_TRASH}\//, '')
64
+ PryMoves::Backtrace.trim_path ?
65
+ File.basename(path, ".*") : path
60
66
  end
61
67
 
62
68
  def format_obj(obj)
@@ -42,9 +42,9 @@ Pry::Command.class_eval do
42
42
  alias run_origin_for_pry_moves run
43
43
  def run(command_string, *args)
44
44
  Pry.config.original_user_input = self.class.original_user_input
45
- result = run_origin_for_pry_moves command_string, *args
45
+ run_origin_for_pry_moves command_string, *args
46
+ ensure
46
47
  Pry.config.original_user_input = nil
47
- result
48
48
  end
49
49
  end
50
50
 
@@ -86,24 +86,32 @@ Pry::Command::Whereami.class_eval do
86
86
 
87
87
  formatter = PryMoves::Formatter.new
88
88
  prefix = Thread.current[:pry_moves_debug] ? "👾 " : ""
89
- lines << "#{prefix}#{formatter.shorten_path location}"
89
+ lines << "🦆 step_in_everywhere" if PryMoves.step_in_everywhere
90
+ lines << "#{prefix}#{formatter.shorten_path location}:#{@line} #{me}"
90
91
  lines << " ." + formatter.method_signature(target)
91
92
  lines << ''
92
93
  lines << "#{code.with_line_numbers(use_line_numbers?).with_marker(marker).highlighted}"
93
94
 
94
95
  lines << PryMoves::Watch.instance.output(target) unless PryMoves::Watch.instance.empty?
95
- lines.concat PryMoves.messages
96
+ lines.concat(PryMoves.messages.map do |message|
97
+ message
98
+ # message.length > MAX_MESSAGE_CHARS ?
99
+ # message[0 .. MAX_MESSAGE_CHARS] + "... (cut)" : message
100
+ end)
96
101
  PryMoves.messages.clear
97
102
 
98
103
  lines << ''
99
104
  lines.join "\n"
100
105
  end
101
106
 
102
- def location
107
+ def me
103
108
  me = target.eval 'self' rescue nil
104
109
  me = PryMoves::Painter.colorize me if me
105
- file = defined?(Rails) ? @file.gsub(Rails.root.to_s, '') : @file
106
- "#{file}:#{@line} #{me}"
110
+ me
111
+ end
112
+
113
+ def location
114
+ defined?(Rails) ? @file.gsub(Rails.root.to_s, '') : @file
107
115
  end
108
116
  end
109
117
 
@@ -123,7 +131,9 @@ Pry::Output.class_eval do
123
131
  alias pry_moves_origin_for_puts puts
124
132
 
125
133
  def puts *args
134
+ # <first> formatted by Pry.config.print = proc do |output, value|
126
135
  first = args[0]
136
+ # Kernel.puts "Pry::Output.puts: #{first}"
127
137
  if first.is_a? String and first.start_with? "(pry) output error"
128
138
  first.slice! 400..-1
129
139
  end
@@ -12,7 +12,7 @@ class PryWrapper
12
12
  PryMoves.lock
13
13
 
14
14
  initial_frame = PryMoves::BindingsStack.new(@pry_start_options).initial_frame
15
- if not @pry_start_options[:pry_moves_loop] and
15
+ if not @pry_start_options[:pry_moves_loop] and initial_frame and
16
16
  initial_frame.local_variable_defined? :debug_redirect
17
17
  debug_redirect = initial_frame.local_variable_get(:debug_redirect)
18
18
  PryMoves.messages << "⏩ redirected to #{debug_redirect}"
@@ -1,17 +1,21 @@
1
1
  module PryMoves::Restartable
2
2
 
3
3
  attr_accessor :restart_requested, :reload_requested,
4
+ :reload_ruby_scripts, :reloader,
4
5
  :reload_rake_tasks
5
6
 
6
7
  def restartable context
7
8
  trigger :each_new_run, context
8
- yield
9
+ context[:retry] ||= 0
10
+ PryMoves.reloader&.reload if context[:retry] > 0
11
+ yield context
9
12
  re_execution
10
13
  rescue PryMoves::Restart
11
14
  puts "🔄️ Restarting execution"
12
15
  self.restart_requested = false
13
16
  PryMoves.reset
14
17
  trigger :restart, context
18
+ context[:retry] += 1
15
19
  retry
16
20
  rescue PryMoves::Reload
17
21
  puts "🔮 try to use @ with reload"
@@ -0,0 +1,22 @@
1
+ class PryMoves::Tools
2
+
3
+ def initialize pry
4
+ @pry = pry
5
+ end
6
+
7
+ def add_breakpoint var_name, line_number, binding
8
+ file, line = binding.eval('[__FILE__, __LINE__]')
9
+ line_number ||= line
10
+ lines = IO.readlines(file)
11
+
12
+ value = binding.eval(var_name)
13
+ value = value.to_json if value.is_a? String
14
+ lines.insert line_number-1, "debug if #{var_name} == #{value}"
15
+
16
+ File.open(file, 'w') do |file|
17
+ file.puts lines
18
+ end
19
+ @pry.output.puts "🔴 Breakpoint added to #{File.basename file}:#{line_number}"
20
+ end
21
+
22
+ end
@@ -1,3 +1,3 @@
1
1
  module PryMoves
2
- VERSION = '1.0.2'
2
+ VERSION = '1.0.4'
3
3
  end
data/lib/pry-moves.rb CHANGED
@@ -1,37 +1,4 @@
1
- require 'pry' unless defined? Pry
2
- require 'colorize'
3
- require 'diffy'
4
-
5
- require 'pry-moves/version'
6
- require 'pry-moves/pry_ext'
7
- require 'pry-moves/commands'
8
- require 'pry-moves/add_suffix'
9
- require 'pry-moves/pry_wrapper'
10
- require 'pry-moves/bindings_stack'
11
- require 'pry-moves/formatter'
12
- require 'pry-moves/backtrace'
13
- require 'pry-moves/watch'
14
- require 'pry-moves/painter'
15
- require 'pry-moves/restartable'
16
- require 'pry-moves/recursion_tracker'
17
- require 'pry-moves/error_with_data'
18
-
19
- require 'commands/traced_method'
20
- require 'commands/trace_helpers'
21
- require 'commands/trace_command'
22
- require 'commands/debug'
23
- require 'commands/finish'
24
- require 'commands/goto'
25
- require 'commands/iterate'
26
- require 'commands/next'
27
- require 'commands/next_breakpoint'
28
- require 'commands/step'
29
-
30
- require 'pry-stack_explorer/pry-stack_explorer'
31
- require 'debug_sugar'
32
-
33
- # Optionally load pry-remote monkey patches
34
- require 'pry-moves/pry_remote_ext' if defined? PryRemote
1
+ require 'requires.rb'
35
2
 
36
3
  module PryMoves
37
4
  TRACE_IGNORE_FILES = Dir[File.join(File.dirname(__FILE__), '**', '*.rb')].map { |f| File.expand_path(f) }
@@ -40,22 +7,35 @@ module PryMoves
40
7
  extend PryMoves::Restartable
41
8
 
42
9
  attr_accessor :is_open, :trace, :stack_tips,
43
- :stop_on_breakpoints, :launched_specs_examples, :debug_called_times
10
+ :stop_on_breakpoints, :launched_specs_examples,
11
+ :debug_called_times, :step_in_everywhere
12
+
13
+ def init
14
+ reset
15
+ self.trace = true if ENV['TRACE_MOVES']
16
+ self.reload_ruby_scripts = {
17
+ monitor: %w(app spec),
18
+ except: %w(app/assets app/views)
19
+ }
20
+ self.reloader = CodeReloader.new unless ENV['PRY_MOVES_RELOADER'] == 'off'
21
+ self.reload_rake_tasks = true
22
+ end
44
23
 
45
24
  def reset
46
25
  self.launched_specs_examples = 0
47
- self.stop_on_breakpoints = true
26
+ self.stop_on_breakpoints = true unless ENV['PRY_MOVES'] == 'off' ||
27
+ (defined?(Rails) and Rails.env.production?)
48
28
  self.debug_called_times = 0
29
+ self.step_in_everywhere = false
49
30
  end
50
31
 
51
- def debug(message = nil, at: nil, options: nil)
32
+ def debug(message = nil, at: nil, from: nil, options: nil)
52
33
  pry_moves_stack_end = true
53
34
  PryMoves.re_execution
54
35
  if PryMoves.stop_on_breakpoints
55
36
  self.debug_called_times += 1
56
- if at
57
- return unless self.debug_called_times == at
58
- end
37
+ return if at and self.debug_called_times != at
38
+ return if from and self.debug_called_times < from
59
39
  if message
60
40
  PryMoves.messages << (message.is_a?(String) ? message : message.ai)
61
41
  end
@@ -64,7 +44,43 @@ module PryMoves
64
44
  end
65
45
  end
66
46
 
67
- def error(message)
47
+ ROOT_DIR = File.expand_path(".")
48
+
49
+ def runtime_debug(instance, external: false)
50
+ do_debug = (
51
+ stop_on_breakpoints and
52
+ not open? and
53
+ (external or is_project_file?) and
54
+ not [RubyVM::InstructionSequence].include?(instance)
55
+ )
56
+ if do_debug
57
+ hide_from_stack = true
58
+ err, obj = yield
59
+ # HINT: when pry failed to start use: caller.reverse
60
+ PryMoves.debug_error err, obj
61
+ true
62
+ end
63
+ end
64
+
65
+ def is_project_file?
66
+ files = caller[2..3] # -2 steps upside: runtime_debug, debug sugar function
67
+ files.any? do |file|
68
+ !file.start_with?("/") || file.start_with?(ROOT_DIR)
69
+ end
70
+ end
71
+
72
+ MAX_MESSAGE_CHARS = 520
73
+ def format_debug_object obj
74
+ output = obj.ai rescue "#{obj.class} #{obj}"
75
+ output.length > MAX_MESSAGE_CHARS ?
76
+ output[0 .. MAX_MESSAGE_CHARS] + "... (cut)" : output
77
+ end
78
+
79
+ def debug_error(message, debug_object=nil)
80
+ pry_moves_stack_end = true
81
+ if debug_object
82
+ message = [format_debug_object(debug_object), message].join "\n"
83
+ end
68
84
  debug message, options: {is_error: true}
69
85
  end
70
86
 
@@ -123,7 +139,7 @@ module PryMoves
123
139
 
124
140
  TRIGGERS = [:each_new_run, :restart]
125
141
  def on(trigger, &block)
126
- error "Invalid trigger, possible triggers: #{TRIGGERS}", trigger unless trigger.in? TRIGGERS
142
+ error "Invalid trigger, possible triggers: #{TRIGGERS}", trigger unless TRIGGERS.include? trigger
127
143
  triggers[trigger] << block
128
144
  end
129
145
 
@@ -131,5 +147,6 @@ module PryMoves
131
147
  attr_accessor :current_remote_server
132
148
  end
133
149
 
134
- PryMoves.reset
135
- PryMoves.trace = true if ENV['TRACE_MOVES']
150
+ PryMoves.init
151
+
152
+ require 'sugar/debug_of_missing' # After PryMoves loaded
@@ -88,6 +88,7 @@ module PryStackExplorer::FrameHelpers
88
88
  end
89
89
 
90
90
  def find_frame_by_direction(dir, step_into_vapid: false)
91
+ PryMoves.step_in_everywhere = true if step_into_vapid
91
92
  frame_index = find_frame_by_block(dir) do |b|
92
93
  step_into_vapid or not b.hidden
93
94
  end
data/lib/requires.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'pry' unless defined? Pry
2
+ require 'colorize'
3
+ require 'diffy'
4
+
5
+ require 'pry-moves/version'
6
+ require 'pry-moves/pry_ext'
7
+ require 'pry-moves/commands'
8
+ require 'pry-moves/add_suffix'
9
+ require 'pry-moves/pry_wrapper'
10
+ require 'pry-moves/bindings_stack'
11
+ require 'pry-moves/code_reloader'
12
+ require 'pry-moves/formatter'
13
+ require 'pry-moves/backtrace'
14
+ require 'pry-moves/backtrace_builder'
15
+ require 'pry-moves/tools'
16
+ require 'pry-moves/watch'
17
+ require 'pry-moves/diff'
18
+ require 'pry-moves/painter'
19
+ require 'pry-moves/restartable'
20
+ require 'pry-moves/recursion_tracker'
21
+ require 'pry-moves/error_with_data'
22
+
23
+ require 'commands/traced_method'
24
+ require 'commands/trace_helpers'
25
+ require 'commands/trace_command'
26
+ require 'commands/debug'
27
+ require 'commands/finish'
28
+ require 'commands/goto'
29
+ require 'commands/iterate'
30
+ require 'commands/next'
31
+ require 'commands/next_breakpoint'
32
+ require 'commands/step'
33
+
34
+ require 'pry-stack_explorer/pry-stack_explorer'
35
+ require 'sugar/debug_sugar'
36
+
37
+ # Optionally load pry-remote monkey patches
38
+ require 'pry-moves/pry_remote_ext' if defined? PryRemote
@@ -0,0 +1,36 @@
1
+ Object.class_eval do
2
+
3
+ def method_missing(method, *args)
4
+ pry_moves_stack_end = true
5
+ pry_cancel_debug = true
6
+
7
+ debug_missing_method = (
8
+ not ([:begin, :to_s, :to_str, :to_int, :to_ary, :to_io, :to_hash].include? method)
9
+
10
+ # not ([:begin, :to_s, :to_str, :to_int, :to_ary, :to_io, :to_hash].include? method) and
11
+ # not caller[0].match PryMoves::Backtrace::filter
12
+ )
13
+
14
+ PryMoves.runtime_debug(self) do
15
+ message = self.nil? ?
16
+ "\e[31mCalling \e[1m#{method}\e[0m\e[31m on nil\e[0m" :
17
+ "\e[31mMethod \e[1m#{method}\e[0m\e[31m missing\e[0m"
18
+ [message, self]
19
+ end if debug_missing_method
20
+
21
+ super
22
+ end
23
+
24
+ def self.const_missing(name)
25
+ super
26
+ rescue => e
27
+ unless PryMoves.open?
28
+ hide_from_stack = true
29
+ message = "😱 \e[31m#{e.to_s}\e[0m"
30
+ PryMoves.debug_error message
31
+ end
32
+ raise
33
+ end unless defined?(Rails)
34
+
35
+ end if ENV['PRY_MOVES_DEBUG_MISSING'] != 'off' and ENV['PRY_MOVES'] != 'off' and
36
+ not (defined?(Rails) and Rails.env.production?)
@@ -1,4 +1,5 @@
1
1
  def debug *args
2
+ return binding.pry_forced if args.first == :forced
2
3
  pry_moves_stack_end = true
3
4
  PryMoves.debug *args
4
5
  end
@@ -8,11 +9,9 @@ def error(msg = "Error", debug_object = nil)
8
9
  err = "😱 #{msg}"
9
10
  unless PryMoves.open?
10
11
  if PryMoves.stop_on_breakpoints
11
- lines = [err.red]
12
- lines.prepend debug_object.ai if debug_object
13
- PryMoves.error lines.join("\n")
12
+ PryMoves.debug_error err.red, debug_object
14
13
  else
15
- STDERR.puts debug_object.ai if debug_object
14
+ STDERR.puts PryMoves.format_debug_object(debug_object) if debug_object
16
15
  STDERR.puts err.ljust(80, ' ').red
17
16
  end
18
17
  end
@@ -26,14 +25,26 @@ def shit!(err = 'Oh, shit!', debug_object = nil)
26
25
  raise err unless PryMoves.stop_on_breakpoints
27
26
  lines = [message.red]
28
27
  lines.prepend debug_object.ai if debug_object
29
- PryMoves.error lines.join("\n")
28
+ PryMoves.debug_error lines.join("\n")
30
29
  nil
31
30
  end
32
31
 
33
- def required(var)
34
- pry_moves_stack_end = true
35
- error("required parameter is missing") if var.nil?
36
- var
32
+ Object.class_eval do
33
+
34
+ def required!
35
+ pry_moves_stack_end = true
36
+ error("required parameter is missing") if self.nil?
37
+ self
38
+ end
39
+
40
+ def should_be *classes
41
+ hide_from_stack = true
42
+ if self && !classes.some?{self.is_a?(_1)}
43
+ error("Expected class #{classes.join ", "}, got #{self.class.ai}", self)
44
+ end
45
+ self
46
+ end
47
+
37
48
  end
38
49
 
39
50
  RSpec.configure do |config|
@@ -41,7 +52,7 @@ RSpec.configure do |config|
41
52
  config.before(:each) do
42
53
  PryMoves.launched_specs_examples += 1
43
54
  PryMoves.stop_on_breakpoints =
44
- PryMoves.launched_specs_examples < 2
55
+ RSpec.configuration.world.example_count == 1
45
56
  end
46
57
 
47
58
  config.around(:each) do |example|
@@ -50,7 +61,7 @@ RSpec.configure do |config|
50
61
  end
51
62
  end
52
63
 
53
- end if defined? RSpec
64
+ end if ENV['PRY_MOVES'] != 'off' and defined? RSpec
54
65
 
55
66
  Rake::Task.class_eval do
56
67
 
@@ -58,8 +69,8 @@ Rake::Task.class_eval do
58
69
 
59
70
  def execute(args=nil)
60
71
  args ||= EMPTY_TASK_ARGS
61
- PryMoves.restartable(rake_args: args) do
62
- reload_actions if PryMoves.reload_rake_tasks
72
+ PryMoves.restartable(rake_args: args) do |context|
73
+ reload_actions if PryMoves.reload_rake_tasks and context[:retry] > 0
63
74
  execute_origin_for_pry_moves args
64
75
  end
65
76
  end
@@ -70,4 +81,18 @@ Rake::Task.class_eval do
70
81
  load rake_task_path
71
82
  end
72
83
 
73
- end if defined? Rake and defined? Rake::Task
84
+ end if ENV['PRY_MOVES'] != 'off' and defined? Rake and defined? Rake::Task
85
+
86
+ Diffy.module_eval do
87
+
88
+ class << self
89
+ def diff text1, text2
90
+ diff = Diffy::Diff.new(
91
+ text1 + "\n", text2 + "\n"
92
+ ).to_s "color"
93
+ diff = 'Outputs are equal' if diff.strip.empty?
94
+ diff
95
+ end
96
+ end
97
+
98
+ end
@@ -1,10 +1,10 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- pry-moves (1.0.1)
4
+ pry-moves (1.0.2)
5
5
  binding_of_caller (~> 0.7)
6
6
  colorize (~> 0.8)
7
- diffy
7
+ diffy (~> 3.4.0)
8
8
  pry (>= 0.10.4, < 0.13)
9
9
 
10
10
  GEM
@@ -15,7 +15,7 @@ GEM
15
15
  coderay (1.1.3)
16
16
  colorize (0.8.1)
17
17
  debug_inspector (1.1.0)
18
- diffy (3.4.0)
18
+ diffy (3.4.2)
19
19
  method_source (0.9.2)
20
20
  pry (0.12.2)
21
21
  coderay (~> 1.1.0)
@@ -155,13 +155,18 @@ class Playground
155
155
  def method_with_breakpoints
156
156
  binding.pry # method_with_breakpoints host
157
157
  dummy = 1 # some internal line
158
- debug_ # breakpoint
158
+ method_with_breakpoint # breakpoint
159
159
  dummy = 1 # after breakpoint
160
160
  dummy = 1 # after after breakpoint
161
- debug_ # breakpoint 2
161
+ method_with_breakpoint # breakpoint 2
162
162
  dummy = 1 # after breakpoint 2
163
163
  end
164
164
 
165
+ def method_with_breakpoint
166
+ pry_breakpoint = true
167
+ hide_from_stack = true
168
+ end
169
+
165
170
  def skip_test
166
171
  binding.pry # stop in skip_test
167
172
  skipped_method.not_skipped_method # next step
data/pry-moves.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |gem|
22
22
  gem.add_runtime_dependency 'pry', '>= 0.10.4', '< 0.13'
23
23
  gem.add_runtime_dependency 'binding_of_caller', '~> 0.7'
24
24
  gem.add_runtime_dependency 'colorize', '~> 0.8'
25
+ gem.add_runtime_dependency 'awesome_print', '>= 1.8.0'
25
26
  gem.add_runtime_dependency 'diffy', '~> 3.4.0'
26
27
  gem.add_development_dependency 'pry-remote', '~> 0.1.6'
27
28
  end
data/publish.sh CHANGED
@@ -1,3 +1,6 @@
1
- bundle exec rspec && \
2
- gem build pry-moves.gemspec && \
1
+ set -e
2
+ set -o pipefail
3
+
4
+ bundle exec rspec
5
+ gem build pry-moves.gemspec
3
6
  gem push pry-moves-`ruby -e 'require "./lib/pry-moves/version.rb"; puts PryMoves::VERSION'`.gem
@@ -17,6 +17,9 @@ describe 'backtrace' do
17
17
  }],
18
18
  ['bt hidden', lambda{|b, output|
19
19
  lines = output.split("\n").reverse
20
+ 2.times do
21
+ lines.pop if lines.last.end_with? "main" # remove tech frames from bin/rspec
22
+ end
20
23
  # show hidden frame
21
24
  expect(lines[1]).to end_with 'level_b()'
22
25
  expect(lines.count).to be 11
@@ -2,6 +2,8 @@ require_relative 'spec_helper'
2
2
 
3
3
  describe 'PryMoves commands' do
4
4
 
5
+ # todo: test sugars: method_missing, etc...
6
+
5
7
  it 'should make one move next' do
6
8
  breakpoints [
7
9
  [nil, 'basic next stop'],
data/spec/spec_helper.rb CHANGED
@@ -12,12 +12,13 @@ RSpec.configure do |config|
12
12
 
13
13
  config.before(:example) do
14
14
  PryMoves.unlock if PryMoves.semaphore.locked?
15
+ PryMoves.step_in_everywhere = false
15
16
  end
16
17
 
17
18
  config.after(:example) do |example|
18
19
  unless example.exception
19
20
  expect(PryDebugger.breakpoints.count).to be(0),
20
- "not all breakpoints launched: #{PryDebugger.breakpoints.count}"
21
+ "not all breakpoints launched, left to launch: #{PryDebugger.breakpoints.count}. All following specs may fail."
21
22
  end
22
23
  end
23
24