puppet-debugger 0.15.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +21 -45
  3. data/.rubocop.yml +64 -233
  4. data/.rubocop_todo.yml +89 -147
  5. data/.ruby-version +1 -1
  6. data/.vscode/launch.json +15 -0
  7. data/CHANGELOG.md +34 -2
  8. data/Gemfile +7 -5
  9. data/README.md +29 -261
  10. data/Rakefile +11 -12
  11. data/bin/pdb +1 -1
  12. data/lib/awesome_print/ext/awesome_puppet.rb +22 -8
  13. data/lib/plugins/puppet-debugger/input_responders/benchmark.rb +5 -4
  14. data/lib/plugins/puppet-debugger/input_responders/classes.rb +14 -2
  15. data/lib/plugins/puppet-debugger/input_responders/classification.rb +4 -2
  16. data/lib/plugins/puppet-debugger/input_responders/commands.rb +18 -18
  17. data/lib/plugins/puppet-debugger/input_responders/datatypes.rb +22 -6
  18. data/lib/plugins/puppet-debugger/input_responders/environment.rb +4 -2
  19. data/lib/plugins/puppet-debugger/input_responders/exit.rb +4 -2
  20. data/lib/plugins/puppet-debugger/input_responders/facterdb_filter.rb +4 -2
  21. data/lib/plugins/puppet-debugger/input_responders/facts.rb +4 -2
  22. data/lib/plugins/puppet-debugger/input_responders/functions.rb +34 -32
  23. data/lib/plugins/puppet-debugger/input_responders/help.rb +4 -2
  24. data/lib/plugins/puppet-debugger/input_responders/krt.rb +4 -2
  25. data/lib/plugins/puppet-debugger/input_responders/play.rb +22 -24
  26. data/lib/plugins/puppet-debugger/input_responders/reset.rb +5 -3
  27. data/lib/plugins/puppet-debugger/input_responders/resources.rb +16 -7
  28. data/lib/plugins/puppet-debugger/input_responders/set.rb +34 -32
  29. data/lib/plugins/puppet-debugger/input_responders/stacktrace.rb +23 -0
  30. data/lib/plugins/puppet-debugger/input_responders/types.rb +6 -2
  31. data/lib/plugins/puppet-debugger/input_responders/vars.rb +8 -7
  32. data/lib/plugins/puppet-debugger/input_responders/whereami.rb +5 -3
  33. data/lib/puppet-debugger.rb +1 -45
  34. data/lib/puppet-debugger/cli.rb +120 -92
  35. data/lib/puppet-debugger/code/code_file.rb +13 -14
  36. data/lib/puppet-debugger/code/code_range.rb +5 -3
  37. data/lib/puppet-debugger/code/loc.rb +1 -1
  38. data/lib/puppet-debugger/debugger_code.rb +2 -0
  39. data/lib/puppet-debugger/hooks.rb +15 -16
  40. data/lib/puppet-debugger/input_responder_plugin.rb +54 -52
  41. data/lib/puppet-debugger/monkey_patches.rb +57 -0
  42. data/lib/puppet-debugger/plugin_test_helper.rb +9 -8
  43. data/lib/puppet-debugger/support.rb +27 -17
  44. data/lib/puppet-debugger/support/environment.rb +10 -3
  45. data/lib/puppet-debugger/support/errors.rb +25 -27
  46. data/lib/puppet-debugger/support/facts.rb +5 -5
  47. data/lib/puppet-debugger/support/node.rb +4 -7
  48. data/lib/puppet-debugger/support/scope.rb +29 -0
  49. data/lib/puppet-debugger/trollop.rb +38 -31
  50. data/lib/puppet-debugger/version.rb +1 -1
  51. data/lib/puppet/application/debugger.rb +151 -126
  52. data/output.json +1 -0
  53. data/puppet-debugger.gemspec +17 -15
  54. data/spec/awesome_print/ext/awesome_puppet_spec.rb +30 -30
  55. data/spec/fixtures/pe-xl-core-0.puppet.vm.json +1 -0
  56. data/spec/fixtures/sample_start_debugger.pp +3 -2
  57. data/spec/hooks_spec.rb +33 -35
  58. data/spec/input_responder_plugin_spec.rb +7 -6
  59. data/spec/input_responders/benchmark_spec.rb +3 -1
  60. data/spec/input_responders/classes_spec.rb +12 -13
  61. data/spec/input_responders/classification_spec.rb +4 -2
  62. data/spec/input_responders/commands_spec.rb +2 -0
  63. data/spec/input_responders/datatypes_spec.rb +8 -2
  64. data/spec/input_responders/environment_spec.rb +2 -0
  65. data/spec/input_responders/exit_spec.rb +9 -11
  66. data/spec/input_responders/facterdb_filter_spec.rb +2 -0
  67. data/spec/input_responders/facts_spec.rb +2 -0
  68. data/spec/input_responders/functions_spec.rb +30 -28
  69. data/spec/input_responders/help_spec.rb +5 -3
  70. data/spec/input_responders/krt_spec.rb +3 -1
  71. data/spec/input_responders/play_spec.rb +10 -20
  72. data/spec/input_responders/reset_spec.rb +2 -0
  73. data/spec/input_responders/resources_spec.rb +7 -1
  74. data/spec/input_responders/set_spec.rb +3 -1
  75. data/spec/input_responders/stacktrace_spec.rb +15 -0
  76. data/spec/input_responders/types_spec.rb +2 -0
  77. data/spec/input_responders/vars_spec.rb +4 -4
  78. data/spec/input_responders/whereami_spec.rb +2 -0
  79. data/spec/pdb_spec.rb +0 -9
  80. data/spec/puppet/application/debugger_spec.rb +35 -17
  81. data/spec/puppet_debugger_spec.rb +81 -83
  82. data/spec/remote_node_spec.rb +1 -5
  83. data/spec/spec_helper.rb +22 -18
  84. data/spec/support_spec.rb +3 -5
  85. data/test_matrix.rb +1 -1
  86. metadata +53 -19
