puppet-debugger 0.4.1 → 0.4.2

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.
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/Gemfile CHANGED
@@ -11,6 +11,11 @@ group :test do
11
11
  gem "bundler"
12
12
  gem "simplecov", ">= 0"
13
13
  gem 'rake'
14
+ gem 'release_me'
15
+ end
16
+
17
+ group :validate do
18
+ gem 'rubocop'
14
19
  end
15
20
 
16
21
  group :development do
data/Gemfile.lock CHANGED
@@ -2,6 +2,7 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  CFPropertyList (2.2.8)
5
+ ast (2.3.0)
5
6
  awesome_print (1.7.0)
6
7
  coderay (1.1.1)
7
8
  diff-lcs (1.2.5)
@@ -17,6 +18,9 @@ GEM
17
18
  json (1.8.3)
18
19
  json_pure (1.8.3)
19
20
  method_source (0.8.2)
21
+ parser (2.3.2.0)
22
+ ast (~> 2.2)
23
+ powerpack (0.1.1)
20
24
  pry (0.10.4)
21
25
  coderay (~> 1.1.0)
22
26
  method_source (~> 0.8.1)
@@ -25,9 +29,11 @@ GEM
25
29
  facter (> 2.0, < 4)
26
30
  hiera (>= 2.0, < 4)
27
31
  json_pure (~> 1.8)
32
+ rainbow (2.1.0)
28
33
  rake (11.2.2)
29
34
  rdoc (3.12.2)
30
35
  json (~> 1.4)
36
+ release_me (0.1.1)
31
37
  rspec (3.5.0)
32
38
  rspec-core (~> 3.5.0)
33
39
  rspec-expectations (~> 3.5.0)
@@ -41,12 +47,20 @@ GEM
41
47
  diff-lcs (>= 1.2.0, < 2.0)
42
48
  rspec-support (~> 3.5.0)
43
49
  rspec-support (3.5.0)
50
+ rubocop (0.45.0)
51
+ parser (>= 2.3.1.1, < 3.0)
52
+ powerpack (~> 0.1)
53
+ rainbow (>= 1.99.1, < 3.0)
54
+ ruby-progressbar (~> 1.7)
55
+ unicode-display_width (~> 1.0, >= 1.0.1)
56
+ ruby-progressbar (1.8.1)
44
57
  simplecov (0.12.0)
45
58
  docile (~> 1.1.0)
46
59
  json (>= 1.8, < 3)
47
60
  simplecov-html (~> 0.10.0)
48
61
  simplecov-html (0.10.0)
49
62
  slop (3.6.0)
63
+ unicode-display_width (1.1.1)
50
64
 
51
65
  PLATFORMS
52
66
  ruby
@@ -57,10 +71,12 @@ DEPENDENCIES
57
71
  facterdb (~> 0.3)
58
72
  json_pure (<= 2.0.1)
59
73
  pry
60
- puppet (~> 4.3)
74
+ puppet (>= 3.8)
61
75
  rake
62
76
  rdoc (~> 3.12)
77
+ release_me
63
78
  rspec
79
+ rubocop
64
80
  simplecov
65
81
 
66
82
  BUNDLED WITH
data/bin/pdb CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  require_relative '../lib/puppet-debugger'
3
4
 
4
5
  PuppetDebugger::Cli.start
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module AwesomePrint
2
3
  module Puppet
3
4
  def self.included(base)
@@ -10,11 +11,11 @@ module AwesomePrint
10
11
  def cast_with_puppet_resource(object, type)
11
12
  cast = cast_without_puppet_resource(object, type)
12
13
  # check the object to see if it has an acestor (< ) of the specified type
13
- if (defined?(::Puppet::Type)) && (object.class < ::Puppet::Type)
14
+ if defined?(::Puppet::Type) && (object.class < ::Puppet::Type)
14
15
  cast = :puppet_type
15
- elsif (defined?(::Puppet::Pops::Types)) && (object.class < ::Puppet::Pops::Types)
16
+ elsif defined?(::Puppet::Pops::Types) && (object.class < ::Puppet::Pops::Types)
16
17
  cast = :puppet_type
17
- elsif (defined?(::Puppet::Parser::Resource)) && (object.class < ::Puppet::Parser::Resource)
18
+ elsif defined?(::Puppet::Parser::Resource) && (object.class < ::Puppet::Parser::Resource)
18
19
  cast = :puppet_resource
19
20
  elsif /Puppet::Pops::Types/.match(object.class.to_s)
20
21
  cast = :puppet_type
@@ -30,9 +31,9 @@ module AwesomePrint
30
31
  def awesome_puppet_type(object)
