Merge pull request #5836 from inspec/nm/init-plugin-streaming-reporter

CFINSPEC-43 Init plugin functionality extended for streaming_reporter
This commit is contained in:
Clinton Wolfe 2022-02-16 09:43:38 -05:00 committed by GitHub
commit ac4d3fad6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 1 deletions

View file

@ -45,10 +45,13 @@ Generates an InSpec plugin, which can extend the functionality of InSpec itself.
`--detail` This option can be used to skip generation of test files or gemspec file. Available values `full`, `core` or `test-fixture`.
`--activator` Available activator type are `cli_command` and `reporter`. The default activator type is "cli_command".
`--activator` Available activator type are `cli_command`, `reporter` and `streaming_reporter`. The default activator type is "cli_command".
Usage: `inspec init pluign <inspec-plugin-name> --activator "cli_command:my_test"`
`OR`
`inspec init plugin <inspec-plugin-reporter-name> --activator "reporter:my_reporter"`
`OR`
`inspec init plugin <inspec-plugin-streaming-reporter-name> --activator "streaming_reporter:my_streaming_reporter"`
**Note:** The InSpec plugin generator can currently only generate one activator of each type.

View file

@ -81,6 +81,7 @@ module InspecPlugins
File.join("lib", "inspec-plugin-template.erb") => File.join("lib", plugin_name + ".rb"),
File.join("lib", "inspec-plugin-template", "cli_command.erb") => File.join("lib", plugin_name, "cli_command.rb"),
File.join("lib", "inspec-plugin-template", "reporter.erb") => File.join("lib", plugin_name, "reporter.rb"),
File.join("lib", "inspec-plugin-template", "streaming_reporter.erb") => File.join("lib", plugin_name, "streaming_reporter.rb"),
File.join("lib", "inspec-plugin-template", "plugin.erb") => File.join("lib", plugin_name, "plugin.rb"),
File.join("lib", "inspec-plugin-template", "version.erb") => File.join("lib", plugin_name, "version.rb"),
File.join("test", "functional", "inspec_plugin_template_test.erb") => File.join("test", "functional", snake_case + "_test.rb"),
@ -183,6 +184,9 @@ module InspecPlugins
elsif activators_by_type.key?(:reporter)
vars[:reporter_name_dashes] = activators_by_type[:reporter].tr("_", "-")
vars[:reporter_name_snake] = activators_by_type[:reporter].tr("-", "_")
elsif activators_by_type.key?(:streaming_reporter)
vars[:streaming_reporter_name_dashes] = activators_by_type[:streaming_reporter].tr("_", "-")
vars[:streaming_reporter_name_snake] = activators_by_type[:streaming_reporter].tr("-", "_")
end
vars
end
@ -267,6 +271,11 @@ module InspecPlugins
File.join("lib", "inspec-plugin-template", "reporter.erb"),
]
end
unless requested_activators.include?(:streaming_reporter)
skips += [
File.join("lib", "inspec-plugin-template", "streaming_reporter.erb"),
]
end
skips.uniq
end

View file

@ -66,6 +66,22 @@ module InspecPlugins
InspecPlugins::<%= module_name %>::Reporter
end
<% end %>
<% if activators[:streaming_reporter] %>
# Define a new Streaming Reporter.
# The argument here will be used to match against the CLI --reporter option.
# `--reporter <%= streaming_reporter_name_snake %>` will load your streaming reporter and perform streaming real-time on each passing, failing or pending test.
streaming_reporter :<%= streaming_reporter_name_snake %> do
# Calling this activator doesn't mean the reporter is being executed - just
# that we should be ready to do so. So, load the file that defines the
# functionality.
require "<%= plugin_name %>/streaming_reporter"
# Having loaded our functionality, return a class that will let the
# reporting engine tap into it.
InspecPlugins::<%= module_name %>::StreamingReporter
end
<% end %>
end
end
end

View file

@ -0,0 +1,31 @@
module InspecPlugins::<%= module_name %>
# This class will provide the actual Streaming Reporter implementation.
# Its superclass is provided by another call to Inspec.plugin,
# this time with two args. The first arg specifies we are requesting
# version 2 of the Plugins API. The second says we are making a
# Streaming Reporter plugin component, so please make available any DSL needed
# for that.
class StreamingReporter < Inspec.plugin(2, :streaming_reporter)
# Registering these methods with RSpec::Core::Formatters class is mandatory
RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending
def initialize(output)
@output = output
end
def example_passed(notification) # ExampleNotification
# some logic to run on passing test case
end
def example_failed(notification) # FailedExampleNotification
# some logic to run on failing test case
end
def example_pending(notification) # ExampleNotification
# some logic to run on pending test case
end
end
end

View file

@ -178,4 +178,73 @@ class InitPluginCli < Minitest::Test
end
end
def test_generating_inspec_plugin_with_streaming_reporter_activator
Dir.mktmpdir do |dir|
plugin = "inspec-test-generated-plugin"
module_name = plugin.sub(/^inspec\-/, "").split("-").map(&:capitalize).join("")
opts = ""
opts += " --author-email nikita@example.com "
opts += " --author-name Nikita "
opts += ' --copyright "Copyright © 2022 Nikita" '
opts += ' --description "That you will really like" '
opts += " --license-name BSD-3-Clause "
opts += ' --summary "A fantastic plugin" '
opts += " --homepage http://example.com "
opts += " --activator streaming_reporter:test_cli_stream"
run_result = run_inspec_process("init plugin #{plugin} --no-prompt #{opts}", prefix: "cd #{dir} &&")
assert_includes run_result.stdout, "Creating new inspec plugin at"
assert_includes run_result.stdout, plugin
assert_empty run_result.stderr
assert_exit_code 0, run_result
# Check generated files and contents.
# Each file must exist, and its contents must match each of the regexen given.
{
File.join(plugin, "README.md") => [],
File.join(plugin, "LICENSE") => [
/Copyright . 2022 Nikita/,
/used to endorse or promote/,
],
File.join(plugin, "Gemfile") => [],
File.join(plugin, "Rakefile") => [],
File.join(plugin, plugin + ".gemspec") => [
/spec\.version\s+=\s+InspecPlugins::TestGeneratedPlugin::VERSION/,
/spec\.authors\s+=\s+\["Nikita"\]/,
/spec\.email\s+=\s+\["nikita@example\.com"\]/,
/spec\.summary\s+=\s+"A fantastic plugin"/,
/spec\.description\s+=\s+"That you will really like"/,
%r{spec\.homepage\s+=\s+"http://example.com"},
/spec\.license\s+=\s+"BSD-3-Clause"/,
],
File.join(plugin, "lib", plugin + ".rb") => [],
File.join(plugin, "lib", plugin, "plugin.rb") => [
%r{require\s"#{plugin}/version"},
/module\s#{module_name}/,
/plugin_name\s+:"#{plugin}"/,
/streaming_reporter :test_cli_stream/,
%r{require\s"#{plugin}/streaming_reporter"},
/InspecPlugins::#{module_name}::StreamingReporter/,
],
File.join(plugin, "lib", plugin, "version.rb") => [],
File.join(plugin, "lib", plugin, "streaming_reporter.rb") => [],
File.join(plugin, "test", "unit", "plugin_def_test.rb") => [],
}.each do |path, regexen|
full_path = File.join(dir, path)
assert(File.exist?(full_path), "#{path} should have been generated")
next if regexen.empty?
contents = File.read(full_path)
regexen.each do |re|
assert_match re, contents, "#{path} should match #{re}"
end
end
end
end
end