@@ -1,31 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
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
-
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
- Puppet.settings[:trusted_server_facts] = true unless Puppet.settings[:trusted_server_facts].nil?
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
- @log_level = "notice"
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,13 +34,13 @@ 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
  }
44
45
  end
45
46
 
@@ -50,11 +51,12 @@ module PuppetDebugger
50
51
  proc do |input|
51
52
  words = Readline.line_buffer.split(Readline.basic_word_break_characters)
52
53
  next key_words.grep(/^#{Regexp.escape(input)}/) if words.empty?
54
+
53
55
  first_word = words.shift
54
56
  plugins = PuppetDebugger::InputResponders::Commands.plugins.find_all do |p|
55
57
  p::COMMAND_WORDS.find { |word| word.start_with?(first_word) }
56
58
  end
57
- if plugins.count == 1 and /\A#{first_word}\s/.match(Readline.line_buffer)
59
+ if (plugins.count == 1) && /\A#{first_word}\s/.match(Readline.line_buffer)
58
60
  plugins.first.command_completion(words)
59
61
  else
60
62
  key_words.grep(/^#{Regexp.escape(input)}/)
@@ -76,7 +78,8 @@ module PuppetDebugger
76
78
  PuppetDebugger::InputResponders::Functions.instance.debugger = self
77
79
  funcs = PuppetDebugger::InputResponders::Functions.instance.func_list
78
80
  PuppetDebugger::InputResponders::Datatypes.instance.debugger = self
79
- (scoped_vars + funcs + static_responder_list + PuppetDebugger::InputResponders::Datatypes.instance.all_data_types).uniq.sort
81
+ (scoped_vars + funcs + static_responder_list +
82
+ PuppetDebugger::InputResponders::Datatypes.instance.all_data_types).uniq.sort
80
83
  end
81
84
 
82
85
  # looks up the type in the catalog by using the type and title
@@ -106,7 +109,7 @@ module PuppetDebugger
106
109
  end
107
110
 
108
111
  def contains_resources?(result)
109
- !Array(result).flatten.find { |r| r.class.to_s =~ /Puppet::Pops::Types/ }.nil?
112
+ !Array(result).flatten.find { |r| r.class.to_s =~ /Puppet::Pops::Types::PResourceType/ }.nil?
110
113
  end
111
114
 
112
115
  def normalize_output(result)
@@ -116,87 +119,107 @@ module PuppetDebugger
116
119
  # if the only output is a resource then return it
117
120
  # otherwise it is multiple items or an actually array
118
121
  return output.first if output.count == 1
122
+
119
123
  return output
120
124
  end
121
125
  result
122
126
  end
123
127
 
124
128
  def responder_list
125
- plugins = Pluginator.find(PuppetDebugger)
129
+ Pluginator.find(PuppetDebugger)
130
+ end
131
+
132
+ # @return [TTY::Pager] the pager object, disable if CI or testing is present
133
+ def pager
134
+ @pager ||= TTY::Pager.new(output: out_buffer, enabled: pager_enabled?)
135
+ end
136
+
137
+ def pager_enabled?
138
+ ENV['CI'].nil?
139
+ end
140
+
141
+ # @param output [String] - the content to output
142
+ # @summary outputs the output to the output buffer
143
+ # uses the pager if the screen height is less than the height of the
144
+ # output content
145
+ # Disabled if CI or testing is being done
146
+ def handle_output(output)
147
+ return if output.nil?
148
+ if pager_enabled? && output.lines.count >= TTY::Screen.height
149
+ output << "\n"
150
+ pager.page(output)
151
+ else
152
+ out_buffer.puts(output) unless output.empty?
153
+ end
126
154
  end
127
155
 
128
156
  # this method handles all input and expects a string of text.
129
- #
157
+ # @param input [String] - the input content to parse or run
130
158
  def handle_input(input)
131
159
  raise ArgumentError unless input.instance_of?(String)
132
- begin
133
- output = ""
134
- case input.strip
135
- when PuppetDebugger::InputResponders::Commands.command_list_regex
136
- args = input.split(" ")
137
- command = args.shift
138
- plugin = PuppetDebugger::InputResponders::Commands.plugin_from_command(command)
139
- output = plugin.execute(args, self)
140
- return out_buffer.puts output
141
- when "_"
142
- output = " => #{@last_item}"
143
- else
144
- result = puppet_eval(input)
145
- @last_item = result
146
- output = normalize_output(result)
147
- output = output.nil? ? "" : output.ai
160
+
161
+ output =
162
+ begin
163
+ case input.strip
164
+ when PuppetDebugger::InputResponders::Commands.command_list_regex
165
+ args = input.split(' ')
166
+ command = args.shift
167
+ plugin = PuppetDebugger::InputResponders::Commands.plugin_from_command(command)
168
+ plugin.execute(args, self) || ''
169
+ when '_'
170
+ " => #{@last_item}"
171
+ else
172
+ result = puppet_eval(input)
173
+ @last_item = result
174
+ o = normalize_output(result)
175
+ o.nil? ? '' : o.ai
176
+ end
177
+ rescue PuppetDebugger::Exception::InvalidCommand => e
178
+ e.message.fatal
179
+ rescue LoadError => e
180
+ e.message.fatal
181
+ rescue Errno::ETIMEDOUT => e
182
+ e.message.fatal
183
+ rescue ArgumentError => e
184
+ e.message.fatal
185
+ rescue Puppet::ResourceError => e
186
+ e.message.fatal
187
+ rescue Puppet::Error => e
188
+ e.message.fatal
189
+ rescue Puppet::ParseErrorWithIssue => e
190
+ e.message.fatal
191
+ rescue PuppetDebugger::Exception::FatalError => e
192
+ handle_output(e.message.fatal)
193
+ exit 1 # this can sometimes causes tests to fail
194
+ rescue PuppetDebugger::Exception::Error => e
195
+ e.message.fatal
196
+ rescue ::RuntimeError => e
197
+ handle_output(e.message.fatal)
198
+ exit 1
148
199
  end
149
- rescue PuppetDebugger::Exception::InvalidCommand => e
150
- output = e.message.fatal
151
- rescue LoadError => e
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
200
+ output = OUT_SYMBOL + output unless output.empty?
201
+ handle_output(output)
202
+ exec_hook :after_output, out_buffer, self, self
179
203
  end
180
204
 
181
205
  def self.print_repl_desc
182
- output = <<-EOT
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.
206
+ <<~OUT
207
+ Ruby Version: #{RUBY_VERSION}
208
+ Puppet Version: #{Puppet.version}
209
+ Puppet Debugger Version: #{PuppetDebugger::VERSION}
210
+ Created by: NWOps <corey@nwops.io>
211
+ Type "commands" for a list of debugger commands
212
+ or "help" to show the help screen.
189
213
 
190
214
 
191
- EOT
192
- output
215
+ OUT
193
216
  end
194
217
 
195
218
  # tries to determine if the input is going to be a multiline input
196
219
  # by reading the parser error message
197
220
  # @return [Boolean] - return true if this is a multiline input, false otherwise
198
- def multiline_input?(e)
199
- case e.message
221
+ def multiline_input?(data)
222
+ case data.message
200
223
  when /Syntax error at end of/i
201
224
  true
202
225
  else
@@ -211,7 +234,7 @@ or "help" to show the help screen.
211
234
  # input
212
235
  def read_loop
213
236
  line_number = 1
214
- full_buffer = ""
237
+ full_buffer = ''
215
238
  while buf = Readline.readline("#{line_number}:#{extra_prompt}>> ", true)
216
239
  begin
217
240
  full_buffer += buf
@@ -222,14 +245,14 @@ or "help" to show the help screen.
222
245
  parser.parse_string(full_buffer)
223
246
  rescue Puppet::ParseErrorWithIssue => e
224
247
  if multiline_input?(e)
225
- out_buffer.print " "
248
+ out_buffer.print ' '
226
249
  full_buffer += "\n"
227
250
  next
228
251
  end
229
252
  end
230
253
  end
231
254
  handle_input(full_buffer)
232
- full_buffer = ""
255
+ full_buffer = ''
233
256
  end
234
257
  end
235
258
  end
@@ -251,7 +274,7 @@ or "help" to show the help screen.
251
274
  repl_obj.out_buffer.puts print_repl_desc unless options[:quiet]
252
275
  repl_obj.handle_input(options[:content]) if options[:content]
253
276
  # TODO: make the output optional so we can have different output destinations
254
- repl_obj.handle_input("whereami") if options[:source_file] && options[:source_line]
277
+ repl_obj.handle_input('whereami') if options[:source_file] && options[:source_line]
255
278
  repl_obj.handle_input("play #{options[:play]}") if options[:play]
256
279
  repl_obj.read_loop unless options[:run_once]
257
280
  end
@@ -262,10 +285,15 @@ or "help" to show the help screen.
262
285
  # @param [Hash] puppet scope object
263
286
  def self.start(options = { scope: nil })
264
287
  opts = Trollop.options do
265
- opt :play, "Url or file to load from", required: false, type: String
266
- opt :run_once, "Evaluate and quit", required: false, default: false
267
- opt :node_name, "Remote Node to grab facts from", required: false, type: String
268
- opt :quiet, "Do not display banner", required: false, default: false
288
+ opt :play, 'Url or file to load from', required: false, type: String
289
+ opt :run_once, 'Evaluate and quit', required: false, default: false
290
+ opt :node_name, 'Remote Node to grab facts from', required: false, type: String
291
+ opt :catalog, 'Import a catalog file to inspect', required: false, type: String
292
+ opt :quiet, 'Do not display banner', required: false, default: false
293
+ end
294
+ if !STDIN.tty? && !STDIN.closed?
295
+ options[:run_once] = true
296
+ options[:quiet] = true
269
297
  end
270
298
  options = opts.merge(options)
271
299
  options[:play] = options[:play].path if options[:play].respond_to?(:path)
@@ -273,14 +301,14 @@ or "help" to show the help screen.
273
301
  repl_obj.out_buffer.puts print_repl_desc unless options[:quiet]
274
302
  if options[:play]
275
303
  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?)
304
+ elsif (ARGF.filename == '-') && (!STDIN.tty? && !STDIN.closed?)
281
305
  # when the user supplied a file content using stdin, aka. cat,pipe,echo or redirection
282
306
  input = ARGF.read
283
307
  repl_obj.handle_input(input)
308
+ elsif ARGF.filename != '-'
309
+ # when the user supplied a file name without using the args (stdin)
310
+ path = File.expand_path(ARGF.filename)
311
+ repl_obj.handle_input("play #{path}")
284
312
  end
285
313
  # helper code to make tests exit the loop
286
314
  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] => :python,
14
- %w[.js] => :javascript,
15
- %w[.pp] => :puppet,
16
- %w[.css] => :css,
17
- %w[.xml] => :xml,
18
- %w[.php] => :php,
19
- %w[.html] => :html,
20
- %w[.diff] => :diff,
21
- %w[.java] => :java,
22
- %w[.json] => :json,
23
- %w[.c .h] => :c,
24
- %w[.rhtml] => :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
- end
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 < 0
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 < 0
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
- end
71
+ end
@@ -76,4 +76,4 @@ class DebuggerCode
76
76
  tuple[0] = "#{' ' * distance}#{line}"
77
77
  end
78
78
  end
79
- end
79
+ 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(orig)
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 |key, array, other_array|
41
- temp_hash, output = {}, []
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
- self.dup.tap do |v|
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, k| h.nil? } if hook_name.nil?
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 |hook_name, callable|
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, callable|
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.last if 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
- def hooks
171
- @hooks
172
- end
171
+ attr_reader :hooks
173
172
  end
174
- end
173
+ end