puppet-debugger 0.16.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +10 -26
- data/.rubocop.yml +64 -232
- data/.rubocop_todo.yml +89 -147
- data/.ruby-version +1 -1
- data/.vscode/launch.json +15 -0
- data/CHANGELOG.md +34 -0
- data/Gemfile +7 -5
- data/README.md +29 -261
- data/Rakefile +11 -12
- data/bin/pdb +1 -1
- data/lib/awesome_print/ext/awesome_puppet.rb +10 -8
- data/lib/plugins/puppet-debugger/input_responders/benchmark.rb +5 -4
- data/lib/plugins/puppet-debugger/input_responders/classes.rb +14 -2
- data/lib/plugins/puppet-debugger/input_responders/classification.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/commands.rb +18 -18
- data/lib/plugins/puppet-debugger/input_responders/datatypes.rb +22 -6
- data/lib/plugins/puppet-debugger/input_responders/environment.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/exit.rb +5 -3
- data/lib/plugins/puppet-debugger/input_responders/facterdb_filter.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/facts.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/functions.rb +34 -32
- data/lib/plugins/puppet-debugger/input_responders/help.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/krt.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/play.rb +22 -24
- data/lib/plugins/puppet-debugger/input_responders/reset.rb +5 -3
- data/lib/plugins/puppet-debugger/input_responders/resources.rb +16 -7
- data/lib/plugins/puppet-debugger/input_responders/set.rb +34 -32
- data/lib/plugins/puppet-debugger/input_responders/stacktrace.rb +31 -0
- data/lib/plugins/puppet-debugger/input_responders/types.rb +6 -2
- data/lib/plugins/puppet-debugger/input_responders/vars.rb +8 -7
- data/lib/plugins/puppet-debugger/input_responders/whereami.rb +5 -3
- data/lib/puppet-debugger.rb +1 -45
- data/lib/puppet-debugger/cli.rb +130 -92
- data/lib/puppet-debugger/code/code_file.rb +13 -14
- data/lib/puppet-debugger/code/code_range.rb +5 -3
- data/lib/puppet-debugger/code/loc.rb +1 -1
- data/lib/puppet-debugger/debugger_code.rb +2 -0
- data/lib/puppet-debugger/hooks.rb +15 -16
- data/lib/puppet-debugger/input_responder_plugin.rb +54 -52
- data/lib/puppet-debugger/monkey_patches.rb +57 -0
- data/lib/puppet-debugger/plugin_test_helper.rb +9 -8
- data/lib/puppet-debugger/support.rb +27 -17
- data/lib/puppet-debugger/support/environment.rb +6 -5
- data/lib/puppet-debugger/support/errors.rb +25 -27
- data/lib/puppet-debugger/support/facts.rb +5 -5
- data/lib/puppet-debugger/support/node.rb +4 -7
- data/lib/puppet-debugger/support/scope.rb +29 -0
- data/lib/puppet-debugger/trollop.rb +38 -31
- data/lib/puppet-debugger/version.rb +1 -1
- data/lib/puppet/application/debugger.rb +151 -126
- data/output.json +1 -0
- data/puppet-debugger.gemspec +17 -15
- data/spec/awesome_print/ext/awesome_puppet_spec.rb +30 -30
- data/spec/fixtures/pe-xl-core-0.puppet.vm.json +1 -0
- data/spec/fixtures/sample_start_debugger.pp +3 -2
- data/spec/hooks_spec.rb +33 -35
- data/spec/input_responder_plugin_spec.rb +7 -6
- data/spec/input_responders/benchmark_spec.rb +3 -1
- data/spec/input_responders/classes_spec.rb +12 -13
- data/spec/input_responders/classification_spec.rb +4 -2
- data/spec/input_responders/commands_spec.rb +2 -0
- data/spec/input_responders/datatypes_spec.rb +8 -2
- data/spec/input_responders/environment_spec.rb +2 -0
- data/spec/input_responders/exit_spec.rb +9 -11
- data/spec/input_responders/facterdb_filter_spec.rb +2 -0
- data/spec/input_responders/facts_spec.rb +2 -0
- data/spec/input_responders/functions_spec.rb +30 -28
- data/spec/input_responders/help_spec.rb +5 -3
- data/spec/input_responders/krt_spec.rb +3 -1
- data/spec/input_responders/play_spec.rb +10 -20
- data/spec/input_responders/reset_spec.rb +2 -0
- data/spec/input_responders/resources_spec.rb +7 -1
- data/spec/input_responders/set_spec.rb +3 -1
- data/spec/input_responders/stacktrace_spec.rb +15 -0
- data/spec/input_responders/types_spec.rb +2 -0
- data/spec/input_responders/vars_spec.rb +4 -4
- data/spec/input_responders/whereami_spec.rb +2 -0
- data/spec/pdb_spec.rb +0 -9
- data/spec/puppet/application/debugger_spec.rb +35 -17
- data/spec/puppet_debugger_spec.rb +81 -83
- data/spec/remote_node_spec.rb +1 -5
- data/spec/spec_helper.rb +22 -18
- data/spec/support_spec.rb +3 -5
- data/test_matrix.rb +1 -1
- metadata +56 -22
data/lib/puppet-debugger/cli.rb
CHANGED
@@ -1,31 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
|
3
|
+
require 'puppet'
|
4
|
+
require 'readline'
|
5
|
+
require 'json'
|
6
|
+
require 'puppet-debugger/support'
|
7
|
+
require 'pluginator'
|
8
|
+
require 'puppet-debugger/hooks'
|
9
|
+
require 'forwardable'
|
10
|
+
require 'plugins/puppet-debugger/input_responders/functions'
|
11
|
+
require 'plugins/puppet-debugger/input_responders/datatypes'
|
12
|
+
require 'tty-pager'
|
13
13
|
module PuppetDebugger
|
14
14
|
class Cli
|
15
15
|
include PuppetDebugger::Support
|
16
16
|
extend Forwardable
|
17
17
|
attr_accessor :settings, :log_level, :in_buffer, :out_buffer, :html_mode, :extra_prompt, :bench
|
18
|
-
attr_reader :source_file, :source_line_num, :hooks
|
18
|
+
attr_reader :source_file, :source_line_num, :hooks, :options
|
19
19
|
def_delegators :hooks, :exec_hook, :add_hook, :delete_hook
|
20
|
-
|
20
|
+
OUT_SYMBOL = ' => '
|
21
21
|
def initialize(options = {})
|
22
22
|
do_initialize if Puppet[:codedir].nil?
|
23
23
|
Puppet.settings[:name] = :debugger
|
24
|
-
|
24
|
+
@options = options
|
25
25
|
Puppet[:static_catalogs] = false unless Puppet.settings[:static_catalogs].nil?
|
26
26
|
set_remote_node_name(options[:node_name])
|
27
27
|
initialize_from_scope(options[:scope])
|
28
|
-
|
28
|
+
set_catalog(options[:catalog])
|
29
|
+
@log_level = 'notice'
|
29
30
|
@out_buffer = options[:out_buffer] || $stdout
|
30
31
|
@html_mode = options[:html_mode] || false
|
31
32
|
@source_file = options[:source_file] || nil
|
@@ -33,14 +34,23 @@ module PuppetDebugger
|
|
33
34
|
@in_buffer = options[:in_buffer] || $stdin
|
34
35
|
Readline.input = @in_buffer
|
35
36
|
Readline.output = @out_buffer
|
36
|
-
Readline.completion_append_character =
|
37
|
-
Readline.basic_word_break_characters =
|
37
|
+
Readline.completion_append_character = ''
|
38
|
+
Readline.basic_word_break_characters = ' '
|
38
39
|
Readline.completion_proc = command_completion
|
39
40
|
AwesomePrint.defaults = {
|
40
41
|
html: @html_mode,
|
41
42
|
sort_keys: true,
|
42
|
-
indent: 2
|
43
|
+
indent: 2
|
43
44
|
}
|
45
|
+
# Catch control-c sequences
|
46
|
+
trap('SIGINT') do
|
47
|
+
# control-d
|
48
|
+
exit 0
|
49
|
+
end
|
50
|
+
trap('INT') do
|
51
|
+
# control-c
|
52
|
+
# handle_output('Type exit or use control-d')
|
53
|
+
end
|
44
54
|
end
|
45
55
|
|
46
56
|
# @return [Proc] the proc used in the command completion for readline
|
@@ -50,11 +60,12 @@ module PuppetDebugger
|
|
50
60
|
proc do |input|
|
51
61
|
words = Readline.line_buffer.split(Readline.basic_word_break_characters)
|
52
62
|
next key_words.grep(/^#{Regexp.escape(input)}/) if words.empty?
|
63
|
+
|
53
64
|
first_word = words.shift
|
54
65
|
plugins = PuppetDebugger::InputResponders::Commands.plugins.find_all do |p|
|
55
66
|
p::COMMAND_WORDS.find { |word| word.start_with?(first_word) }
|
56
67
|
end
|
57
|
-
if plugins.count == 1
|
68
|
+
if (plugins.count == 1) && /\A#{first_word}\s/.match(Readline.line_buffer)
|
58
69
|
plugins.first.command_completion(words)
|
59
70
|
else
|
60
71
|
key_words.grep(/^#{Regexp.escape(input)}/)
|
@@ -76,7 +87,8 @@ module PuppetDebugger
|
|
76
87
|
PuppetDebugger::InputResponders::Functions.instance.debugger = self
|
77
88
|
funcs = PuppetDebugger::InputResponders::Functions.instance.func_list
|
78
89
|
PuppetDebugger::InputResponders::Datatypes.instance.debugger = self
|
79
|
-
(scoped_vars + funcs + static_responder_list +
|
90
|
+
(scoped_vars + funcs + static_responder_list +
|
91
|
+
PuppetDebugger::InputResponders::Datatypes.instance.all_data_types).uniq.sort
|
80
92
|
end
|
81
93
|
|
82
94
|
# looks up the type in the catalog by using the type and title
|
@@ -106,7 +118,7 @@ module PuppetDebugger
|
|
106
118
|
end
|
107
119
|
|
108
120
|
def contains_resources?(result)
|
109
|
-
!Array(result).flatten.find { |r| r.class.to_s =~ /Puppet::Pops::Types/ }.nil?
|
121
|
+
!Array(result).flatten.find { |r| r.class.to_s =~ /Puppet::Pops::Types::PResourceType/ }.nil?
|
110
122
|
end
|
111
123
|
|
112
124
|
def normalize_output(result)
|
@@ -116,87 +128,108 @@ module PuppetDebugger
|
|
116
128
|
# if the only output is a resource then return it
|
117
129
|
# otherwise it is multiple items or an actually array
|
118
130
|
return output.first if output.count == 1
|
131
|
+
|
119
132
|
return output
|
120
133
|
end
|
121
134
|
result
|
122
135
|
end
|
123
136
|
|
124
137
|
def responder_list
|
125
|
-
|
138
|
+
Pluginator.find(PuppetDebugger)
|
139
|
+
end
|
140
|
+
|
141
|
+
# @return [TTY::Pager] the pager object, disable if CI or testing is present
|
142
|
+
def pager
|
143
|
+
@pager ||= TTY::Pager.new(output: out_buffer, enabled: pager_enabled?)
|
144
|
+
end
|
145
|
+
|
146
|
+
def pager_enabled?
|
147
|
+
ENV['CI'].nil?
|
148
|
+
end
|
149
|
+
|
150
|
+
# @param output [String] - the content to output
|
151
|
+
# @summary outputs the output to the output buffer
|
152
|
+
# uses the pager if the screen height is less than the height of the
|
153
|
+
# output content
|
154
|
+
# Disabled if CI or testing is being done
|
155
|
+
def handle_output(output)
|
156
|
+
return if output.nil?
|
157
|
+
|
158
|
+
if pager_enabled? && output.lines.count >= TTY::Screen.height
|
159
|
+
output << "\n"
|
160
|
+
pager.page(output)
|
161
|
+
else
|
162
|
+
out_buffer.puts(output) unless output.empty?
|
163
|
+
end
|
126
164
|
end
|
127
165
|
|
128
166
|
# this method handles all input and expects a string of text.
|
129
|
-
#
|
167
|
+
# @param input [String] - the input content to parse or run
|
130
168
|
def handle_input(input)
|
131
169
|
raise ArgumentError unless input.instance_of?(String)
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
170
|
+
|
171
|
+
output =
|
172
|
+
begin
|
173
|
+
case input.strip
|
174
|
+
when PuppetDebugger::InputResponders::Commands.command_list_regex
|
175
|
+
args = input.split(' ')
|
176
|
+
command = args.shift
|
177
|
+
plugin = PuppetDebugger::InputResponders::Commands.plugin_from_command(command)
|
178
|
+
plugin.execute(args, self) || ''
|
179
|
+
when '_'
|
180
|
+
" => #{@last_item}"
|
181
|
+
else
|
182
|
+
result = puppet_eval(input)
|
183
|
+
@last_item = result
|
184
|
+
o = normalize_output(result)
|
185
|
+
o.nil? ? '' : o.ai
|
186
|
+
end
|
187
|
+
rescue PuppetDebugger::Exception::InvalidCommand => e
|
188
|
+
e.message.fatal
|
189
|
+
rescue LoadError => e
|
190
|
+
e.message.fatal
|
191
|
+
rescue Errno::ETIMEDOUT => e
|
192
|
+
e.message.fatal
|
193
|
+
rescue ArgumentError => e
|
194
|
+
e.message.fatal
|
195
|
+
rescue Puppet::ResourceError => e
|
196
|
+
e.message.fatal
|
197
|
+
rescue Puppet::Error => e
|
198
|
+
e.message.fatal
|
199
|
+
rescue Puppet::ParseErrorWithIssue => e
|
200
|
+
e.message.fatal
|
201
|
+
rescue PuppetDebugger::Exception::FatalError => e
|
202
|
+
handle_output(e.message.fatal)
|
203
|
+
exit 1 # this can sometimes causes tests to fail
|
204
|
+
rescue PuppetDebugger::Exception::Error => e
|
205
|
+
e.message.fatal
|
206
|
+
rescue ::RuntimeError => e
|
207
|
+
handle_output(e.message.fatal)
|
208
|
+
exit 1
|
148
209
|
end
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
output = e.message.fatal
|
153
|
-
rescue Errno::ETIMEDOUT => e
|
154
|
-
output = e.message.fatal
|
155
|
-
rescue ArgumentError => e
|
156
|
-
output = e.message.fatal
|
157
|
-
rescue Puppet::ResourceError => e
|
158
|
-
output = e.message.fatal
|
159
|
-
rescue Puppet::Error => e
|
160
|
-
output = e.message.fatal
|
161
|
-
rescue Puppet::ParseErrorWithIssue => e
|
162
|
-
output = e.message.fatal
|
163
|
-
rescue PuppetDebugger::Exception::FatalError => e
|
164
|
-
output = e.message.fatal
|
165
|
-
out_buffer.puts output
|
166
|
-
exit 1 # this can sometimes causes tests to fail
|
167
|
-
rescue PuppetDebugger::Exception::Error => e
|
168
|
-
output = e.message.fatal
|
169
|
-
rescue ::RuntimeError => e
|
170
|
-
output = e.message.fatal
|
171
|
-
out_buffer.puts output
|
172
|
-
exit 1
|
173
|
-
end
|
174
|
-
unless output.empty?
|
175
|
-
out_buffer.print " => "
|
176
|
-
out_buffer.puts output unless output.empty?
|
177
|
-
exec_hook :after_output, out_buffer, self, self
|
178
|
-
end
|
210
|
+
output = OUT_SYMBOL + output unless output.empty?
|
211
|
+
handle_output(output)
|
212
|
+
exec_hook :after_output, out_buffer, self, self
|
179
213
|
end
|
180
214
|
|
181
215
|
def self.print_repl_desc
|
182
|
-
|
183
|
-
Ruby Version: #{RUBY_VERSION}
|
184
|
-
Puppet Version: #{Puppet.version}
|
185
|
-
Puppet Debugger Version: #{PuppetDebugger::VERSION}
|
186
|
-
Created by: NWOps <corey@nwops.io>
|
187
|
-
Type "commands" for a list of debugger commands
|
188
|
-
or "help" to show the help screen.
|
216
|
+
<<~OUT
|
217
|
+
Ruby Version: #{RUBY_VERSION}
|
218
|
+
Puppet Version: #{Puppet.version}
|
219
|
+
Puppet Debugger Version: #{PuppetDebugger::VERSION}
|
220
|
+
Created by: NWOps <corey@nwops.io>
|
221
|
+
Type "commands" for a list of debugger commands
|
222
|
+
or "help" to show the help screen.
|
189
223
|
|
190
224
|
|
191
|
-
|
192
|
-
output
|
225
|
+
OUT
|
193
226
|
end
|
194
227
|
|
195
228
|
# tries to determine if the input is going to be a multiline input
|
196
229
|
# by reading the parser error message
|
197
230
|
# @return [Boolean] - return true if this is a multiline input, false otherwise
|
198
|
-
def multiline_input?(
|
199
|
-
case
|
231
|
+
def multiline_input?(data)
|
232
|
+
case data.message
|
200
233
|
when /Syntax error at end of/i
|
201
234
|
true
|
202
235
|
else
|
@@ -211,7 +244,7 @@ or "help" to show the help screen.
|
|
211
244
|
# input
|
212
245
|
def read_loop
|
213
246
|
line_number = 1
|
214
|
-
full_buffer =
|
247
|
+
full_buffer = ''
|
215
248
|
while buf = Readline.readline("#{line_number}:#{extra_prompt}>> ", true)
|
216
249
|
begin
|
217
250
|
full_buffer += buf
|
@@ -222,14 +255,14 @@ or "help" to show the help screen.
|
|
222
255
|
parser.parse_string(full_buffer)
|
223
256
|
rescue Puppet::ParseErrorWithIssue => e
|
224
257
|
if multiline_input?(e)
|
225
|
-
out_buffer.print
|
258
|
+
out_buffer.print ' '
|
226
259
|
full_buffer += "\n"
|
227
260
|
next
|
228
261
|
end
|
229
262
|
end
|
230
263
|
end
|
231
264
|
handle_input(full_buffer)
|
232
|
-
full_buffer =
|
265
|
+
full_buffer = ''
|
233
266
|
end
|
234
267
|
end
|
235
268
|
end
|
@@ -251,7 +284,7 @@ or "help" to show the help screen.
|
|
251
284
|
repl_obj.out_buffer.puts print_repl_desc unless options[:quiet]
|
252
285
|
repl_obj.handle_input(options[:content]) if options[:content]
|
253
286
|
# TODO: make the output optional so we can have different output destinations
|
254
|
-
repl_obj.handle_input(
|
287
|
+
repl_obj.handle_input('whereami') if options[:source_file] && options[:source_line]
|
255
288
|
repl_obj.handle_input("play #{options[:play]}") if options[:play]
|
256
289
|
repl_obj.read_loop unless options[:run_once]
|
257
290
|
end
|
@@ -262,10 +295,15 @@ or "help" to show the help screen.
|
|
262
295
|
# @param [Hash] puppet scope object
|
263
296
|
def self.start(options = { scope: nil })
|
264
297
|
opts = Trollop.options do
|
265
|
-
opt :play,
|
266
|
-
opt :run_once,
|
267
|
-
opt :node_name,
|
268
|
-
opt :
|
298
|
+
opt :play, 'Url or file to load from', required: false, type: String
|
299
|
+
opt :run_once, 'Evaluate and quit', required: false, default: false
|
300
|
+
opt :node_name, 'Remote Node to grab facts from', required: false, type: String
|
301
|
+
opt :catalog, 'Import a catalog file to inspect', required: false, type: String
|
302
|
+
opt :quiet, 'Do not display banner', required: false, default: false
|
303
|
+
end
|
304
|
+
if !STDIN.tty? && !STDIN.closed?
|
305
|
+
options[:run_once] = true
|
306
|
+
options[:quiet] = true
|
269
307
|
end
|
270
308
|
options = opts.merge(options)
|
271
309
|
options[:play] = options[:play].path if options[:play].respond_to?(:path)
|
@@ -273,14 +311,14 @@ or "help" to show the help screen.
|
|
273
311
|
repl_obj.out_buffer.puts print_repl_desc unless options[:quiet]
|
274
312
|
if options[:play]
|
275
313
|
repl_obj.handle_input("play #{options[:play]}")
|
276
|
-
elsif ARGF.filename
|
277
|
-
# when the user supplied a file name without using the args (stdin)
|
278
|
-
path = File.expand_path(ARGF.filename)
|
279
|
-
repl_obj.handle_input("play #{path}")
|
280
|
-
elsif (ARGF.filename == "-") && (!STDIN.tty? && !STDIN.closed?)
|
314
|
+
elsif (ARGF.filename == '-') && (!STDIN.tty? && !STDIN.closed?)
|
281
315
|
# when the user supplied a file content using stdin, aka. cat,pipe,echo or redirection
|
282
316
|
input = ARGF.read
|
283
317
|
repl_obj.handle_input(input)
|
318
|
+
elsif ARGF.filename != '-'
|
319
|
+
# when the user supplied a file name without using the args (stdin)
|
320
|
+
path = File.expand_path(ARGF.filename)
|
321
|
+
repl_obj.handle_input("play #{path}")
|
284
322
|
end
|
285
323
|
# helper code to make tests exit the loop
|
286
324
|
repl_obj.read_loop unless options[:run_once]
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
class CodeFile
|
@@ -10,18 +9,18 @@ class CodeFile
|
|
10
9
|
# List of all supported languages.
|
11
10
|
# @return [Hash]
|
12
11
|
EXTENSIONS = {
|
13
|
-
%w[.py]
|
14
|
-
%w[.js]
|
15
|
-
%w[.pp]
|
16
|
-
%w[.css]
|
17
|
-
%w[.xml]
|
18
|
-
%w[.php]
|
19
|
-
%w[.html]
|
20
|
-
%w[.diff]
|
21
|
-
%w[.java]
|
22
|
-
%w[.json]
|
23
|
-
%w[.c .h]
|
24
|
-
%w[.rhtml]
|
12
|
+
%w[.py] => :python,
|
13
|
+
%w[.js] => :javascript,
|
14
|
+
%w[.pp] => :puppet,
|
15
|
+
%w[.css] => :css,
|
16
|
+
%w[.xml] => :xml,
|
17
|
+
%w[.php] => :php,
|
18
|
+
%w[.html] => :html,
|
19
|
+
%w[.diff] => :diff,
|
20
|
+
%w[.java] => :java,
|
21
|
+
%w[.json] => :json,
|
22
|
+
%w[.c .h] => :c,
|
23
|
+
%w[.rhtml] => :rhtml,
|
25
24
|
%w[.yaml .yml] => :yaml,
|
26
25
|
%w[.cpp .hpp .cc .h cxx] => :cpp,
|
27
26
|
%w[.rb .ru .irbrc .gemspec .pryrc] => :ruby
|
@@ -96,4 +95,4 @@ class CodeFile
|
|
96
95
|
def from_load_path
|
97
96
|
$LOAD_PATH.map { |path| File.expand_path(@filename, path) }
|
98
97
|
end
|
99
|
-
|
98
|
+
end
|
@@ -47,13 +47,15 @@ class DebuggerCode
|
|
47
47
|
|
48
48
|
# @return [Integer]
|
49
49
|
def find_start_index(lines)
|
50
|
-
return start_line if start_line
|
50
|
+
return start_line if start_line.negative?
|
51
|
+
|
51
52
|
lines.index { |loc| loc.lineno >= start_line } || lines.length
|
52
53
|
end
|
53
54
|
|
54
55
|
# @return [Integer]
|
55
56
|
def find_end_index(lines)
|
56
|
-
return end_line if end_line
|
57
|
+
return end_line if end_line.negative?
|
58
|
+
|
57
59
|
(lines.index { |loc| loc.lineno > end_line } || 0) - 1
|
58
60
|
end
|
59
61
|
|
@@ -66,4 +68,4 @@ class DebuggerCode
|
|
66
68
|
@start_line = start_line.first
|
67
69
|
end
|
68
70
|
end
|
69
|
-
|
71
|
+
end
|
@@ -164,6 +164,7 @@ class DebuggerCode
|
|
164
164
|
# @return [Code]
|
165
165
|
def grep(pattern)
|
166
166
|
return self unless pattern
|
167
|
+
|
167
168
|
pattern = Regexp.new(pattern)
|
168
169
|
|
169
170
|
select do |loc|
|
@@ -238,6 +239,7 @@ class DebuggerCode
|
|
238
239
|
|
239
240
|
def add_file_reference
|
240
241
|
return "From inline code: \n" unless filename
|
242
|
+
|
241
243
|
"From file: #{File.basename(filename)}\n"
|
242
244
|
end
|
243
245
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puppet-debugger/support/errors'
|
2
4
|
|
3
5
|
module PuppetDebugger
|
@@ -18,7 +20,7 @@ module PuppetDebugger
|
|
18
20
|
end
|
19
21
|
|
20
22
|
# Ensure that duplicates have their @hooks object.
|
21
|
-
def initialize_copy(
|
23
|
+
def initialize_copy(_orig)
|
22
24
|
hooks_dup = @hooks.dup
|
23
25
|
@hooks.each do |k, v|
|
24
26
|
hooks_dup[k] = v.dup
|
@@ -37,8 +39,9 @@ module PuppetDebugger
|
|
37
39
|
# @return [PuppetDebugger::Hooks] The receiver.
|
38
40
|
# @see {#merge}
|
39
41
|
def merge!(other)
|
40
|
-
@hooks.merge!(other.dup.hooks) do |
|
41
|
-
temp_hash
|
42
|
+
@hooks.merge!(other.dup.hooks) do |_key, array, other_array|
|
43
|
+
temp_hash = {}
|
44
|
+
output = []
|
42
45
|
|
43
46
|
(array + other_array).reverse_each do |pair|
|
44
47
|
temp_hash[pair.first] ||= output.unshift(pair)
|
@@ -57,7 +60,7 @@ module PuppetDebugger
|
|
57
60
|
# @return [PuppetDebugger::Hooks] a new `PuppetDebugger::Hooks` instance containing a merge of the
|
58
61
|
# contents of two `PuppetDebugger::Hooks` instances.
|
59
62
|
def merge(other)
|
60
|
-
|
63
|
+
dup.tap do |v|
|
61
64
|
v.merge!(other)
|
62
65
|
end
|
63
66
|
end
|
@@ -68,7 +71,7 @@ module PuppetDebugger
|
|
68
71
|
# @param [#call] callable The callable.
|
69
72
|
# @yield The block to use as the callable (if no `callable` provided).
|
70
73
|
# @return [PuppetDebugger::Hooks] The receiver.
|
71
|
-
def add_hook(event_name, hook_name, callable=nil, &block)
|
74
|
+
def add_hook(event_name, hook_name, callable = nil, &block)
|
72
75
|
event_name = event_name.to_s
|
73
76
|
|
74
77
|
# do not allow duplicates, but allow multiple `nil` hooks
|
@@ -77,12 +80,10 @@ module PuppetDebugger
|
|
77
80
|
raise ArgumentError, "Hook with name '#{hook_name}' already defined!"
|
78
81
|
end
|
79
82
|
|
80
|
-
if !block && !callable
|
81
|
-
raise ArgumentError, "Must provide a block or callable."
|
82
|
-
end
|
83
|
+
raise ArgumentError, 'Must provide a block or callable.' if !block && !callable
|
83
84
|
|
84
85
|
# ensure we only have one anonymous hook
|
85
|
-
@hooks[event_name].delete_if { |h,
|
86
|
+
@hooks[event_name].delete_if { |h, _k| h.nil? } if hook_name.nil?
|
86
87
|
|
87
88
|
if block
|
88
89
|
@hooks[event_name] << [hook_name, block]
|
@@ -98,7 +99,7 @@ module PuppetDebugger
|
|
98
99
|
# @param [Array] args The arguments to pass to each hook function.
|
99
100
|
# @return [Object] The return value of the last executed hook.
|
100
101
|
def exec_hook(event_name, *args, &block)
|
101
|
-
@hooks[event_name.to_s].map do |
|
102
|
+
@hooks[event_name.to_s].map do |_hook_name, callable|
|
102
103
|
begin
|
103
104
|
callable.call(*args, &block)
|
104
105
|
rescue PuppetDebugger::Exception::Error, ::RuntimeError => e
|
@@ -118,10 +119,10 @@ module PuppetDebugger
|
|
118
119
|
# @param [Symbol] hook_name The name of the hook
|
119
120
|
# @return [#call] a specific hook for a given event.
|
120
121
|
def get_hook(event_name, hook_name)
|
121
|
-
hook = @hooks[event_name.to_s].find do |current_hook_name,
|
122
|
+
hook = @hooks[event_name.to_s].find do |current_hook_name, _callable|
|
122
123
|
current_hook_name == hook_name
|
123
124
|
end
|
124
|
-
hook
|
125
|
+
hook&.last
|
125
126
|
end
|
126
127
|
|
127
128
|
# @param [Symbol] event_name The name of the event.
|
@@ -167,8 +168,6 @@ module PuppetDebugger
|
|
167
168
|
|
168
169
|
protected
|
169
170
|
|
170
|
-
|
171
|
-
@hooks
|
172
|
-
end
|
171
|
+
attr_reader :hooks
|
173
172
|
end
|
174
|
-
end
|
173
|
+
end
|