Class: Inspec::Shell
- Inherits:
-
Object
- Object
- Inspec::Shell
- Defined in:
- lib/inspec/shell.rb
Overview
A pry based shell for inspec. Given a runner (with a configured backend and all that jazz), this shell will produce a pry shell from which you can run inspec/ruby commands that will be run within the context of the runner.
Instance Method Summary collapse
-
#configure_pry ⇒ Object
rubocop:disable Metrics/AbcSize.
- #help(resource = nil) ⇒ Object
-
#initialize(runner) ⇒ Shell
constructor
A new instance of Shell.
- #intro ⇒ Object
- #mark(x) ⇒ Object
- #print_example(example) ⇒ Object
- #readline_ignore(code) ⇒ Object
- #resources ⇒ Object
- #start ⇒ Object
Constructor Details
#initialize(runner) ⇒ Shell
Returns a new instance of Shell.
13 14 15 |
# File 'lib/inspec/shell.rb', line 13 def initialize(runner) @runner = runner end |
Instance Method Details
#configure_pry ⇒ Object
rubocop:disable Metrics/AbcSize
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/inspec/shell.rb', line 33 def configure_pry # rubocop:disable Metrics/AbcSize # Remove all hooks and checks Pry.hooks.clear_all that = self # Add the help command Pry::Commands.block_command 'help', 'Show examples' do |resource| that.help(resource) end # configure pry shell prompt Pry.config.prompt_name = 'inspec' Pry.prompt = [proc { "#{readline_ignore("\e[0;32m")}#{Pry.config.prompt_name}> #{readline_ignore("\e[0m")}" }] # Add a help menu as the default intro Pry.hooks.add_hook(:before_session, 'inspec_intro') do intro end # Track the rules currently registered and what their merge count is. Pry.hooks.add_hook(:before_eval, 'inspec_before_eval') do @current_eval_rules = @ctx.rules.each_with_object({}) do |(rule_id, rule), h| h[rule_id] = Inspec::Rule.merge_count(rule) end @runner.reset end # After pry has evaluated a commanding within the binding context of a # test file, register all the rules it discovered. Pry.hooks.add_hook(:after_eval, 'inspec_after_eval') do @current_eval_new_tests = @runner.register_rules(@ctx) do |rule_id, rule| @current_eval_rules[rule_id] != Inspec::Rule.merge_count(rule) end @runner.run if @current_eval_new_tests end # Don't print out control class inspection when the user uses DSL methods. # Instead produce a result of evaluating their control. Pry.config.print = proc do |_output_, value, pry| next if @current_eval_new_tests pry.pager.open do |pager| pager.print pry.config.output_prefix Pry::ColorPrinter.pp(value, pager, Pry::Terminal.width! - 1) end end end |
#help(resource = nil) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/inspec/shell.rb', line 108 def help(resource = nil) if resource.nil? ctx = @runner.backend puts <<EOF Available commands: `[resource]` - run resource on target machine `help resources` - show all available resources that can be used as commands `help [resource]` - information about a specific resource `exit` - exit the InSpec shell You can use resources in this environment to test the target machine. For example: command('uname -a').stdout file('/proc/cpuinfo').content => "value", You are currently running on: OS platform: #{mark ctx.os[:name] || 'unknown'} OS family: #{mark ctx.os[:family] || 'unknown'} OS release: #{mark ctx.os[:release] || 'unknown'} EOF elsif resource == 'resources' resources elsif !Inspec::Resource.registry[resource].nil? puts <<EOF #{mark 'Name:'} #{resource} #{mark 'Description:'} #{Inspec::Resource.registry[resource].desc} #{mark 'Example:'} #{print_example(Inspec::Resource.registry[resource].example)} #{mark 'Web Reference:'} https://github.com/chef/inspec/blob/master/docs/resources.rst##{resource} EOF else puts 'Only the following resources are available:' resources end end |
#intro ⇒ Object
102 103 104 105 106 |
# File 'lib/inspec/shell.rb', line 102 def intro puts 'Welcome to the interactive InSpec Shell' puts "To find out how to use it, type: #{mark 'help'}" puts end |
#mark(x) ⇒ Object
85 86 87 |
# File 'lib/inspec/shell.rb', line 85 def mark(x) "#{readline_ignore("\033[1m")}#{x}#{readline_ignore("\033[0m")}" end |
#print_example(example) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/inspec/shell.rb', line 89 def print_example(example) # determine min whitespace that can be removed min = nil example.lines.each do |line| if line.strip.length > 0 # ignore empty lines line_whitespace = line.length - line.lstrip.length min = line_whitespace if min.nil? || line_whitespace < min end end # remove whitespace from each line example.gsub(/\n\s{#{min}}/, "\n") end |
#readline_ignore(code) ⇒ Object
81 82 83 |
# File 'lib/inspec/shell.rb', line 81 def readline_ignore(code) "\001#{code}\002" end |
#resources ⇒ Object
157 158 159 |
# File 'lib/inspec/shell.rb', line 157 def resources puts Inspec::Resource.registry.keys.join(' ') end |
#start ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/inspec/shell.rb', line 17 def start # Create an in-memory empty runner so that we can add tests to it later. # This context lasts for the duration of this "start" method call/pry # session. @ctx = @runner.create_context configure_pry # This will hold a single evaluation binding context as opened within # the instance_eval context of the anonymous class that the profile # context creates to evaluate each individual test file. We want to # pretend like we are constantly appending to the same file and want # to capture the local variable context from inside said class. @ctx_binding = @ctx.load('binding') @ctx_binding.pry end |