31
32
  return '' if object.nil?
32
33
  return object.to_s unless object.respond_to?(:name) && object.respond_to?(:title)
33
- h = object.to_hash.merge(:name => object.name, :title => object.title)
34
+ h = object.to_hash.merge(name: object.name, title: object.title)
34
35
  res_str = awesome_hash(h)
35
- "#{object.class} #{res_str.gsub(':', '')}"
36
+ "#{object.class} #{res_str.delete(':')}"
36
37
  end
37
38
  end
38
39
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'puppet/application'
2
3
  require 'optparse'
3
4
  require 'puppet/util/command_line'
@@ -5,38 +6,38 @@ require 'puppet/util/command_line'
5
6
  class Puppet::Application::Debugger < Puppet::Application
6
7
  attr_reader :use_facterdb, :use_stdin
7
8
 
8
- option("--execute EXECUTE","-e") do |arg|
9
+ option('--execute EXECUTE', '-e') do |arg|
9
10
  options[:code] = arg
10
11
  end
11
12
 
12
- option("--facterdb-filter FILTER") do |arg|
13
+ option('--facterdb-filter FILTER') do |arg|
13
14
  @use_facterdb = true unless options[:node_name]
14
15
  ENV['DEBUGGER_FACTERDB_FILTER'] = arg if arg
15
16
  end
16
17
 
17
- option("--test") do |_arg|
18
+ option('--test') do |_arg|
18
19
  options[:quiet] = true
19
20
  options[:run_once] = true
20
21
  @use_stdin = true
21
22
  end
22
23
 
23
- option("--no-facterdb") { |_arg| @use_facterdb = false }
24
+ option('--no-facterdb') { |_arg| @use_facterdb = false }
24
25
 
25
- option("--log-level LEVEL","-l") do |arg|
26
+ option('--log-level LEVEL', '-l') do |arg|
26
27
  Puppet::Util::Log.level = arg.to_sym
27
28
  end
28
29
 
29
- option("--quiet", "-q") { |_arg| options[:quiet] = true }
30
+ option('--quiet', '-q') { |_arg| options[:quiet] = true }
30
31
 
31
- option("--play URL", "-p") do |arg|
32
+ option('--play URL', '-p') do |arg|
32
33
  options[:play] = arg
33
34
  end
34
35
 
35
- option("--stdin", "-s") { |_arg| @use_stdin = true }
36
+ option('--stdin', '-s') { |_arg| @use_stdin = true }
36
37
 
37
- option("--run-once", '-r') { |_arg| options[:run_once] = true }
38
+ option('--run-once', '-r') { |_arg| options[:run_once] = true }
38
39
 
39
- option("--node-name CERTNAME", '-n') do |arg|
40
+ option('--node-name CERTNAME', '-n') do |arg|
40
41
  @use_facterdb = false
41
42
  options[:node_name] = arg
42
43
  end
@@ -173,7 +174,7 @@ Copyright (c) 2016 NWOps
173
174
 
174
175
  def app_defaults
175
176
  Puppet::Settings.app_defaults_for_run_mode(self.class.run_mode).merge(
176
- :name => name
177
+ name: name
177
178
  )
178
179
  end
179
180
 
@@ -208,26 +209,26 @@ Copyright (c) 2016 NWOps
208
209
  f.write(code_input)
209
210
  end
210
211
  options[:play] = file
211
- elsif command_line.args.length == 0 and use_stdin
212
+ elsif command_line.args.empty? && use_stdin
212
213
  code_input = STDIN.read
213
214
  file = Tempfile.new(['puppet_repl_input', '.pp'])
214
215
  File.open(file, 'w') do |f|
215
216
  f.write(code_input)
216
217
  end
217
218
  options[:play] = file
218
- elsif command_line.args.length > 0
219
+ elsif !command_line.args.empty?
219
220
  manifest = command_line.args.shift
220
221
  raise "Could not find file #{manifest}" unless Puppet::FileSystem.exist?(manifest)
221
- Puppet.warning("Only one file can be used per run. Skipping #{command_line.args.join(', ')}") if command_line.args.size > 0
222
+ Puppet.warning("Only one file can be used per run. Skipping #{command_line.args.join(', ')}") unless command_line.args.empty?
222
223
  options[:play] = file
223
224
  end
224
- if ! use_facterdb and options[:node_name].nil?
225
+ if !use_facterdb && options[:node_name].nil?
225
226
  debug_environment = create_environment(nil)
226
227
  Puppet.notice('Gathering node facts...')
227
228
  node = create_node(debug_environment)
228
229
  scope = create_scope(node)
229
230
  # start_debugger(scope)
