Class: Inspec::Plugin::V2::Loader

Inherits:
Object
  • Object
show all
Extended by:
FilterPredicates
Includes:
FilterPredicates
Defined in:
lib/inspec/plugin/v2/loader.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FilterPredicates

inspec_plugin_name?, train_plugin_name?, valid_plugin_name?

Constructor Details

#initialize(options = {}) ⇒ Loader

Returns a new instance of Loader.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/inspec/plugin/v2/loader.rb', line 19

def initialize(options = {})
  @options = options
  @registry = Inspec::Plugin::V2::Registry.instance

  # User plugins are those installed by the user via `inspec plugin install`
  # and are installed under ~/.inspec/gems
  unless options[:omit_user_plugins]
    @conf_file = Inspec::Plugin::V2::ConfigFile.new
    read_conf_file_into_registry
  end

  # Old-style (v0, v1) co-distributed plugins were called 'bundles'
  # and were located in lib/bundles
  detect_bundled_plugins unless options[:omit_bundles]

  # New-style (v2) co-distributed plugins are in lib/plugins,
  # and may be safely loaded
  detect_core_plugins unless options[:omit_core_plugins]

  # Identify plugins that inspec is co-installed with
  detect_system_plugins unless options[:omit_sys_plugins]
end

Instance Attribute Details

#conf_fileObject (readonly)

Returns the value of attribute conf_file.



13
14
15
# File 'lib/inspec/plugin/v2/loader.rb', line 13

def conf_file
  @conf_file
end

#optionsObject (readonly)

Returns the value of attribute options.



13
14
15
# File 'lib/inspec/plugin/v2/loader.rb', line 13

def options
  @options
end

#registryObject (readonly)

Returns the value of attribute registry.



13
14
15
# File 'lib/inspec/plugin/v2/loader.rb', line 13

def registry
  @registry
end

Class Method Details

.list_installed_plugin_gemsArray[Gem::Specification]

Lists all plugin gems found in the plugin_gem_path. This is simply all gems that begin with train- or inspec- and are not on the exclusion list.

Returns:

  • (Array[Gem::Specification])

    Specs of all gems found.



143
144
145
# File 'lib/inspec/plugin/v2/loader.rb', line 143

def self.list_installed_plugin_gems
  list_managed_gems.select { |spec| valid_plugin_name?(spec.name) }
end

.list_managed_gemsArray[Gem::Specification]

Lists all gems found in the plugin_gem_path.

Returns:

  • (Array[Gem::Specification])

    Specs of all gems found.



131
132
133
# File 'lib/inspec/plugin/v2/loader.rb', line 131

def self.list_managed_gems
  Dir.glob(File.join(plugin_gem_path, "specifications", "*.gemspec")).map { |p| Gem::Specification.load(p) }
end

.plugin_gem_pathObject



122
123
124
125
126
127
# File 'lib/inspec/plugin/v2/loader.rb', line 122

def self.plugin_gem_path
  require "rbconfig"
  ruby_abi_version = RbConfig::CONFIG["ruby_version"]
  # TODO: why are we installing under the api directory for plugins?
  File.join(Inspec.config_dir, "gems", ruby_abi_version)
end

Instance Method Details

#activate_mentioned_cli_plugins(cli_args = ARGV) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/inspec/plugin/v2/loader.rb', line 91

def activate_mentioned_cli_plugins(cli_args = ARGV)
  # Get a list of CLI plugin activation hooks
  registry.find_activators(plugin_type: :cli_command).each do |act|
    next if act.activated?

    # Decide whether to activate.  Several conditions, so split them out for clarity.
    # Assume no, to start.  Each condition may flip it true, which will short-circuit
    # all following ||= ops.
    activate_me = false

    # If the user invoked `inspec help`, `inspec --help`, or only `inspec`
    # then activate all CLI plugins so they can display their usage message.
    activate_me ||= ["help", "--help", nil].include?(cli_args.first)

    # If there is anything in the CLI args with the same name, activate it.
    # This is the expected usual activation for individual plugins.
    # `inspec dosomething` => activate the :dosomething hook
    activate_me ||= cli_args.include?(act.activator_name.to_s)

    # OK, activate.
    if activate_me
      act.activate
      act.implementation_class.register_with_thor
    end
  end
end

#exit_on_load_errorObject

This should possibly be in either lib/inspec/cli.rb or Registry



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/inspec/plugin/v2/loader.rb', line 75

def exit_on_load_error
  if registry.any_load_failures?
    Inspec::Log.error "Errors were encountered while loading plugins..."
    registry.plugin_statuses.select(&:load_exception).each do |plugin_status|
      Inspec::Log.error "Plugin name: " + plugin_status.name.to_s
      Inspec::Log.error "Error: " + plugin_status.load_exception.message
      if ARGV.include?("--debug")
        Inspec::Log.error "Exception: " + plugin_status.load_exception.class.name
        Inspec::Log.error "Trace: " + plugin_status.load_exception.backtrace.join("\n")
      end
    end
    Inspec::Log.error("Run again with --debug for a stacktrace.") unless ARGV.include?("--debug")
    exit 2
  end
end

#list_installed_plugin_gemsObject



147
148
149
# File 'lib/inspec/plugin/v2/loader.rb', line 147

def list_installed_plugin_gems
  self.class.list_managed_gems
end

#list_managed_gemsObject



135
136
137
# File 'lib/inspec/plugin/v2/loader.rb', line 135

def list_managed_gems
  self.class.list_managed_gems
end

#load_allObject



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
# File 'lib/inspec/plugin/v2/loader.rb', line 42

def load_all
  # This fixes the gem paths on some bundles
  Gem.path << plugin_gem_path
  Gem.refresh

  # Be careful not to actually iterate directly over the registry here;
  # we want to allow "sidecar loading", in which case a plugin may add an entry to the registry.
  registry.plugin_names.dup.each do |plugin_name|
    plugin_details = registry[plugin_name]
    # We want to capture literally any possible exception here, since we are storing them.
    # rubocop: disable Lint/RescueException
    begin
      # We could use require, but under testing, we need to repeatedly reload the same
      # plugin.  However, gems only work with require (rubygems dooes not overload `load`)
      if plugin_details.installation_type == :user_gem
        activate_managed_gems_for_plugin(plugin_name)
        require plugin_details.entry_point
      else
        load_path = plugin_details.entry_point
        load_path += ".rb" unless plugin_details.entry_point.end_with?(".rb")
        load load_path
      end
      plugin_details.loaded = true
      annotate_status_after_loading(plugin_name)
    rescue ::Exception => ex
      plugin_details.load_exception = ex
      Inspec::Log.error "Could not load plugin #{plugin_name}: #{ex.message}"
    end
    # rubocop: enable Lint/RescueException
  end
end

#plugin_gem_pathObject



118
119
120
# File 'lib/inspec/plugin/v2/loader.rb', line 118

def plugin_gem_path
  self.class.plugin_gem_path
end