230
- options.merge!({:scope => scope})
231
+ options[:scope] = scope
231
232
  end
232
233
  ::PuppetDebugger::Cli.start_without_stdin(options)
233
234
  end
@@ -235,7 +236,7 @@ Copyright (c) 2016 NWOps
235
236
  def create_environment(manifest)
236
237
  configured_environment = Puppet.lookup(:current_environment)
237
238
  manifest ?
238
- configured_environment.override_with(:manifest => manifest) :
239
+ configured_environment.override_with(manifest: manifest) :
239
240
  configured_environment
240
241
  end
241
242
 
@@ -250,7 +251,7 @@ Copyright (c) 2016 NWOps
250
251
  facts.name = Puppet[:node_name_value]
251
252
  end
252
253
 
253
- Puppet.override({:current_environment => environment}, "For puppet debugger") do
254
+ Puppet.override({ current_environment: environment }, 'For puppet debugger') do
254
255
  # Find our Node
255
256
  unless node = Puppet::Node.indirection.find(Puppet[:node_name_value])
256
257
  raise "Could not find node #{Puppet[:node_name_value]}"
@@ -275,10 +276,10 @@ Copyright (c) 2016 NWOps
275
276
 
276
277
  def start_debugger(scope, options = {})
277
278
  if $stdout.isatty
278
- options = options.merge({:scope => scope})
279
+ options = options.merge(scope: scope)
279
280
  # required in order to use convert puppet hash into ruby hash with symbols
280
- options = options.inject({}){|data,(k,v)| data[k.to_sym] = v; data}
281
- #options[:source_file], options[:source_line] = stacktrace.last
281
+ options = options.each_with_object({}) { |(k, v), data| data[k.to_sym] = v; data }
282
+ # options[:source_file], options[:source_line] = stacktrace.last
282
283
  ::PuppetRepl::Cli.start(options)
283
284
  else
284
285
  Puppet.info 'puppet debug: refusing to start the debugger without a tty'
@@ -292,15 +293,14 @@ Copyright (c) 2016 NWOps
292
293
  # for compatibility with older puppet versions
293
294
  # The basics behind this are to find the `.pp` file in the list of loaded code
294
295
  def stacktrace
295
- result = caller().reduce([]) do |memo, loc|
296
+ result = caller.each_with_object([]) do |loc, memo|
296
297
  if loc =~ /\A(.*\.pp)?:([0-9]+):in\s(.*)/
297
298
  # if the file is not found we set to code
298
299
  # and read from Puppet[:code]
299
300
  # $3 is reserved for the stacktrace type
300
- memo << [$1.nil? ? :code : $1, $2.to_i]
301
+ memo << [Regexp.last_match(1).nil? ? :code : Regexp.last_match(1), Regexp.last_match(2).to_i]
301
302
  end
302
303
  memo
303
304
  end.reverse
304
305
  end
305
-
306
306
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'puppet'
2
3
  require 'readline'
3
4
  require 'json'
@@ -9,23 +10,23 @@ module PuppetDebugger
9
10
 
10
11
  attr_accessor :settings, :log_level, :in_buffer, :out_buffer, :html_mode
11
12
 
12
- def initialize(options={})
13
+ def initialize(options = {})
13
14
  @log_level = 'notice'
14
15
  @out_buffer = options[:out_buffer] || $stdout
15
16
  @html_mode = options[:html_mode] || false
16
17
  @source_file = options[:source_file] || nil
17
18
  @source_line_num = options[:source_line] || nil
18
19
  @in_buffer = options[:in_buffer] || $stdin
19
- comp = Proc.new do |s|
20
+ comp = proc do |s|
20
21
  key_words.grep(/^#{Regexp.escape(s)}/)
21
22
  end
22
- Readline.completion_append_character = ""
23
- Readline.basic_word_break_characters = " "
23
+ Readline.completion_append_character = ''
24
+ Readline.basic_word_break_characters = ' '
24
25
  Readline.completion_proc = comp
25
26
  AwesomePrint.defaults = {
26
- :html => @html_mode,
27
- :sort_keys => true,
28
- :indent => 2
27
+ html: @html_mode,
28
+ sort_keys: true,
29
+ indent: 2
29
30
  }
30
31
  do_initialize
31
32
  end
@@ -36,16 +37,16 @@ module PuppetDebugger
36
37
  # list so its not explicitly clear what the keyword
37
38
  variables = scope.to_hash.keys
38
39
  # prepend a :: to topscope variables
39
- scoped_vars = variables.map { |k,v| scope.compiler.topscope.exist?(k) ? "$::#{k}" : "$#{k}" }
40
+ scoped_vars = variables.map { |k, _v| scope.compiler.topscope.exist?(k) ? "$::#{k}" : "$#{k}" }
40
41
  # append a () to functions so we know they are functions
41
- funcs = function_map.keys.map { |k| "#{k.split('::').last}()"}
42
+ funcs = function_map.keys.map { |k| "#{k.split('::').last}()" }
42
43
  (scoped_vars + funcs + static_responder_list).uniq.sort
43
44
  end
44
45
 
45
46
  # looks up the type in the catalog by using the type and title
46
47
  # and returns the resource in ral format
47
48
  def to_resource_declaration(type)
48
- if type.respond_to?(:type_name) and type.respond_to?(:title)
49
+ if type.respond_to?(:type_name) && type.respond_to?(:title)
49
50
  title = type.title
50
51
  type_name = type.type_name
51
52
  elsif type_result = /(\w+)\['?(\w+)'?\]/.match(type.to_s)
@@ -57,13 +58,11 @@ module PuppetDebugger
57
58
  return type
58
59
  end
59
60
  res = scope.catalog.resource(type_name, title)
60
- if res
61
- return res.to_ral
62
- end
61
+ return res.to_ral if res
63
62
  # don't return anything or returns nil if item is not in the catalog
64
63
  end
65
64
 
66
- # ruturns a formatted array
65
+ # returns a formatted array
67
66
  def expand_resource_type(types)
68
67
  output = [types].flatten.map do |t|
69
68
  if t.class.to_s =~ /Puppet::Pops::Types/
@@ -78,9 +77,7 @@ module PuppetDebugger
78
77
  def normalize_output(result)
79
78
  if result.instance_of?(Array)
80
79
  output = expand_resource_type(result)
81
- if output.count == 1
82
- return output.first
83
- end
80
+ return output.first if output.count == 1
84
81
  return output
85
82
  elsif result.class.to_s =~ /Puppet::Pops::Types/
86
83
  return to_resource_declaration(result)
@@ -91,56 +88,54 @@ module PuppetDebugger
91
88
  # this method handles all input and expects a string of text.
92
89
  #
93
90
  def handle_input(input)
94
- raise ArgumentError unless input.instance_of?(String)
95
- begin
96
- output = ''
97
- case input
98
- when /^play|^classification|^whereami|^facterdb_filter|^facts|^vars|^functions|^classes|^resources|^krt|^environment|^reset|^help/
99
- args = input.split(' ')
100
- command = args.shift.to_sym
101
- if self.respond_to?(command)
102
- output = self.send(command, args)
103
- end
104
- return out_buffer.puts output
105
- when /exit/
106
- exit 0
107
- when /^:set/
108
- output = handle_set(input)
109
- when '_'
110
- output = " => #{@last_item}"
111
- else
112
- result = puppet_eval(input)
113
- @last_item = result
114
- output = normalize_output(result)
115
- if output.nil?
116
- output = ""
117
- else
118
- output = output.ai
119
- end
120
- end
121
- rescue LoadError => e
122
- output = e.message.fatal
123
- rescue Errno::ETIMEDOUT => e
124
- output = e.message.fatal
125
- rescue ArgumentError => e
126
- output = e.message.fatal
127
- rescue Puppet::ResourceError => e
128
- output = e.message.fatal
129
- rescue Puppet::Error => e
130
- output = e.message.fatal
131
- rescue Puppet::ParseErrorWithIssue => e
132
- output = e.message.fatal
133
- rescue PuppetDebugger::Exception::FatalError => e
134
- output = e.message.fatal
135
- out_buffer.puts output
136
- exit 1 # this can sometimes causes tests to fail
137
- rescue PuppetDebugger::Exception::Error => e
138
- output = e.message.fatal
139
- end
140
- unless output.empty?
141
- out_buffer.print " => "
142
- out_buffer.puts output unless output.empty?
91
+ raise ArgumentError unless input.instance_of?(String)
92
+ begin
93
+ output = ''
94
+ case input
95
+ when /^play|^classification|^whereami|^facterdb_filter|^facts|^vars|^functions|^classes|^resources|^krt|^environment|^reset|^help/
96
+ args = input.split(' ')
97
+ command = args.shift.to_sym
98
+ output = send(command, args) if respond_to?(command)
99
+ return out_buffer.puts output
100
+ when /exit/
101
+ exit 0
102
+ when /^:set/
103
+ output = handle_set(input)
104
+ when '_'
105
+ output = " => #{@last_item}"
106
+ else
107
+ result = puppet_eval(input)
108
+ @last_item = result
109
+ output = normalize_output(result)
110
+ output = if output.nil?
111
+ ''
112
+ else
113
+ output.ai
114
+ end
143
115
  end
116
+ rescue LoadError => e
117
+ output = e.message.fatal
118
+ rescue Errno::ETIMEDOUT => e
119
+ output = e.message.fatal
120
+ rescue ArgumentError => e
121
+ output = e.message.fatal
122
+ rescue Puppet::ResourceError => e
123
+ output = e.message.fatal
124
+ rescue Puppet::Error => e
125
+ output = e.message.fatal
126
+ rescue Puppet::ParseErrorWithIssue => e
127
+ output = e.message.fatal
128
+ rescue PuppetDebugger::Exception::FatalError => e
129
+ output = e.message.fatal
130
+ out_buffer.puts output
131
+ exit 1 # this can sometimes causes tests to fail
132
+ rescue PuppetDebugger::Exception::Error => e
133
+ output = e.message.fatal
134
+ end
135
+ unless output.empty?
136
+ out_buffer.print ' => '
137
+ out_buffer.puts output unless output.empty?
138
+ end
144
139
  end
145
140
 
146
141
  def self.print_repl_desc
@@ -195,15 +190,17 @@ Type "exit", "functions", "vars", "krt", "whereami", "facts", "resources", "clas
195
190
  end
196
191
  end
197
192
 
198
- # used to start a repl without attempting to read from stdin
193
+ # used to start a debugger session without attempting to read from stdin
199
194
  # or
195
+ # this is primarily used by the debug::break() module function and the puppet debugger face
200
196
  # @param [Hash] must contain at least the puppet scope object
201
- def self.start_without_stdin(options={:scope => nil})
197
+ def self.start_without_stdin(options = { scope: nil })
202
198
  puts print_repl_desc unless options[:quiet]
203
199
  repl_obj = PuppetDebugger::Cli.new(options)
204
200
  repl_obj.remote_node_name = options[:node_name] if options[:node_name]
205
201
  repl_obj.initialize_from_scope(options[:scope])
206
- puts repl_obj.whereami if options[:source_file] and options[:source_line]
202
+ # TODO: make the output optional so we can have different output destinations
203
+ puts repl_obj.whereami if options[:source_file] && options[:source_line]
207
204
  repl_obj.play_back(options) if options[:play]
208
205
  repl_obj.read_loop unless options[:run_once]
209
206
  end
@@ -212,12 +209,12 @@ Type "exit", "functions", "vars", "krt", "whereami", "facts", "resources", "clas
212
209
  # if from stdin, the repl will process the input and exit
213
210
  # if from a file, the repl will process the file and continue to prompt
214
211
  # @param [Hash] puppet scope object
215
- def self.start(options={:scope => nil})
216
- opts = Trollop::options do
217
- opt :play, "Url or file to load from", :required => false, :type => String
218
- opt :run_once, "Evaluate and quit", :required => false, :default => false
219
- opt :node_name, "Remote Node to grab facts from", :required => false, :type => String
220
- opt :quiet, "Do not display banner", :required => false, :default => false
212
+ def self.start(options = { scope: nil })
213
+ opts = Trollop.options do
214
+ opt :play, 'Url or file to load from', required: false, type: String
215
+ opt :run_once, 'Evaluate and quit', required: false, default: false
216
+ opt :node_name, 'Remote Node to grab facts from', required: false, type: String
217
+ opt :quiet, 'Do not display banner', required: false, default: false
221
218
  end
222
219
  options = opts.merge(options)
223
220
  puts print_repl_desc unless options[:quiet]
@@ -227,18 +224,16 @@ Type "exit", "functions", "vars", "krt", "whereami", "facts", "resources", "clas
227
224
  if options[:play]
228
225
  repl_obj.play_back(opts)
229
226
  # when the user supplied a file name without using the args (stdin)
230
- elsif ARGF.filename != "-"
227
+ elsif ARGF.filename != '-'
231
228
  path = File.expand_path(ARGF.filename)
232
- repl_obj.play_back(:play => path)
229
+ repl_obj.play_back(play: path)
233
230
  # when the user supplied a file content using stdin, aka. cat,pipe,echo or redirection
234
- elsif ARGF.filename == "-" and (not STDIN.tty? and not STDIN.closed?)
231
+ elsif (ARGF.filename == '-') && (!STDIN.tty? && !STDIN.closed?)
235
232
  input = ARGF.read
236
233
  repl_obj.handle_input(input)
237
234
  end
238
235
  # helper code to make tests exit the loop
239
- unless options[:run_once]
240
- repl_obj.read_loop
241
- end
236
+ repl_obj.read_loop unless options[:run_once]
242
237
  end
243
238
  end
244
239
  end