Merge pull request #5536 from inspec/vasundhara/update-inspec-init-plugin

Update inspec init plugin
This commit is contained in:
Clinton Wolfe 2021-05-31 18:06:39 -04:00 committed by GitHub
commit e841b576ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 201 additions and 131 deletions

View file

@ -0,0 +1,54 @@
# About `inspec init plugin` cli command
## Purpose
`inspec init plugin` generates the scaffold of InSpec plugin, which can extend the functionality of InSpec itself.
## Operational Notes
### Generating InSpec Plugin
`inspec init plugin --help`
```
Usage:
inspec init plugin PLUGIN_NAME [options]
Options:
[--prompt], [--no-prompt] # Interactively prompt for information to put in your generated plugin.
# Default: true
[--detail=DETAIL] # How detailed of a plugin to generate. 'full' is a normal full gem with tests; 'core' has tests but no gemspec; 'test-fixture' is stripped down for a test fixture.
# Default: full
[--author-email=AUTHOR_EMAIL] # Author Email for gemspec
# Default: you@example.com
[--author-name=AUTHOR_NAME] # Author Name for gemspec
# Default: Your Name
[--description=DESCRIPTION] # Multi-line description of the plugin
[--summary=SUMMARY] # One-line summary of your plugin
# Default: A plugin with a default summary
[--license-name=LICENSE_NAME] # The name of a license
# Default: Apache-2.0
[--activator=one two three] # A list of plugin activator, in the form type1:name1, type2:name2, etc
# Default: ["cli_command:my_command"]
[--hook=one two three] # Legacy name for --activator - Deprecated.
[--homepage=HOMEPAGE] # A URL for your project, often a GitHub link
[--module-name=MODULE_NAME] # Module Name for your plugin package. Will change plugin name to CamelCase by default.
[--copyright=COPYRIGHT] # A copyright statement, to be added to LICENSE
[--log-level=LOG_LEVEL] # Set the log level: info (default), debug, warn, error
[--log-location=LOG_LOCATION] # Location to send diagnostic log messages to. (default: $stdout or Inspec::Log.error)
Generates an InSpec plugin, which can extend the functionality of InSpec itself.
```
### Options
`inspec init plugin` command requires few details about the plugin to be added. This can be added using command line prompt or by passing them as the options like for e.g `--author-name`,`--author-email`, `--description`, --module-name etc.
`--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".
Usage: `inspec init pluign <inspec-plugin-name> --activator "cli_command:my_test"`
`OR`
`inspec init plugin <inspec-plugin-reporter-name> --activator "reporter:my_reporter"`
**Note:** The InSpec plugin generator can currently only generate one activator of each type.
`--hook` Legacy name for `--activator` - Deprecated.

View file

@ -120,6 +120,11 @@
"object_classes": {
"action": "warn",
"suffix": "These classes will be removed in InSpec 5.0."
},
"cli_option_hook":{
"action": "warn",
"prefix": "The --hook option is being replaced by the --activator option.",
"suffix": "This options will be removed in InSpec 4.0."
}
}
}

View file

@ -17,7 +17,8 @@ module InspecPlugins
option :description, type: :string, default: "", desc: "Multi-line description of the plugin"
option :summary, type: :string, default: "A plugin with a default summary", desc: "One-line summary of your plugin"
option :license_name, type: :string, default: "Apache-2.0", desc: "The name of a license"
option :hook, type: :array, default: ["cli_command:my_command"], desc: "A list of plugin hooks, in the form type1:name1, type2:name2, etc"
option :activator, type: :array, default: ["cli_command:my_command"], desc: "A list of plugin activators, in the form type1:name1, type2:name2, etc"
option :hook, type: :array, desc: "Legacy name for --activator - Deprecated."
# These vars have calculated defaults
option :homepage, type: :string, default: nil, desc: "A URL for your project, often a GitHub link"
option :module_name, type: :string, default: nil, desc: "Module Name for your plugin package. Will change plugin name to CamelCase by default."
@ -29,6 +30,12 @@ module InspecPlugins
plugin_type = determine_plugin_type(plugin_name)
snake_case = plugin_name.tr("-", "_")
# Handle deprecation of option --hook
unless options[:hook].nil?
Inspec.deprecate "cli_option_hook"
options[:activator] = options.delete(:hook)
end
template_vars = {
name: plugin_name,
plugin_name: plugin_name,
@ -41,7 +48,7 @@ module InspecPlugins
templates_path: TEMPLATES_PATH,
overwrite: options[:overwrite],
file_rename_map: make_rename_map(plugin_type, plugin_name, snake_case),
skip_files: make_skip_list(template_vars["hooks"].keys),
skip_files: make_skip_list(template_vars["activators"].keys),
}
renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
@ -71,12 +78,15 @@ module InspecPlugins
{
"inspec-plugin-template.gemspec" => plugin_name + ".gemspec",
File.join("lib", "inspec-plugin-template") => File.join("lib", plugin_name),
File.join("lib", "inspec-plugin-template.rb") => File.join("lib", plugin_name + ".rb"),
File.join("lib", "inspec-plugin-template", "cli_command.rb") => File.join("lib", plugin_name, "cli_command.rb"),
File.join("lib", "inspec-plugin-template", "reporter.rb") => File.join("lib", plugin_name, "reporter.rb"),
File.join("lib", "inspec-plugin-template", "plugin.rb") => File.join("lib", plugin_name, "plugin.rb"),
File.join("lib", "inspec-plugin-template", "version.rb") => File.join("lib", plugin_name, "version.rb"),
File.join("test", "functional", "inspec_plugin_template_test.rb") => File.join("test", "functional", snake_case + "_test.rb"),
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", "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"),
File.join("test", "unit", "cli_args_test.erb") => File.join("test", "unit", "cli_args_test.rb"),
File.join("test", "unit", "plugin_def_test.erb") => File.join("test", "unit", "plugin_def_test.rb"),
File.join("test", "helper.erb") => File.join("test", "helper.rb"),
}
end
@ -93,7 +103,7 @@ module InspecPlugins
ui.error("You requested interactive prompting for the template variables, but this does not seem to be an interactive terminal.")
ui.exit(:usage_error)
end
vars.merge(parse_hook_option(options[:hook]))
vars.merge(parse_activator_option(options[:activator]))
end
def vars_from_defaults
@ -121,7 +131,7 @@ module InspecPlugins
],
},
homepage: { default_setter: proc { options[:homepage] ||= "https://github.com/" + options[:author_email].split("@").first + "/" + options[:plugin_name] } },
# TODO: Handle hooks, when we ever have more than one type of plugin
# TODO: Handle activators, when we ever have more than one type of plugin
}
prompt_for_options(order)
@ -153,26 +163,26 @@ module InspecPlugins
end
end
def parse_hook_option(raw_option)
hooks_by_type = {}
def parse_activator_option(raw_option)
activators_by_type = {}
raw_option.each do |entry|
parts = entry.split(":")
type = parts.first.to_sym
name = parts.last
if hooks_by_type.key?(type)
ui.error "The InSpec plugin generator can currently only generate one hook of each type"
if activators_by_type.key?(type)
ui.error "The InSpec plugin generator can currently only generate one activator of each type"
ui.exit(:usage_error)
end
hooks_by_type[type] = name
activators_by_type[type] = name
end
vars = { hooks: hooks_by_type }
if hooks_by_type.key?(:cli_command)
vars[:command_name_dashes] = hooks_by_type[:cli_command].tr("_", "-")
vars[:command_name_snake] = hooks_by_type[:cli_command].tr("-", "_")
elsif hooks_by_type.key?(:reporter)
vars[:reporter_name_dashes] = hooks_by_type[:reporter].tr("_", "-")
vars[:reporter_name_snake] = hooks_by_type[:reporter].tr("-", "_")
vars = { activators: activators_by_type }
if activators_by_type.key?(:cli_command)
vars[:command_name_dashes] = activators_by_type[:cli_command].tr("_", "-")
vars[:command_name_snake] = activators_by_type[:cli_command].tr("-", "_")
elsif activators_by_type.key?(:reporter)
vars[:reporter_name_dashes] = activators_by_type[:reporter].tr("_", "-")
vars[:reporter_name_snake] = activators_by_type[:reporter].tr("-", "_")
end
vars
end
@ -210,7 +220,7 @@ module InspecPlugins
end
end
def make_skip_list(requested_hooks)
def make_skip_list(requested_activators)
skips = []
case options[:detail]
when "full" # rubocop: disable Lint/EmptyWhen
@ -230,13 +240,13 @@ module InspecPlugins
"Rakefile",
File.join("test", "fixtures", "README.md"),
File.join("test", "fixtures"),
File.join("test", "functional", "inspec_plugin_template_test.rb"),
File.join("test", "functional", "inspec_plugin_template_test.erb"),
File.join("test", "functional", "README.md"),
File.join("test", "unit", "cli_args_test.rb"),
File.join("test", "unit", "plugin_def_test.rb"),
File.join("test", "unit", "cli_args_test.erb"),
File.join("test", "unit", "plugin_def_test.erb"),
File.join("test", "unit", "README.md"),
File.join("test", "unit"),
File.join("test", "helper.rb"),
File.join("test", "helper.erb"),
File.join("test"),
]
else
@ -244,17 +254,17 @@ module InspecPlugins
ui.exit(:usage_error)
end
# Remove hook-specific files
unless requested_hooks.include?(:cli_command)
# Remove activator-specific files
unless requested_activators.include?(:cli_command)
skips += [
File.join("lib", "inspec-plugin-template", "cli_command.rb"),
File.join("test", "unit", "cli_args_test.rb"),
File.join("test", "functional", "inspec_plugin_template_test.rb"),
File.join("lib", "inspec-plugin-template", "cli_command.erb"),
File.join("test", "unit", "cli_args_test.erb"),
File.join("test", "functional", "inspec_plugin_template_test.erb"),
]
end
unless requested_hooks.include?(:reporter)
unless requested_activators.include?(:reporter)
skips += [
File.join("lib", "inspec-plugin-template", "reporter.rb"),
File.join("lib", "inspec-plugin-template", "reporter.erb"),
]
end

View file

@ -65,6 +65,7 @@ module InspecPlugins
# read & render content
content = render(File.read(source_file), template_values)
# write file content
File.write(full_destination_item_path, content)
else
ui.warning "Ignoring #{ui.emphasis(source_file)}, because its not an file or directoy"

View file

@ -1,11 +1,11 @@
source 'https://rubygems.org'
source "https://rubygems.org"
gemspec
group :development do
gem 'bundler'
gem 'byebug'
gem 'minitest'
gem 'rake'
gem 'rubocop', '= 0.49.1' # Need to keep in sync with main InSpec project, so config files will work
gem "bundler"
gem "byebug"
gem "minitest"
gem "rake"
gem "rubocop", "= 0.49.1" # Need to keep in sync with main InSpec project, so config files will work
end

View file

@ -7,13 +7,13 @@
# This task template will make a task named 'test', and run
# the tests that it finds.
require 'rake/testtask'
require "rake/testtask"
Rake::TestTask.new do |t|
t.libs.push 'lib'
t.libs.push "lib"
t.test_files = FileList[
'test/unit/*_test.rb',
'test/functional/*_test.rb',
"test/unit/*_test.rb",
"test/functional/*_test.rb",
]
t.verbose = true
# Ideally, we'd run tests with warnings enabled,
@ -26,15 +26,15 @@ end
#------------------------------------------------------------------#
# Code Style Tasks
#------------------------------------------------------------------#
require 'rubocop/rake_task'
require "rubocop/rake_task"
RuboCop::RakeTask.new(:lint) do |t|
# Choices of RuboCop rules to enforce are deeply personal.
# Here, we set things up so that your plugin will use the Bundler-installed
# inspec gem's copy of the InSpec project's rubocop.yml file (which
# is indeed packaged with the inspec gem).
require 'inspec/globals'
inspec_rubocop_yml = File.join(Inspec.src_root, '.rubocop.yml')
require "inspec/globals"
inspec_rubocop_yml = File.join(Inspec.src_root, ".rubocop.yml")
t.options = ['--display-cop-names', '--config', inspec_rubocop_yml]
t.options = ["--display-cop-names", "--config", inspec_rubocop_yml]
end

View file

@ -4,23 +4,23 @@
# It is traditional in a gemspec to dynamically load the current version
# from a file in the source tree. The next three lines make that happen.
lib = File.expand_path('../lib', __FILE__)
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require '<%= plugin_name %>/version'
require "<%= plugin_name %>/version"
Gem::Specification.new do |spec|
# Importantly, all InSpec plugins must be prefixed with `inspec-` (most
# plugins) or `train-` (plugins which add new connectivity features).
spec.name = '<%= plugin_name %>'
spec.name = "<%= plugin_name %>"
# It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
spec.version = InspecPlugins::<%= module_name %>::VERSION
spec.authors = ['<%= author_name %>']
spec.email = ['<%= author_email %>']
spec.summary = '<%= summary %>'
spec.description = '<%= description %>'
spec.homepage = '<%= homepage %>'
spec.license = '<%= license_name %>'
spec.authors = ["<%= author_name %>"]
spec.email = ["<%= author_email %>"]
spec.summary = "<%= summary %>"
spec.description = "<%= description.is_a?(Array) ? description.join(" "): description %>"
spec.homepage = "<%= homepage %>"
spec.license = "<%= license_name %>"
# Though complicated-looking, this is pretty standard for a gemspec.
# It just filters what will actually be packaged in the gem (leaving
@ -28,9 +28,9 @@ Gem::Specification.new do |spec|
spec.files = %w{
README.md <%= snake_case %>.gemspec Gemfile
} + Dir.glob(
'lib/**/*', File::FNM_DOTMATCH
"lib/**/*", File::FNM_DOTMATCH
).reject { |f| File.directory?(f) }
spec.require_paths = ['lib']
spec.require_paths = ["lib"]
# If you rely on any other gems, list them here with any constraints.
# This is how `inspec plugin install` is able to manage your dependencies.
@ -39,5 +39,5 @@ Gem::Specification.new do |spec|
# All plugins should mention inspec, > 2.2.78
# 2.2.78 included the v2 Plugin API
spec.add_dependency 'inspec', '>=2.2.78', '<4.0.0'
spec.add_dependency "inspec", ">= 2.2.78", "< 4.0.0"
end

View file

@ -11,4 +11,4 @@
libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
require '<%= plugin_name %>/plugin'
require "<%= plugin_name %>/plugin"

View file

@ -1,4 +1,4 @@
require 'inspec/resource'
require "inspec/resource"
module InspecPlugins::<%= module_name %>
# This class will provide the actual CLI implementation.
@ -21,31 +21,31 @@ module InspecPlugins::<%= module_name %>
# Note: if you want your command (or subcommand) to have dashes in it,
# use underscores where you want a dash, and Thor will convert them.
# Thor will fail to find a command that is directly named with dashes.
subcommand_desc '<%= command_name_snake %> [COMMAND]', 'Your Usage Message Here'
subcommand_desc "<%= command_name_snake %> [COMMAND]", "Your Usage Message Here"
# The usual rhythm for a Thor CLI file is description, options, command method.
# Thor just has you call DSL methods in sequence prior to each command.
# Let's make a command, 'do_something'. This will then be available
# as `inspec <%= command_name_dashes %> do-something
# as `inspec <%= command_name_dashes %> do-something`
# (Change this method name to be something sensible for your plugin.)
# First, provide a usage / description. This will appear
# in `inspec help <%= command_name_dashes %>`.
# As this is a usage message, you should write the command as it should appear
# to the user (if you want it to have dashes, use dashes)
desc 'do-something WHAT [OPTIONS]', 'Does something'
desc "do-something WHAT [OPTIONS]", "Does something"
# Let's include an option, -s, to summarize
# Refer to the Thors docs; there is a lot you can do here.
option :summary, desc: 'Include a total at the bottom', \
option :summary, desc: "Include a total at the bottom", \
type: :boolean, default: true, aliases: [:s]
# OK, now the actual method itself. If you provide params, you're telling Thor that
# OK, now the actual method itself. If you provide params, you're telling Thor that
# you accept CLI arguments after all options have been consumed.
# Note again that the method name has an underscore, but when invoked
# on the CLI, use a dash.
def do_something(what = 'nothing')
def do_something(what = "nothing")
# The code here will *only* be executed if someone actually
# runs `inspec <%= command_name_dashes %> do-something`.
@ -55,7 +55,7 @@ module InspecPlugins::<%= module_name %>
# Talk to the user using the `ui` object (see Inspec::UI)
# ui.error('Whoops!')
ui.warning('This is a generated plugin with a default implementation. Edit lib/<%= plugin_name %>/cli_command.rb to make it do what you want.')
ui.warning("This is a generated plugin with a default implementation. Edit lib/<%= plugin_name %>/cli_command.rb to make it do what you want.")
ui.exit(:success) # or :usage_error
end
end

View file

@ -1,49 +1,49 @@
# Plugin Definition file
# The purpose of this file is to declare to InSpec what plugin_types (capabilities)
# are included in this plugin, and provide hooks that will load them as needed.
# are included in this plugin, and provide activator that will load them as needed.
# It is important that this file load successfully and *quickly*.
# Your plugin's functionality may never be used on this InSpec run; so we keep things
# fast and light by only loading heavy things when they are needed.
# Presumably this is light
require '<%= plugin_name %>/version'
require "<%= plugin_name %>/version"
# The InspecPlugins namespace is where all plugins should declare themselves.
# The 'Inspec' capitalization is used throughout the InSpec source code; yes, it's
# The "Inspec" capitalization is used throughout the InSpec source code; yes, it's
# strange.
module InspecPlugins
# Pick a reasonable namespace here for your plugin. A reasonable choice
# Pick a reasonable namespace here for your plugin. A reasonable choice
# would be the CamelCase version of your plugin gem name.
# <%= plugin_name %> => <%= module_name %>
module <%= module_name %>
# This simple class handles the plugin definition, so calling it simply Plugin is OK.
# Inspec.plugin returns various Classes, intended to be superclasses for various
# plugin components. Here, the one-arg form gives you the Plugin Definition superclass,
# which mainly gives you access to the hook / plugin_type DSL.
# which mainly gives you access to the activator / plugin_type DSL.
# The number '2' says you are asking for version 2 of the plugin API. If there are
# future versions, InSpec promises plugin API v2 will work for at least two more InSpec
# major versions.
class Plugin < ::Inspec.plugin(2)
# Internal machine name of the plugin. InSpec will use this in errors, etc.
plugin_name :'<%= plugin_name %>'
plugin_name :"<%= plugin_name %>"
<% if hooks[:cli_command] %>
<% if activators[:cli_command] %>
# Define a new CLI subcommand.
# The argument here will be used to match against the command line args,
# and if the user said `inspec list-resources`, this hook will get called.
# Notice that you can define multiple hooks with different names, and they
# and if the user said `inspec list-resources`, this activator will get called.
# Notice that you can define multiple activators with different names, and they
# don't have to match the plugin name.
# We'd like this to be list-resources, but Thor does not support hyphens
# see https://github.com/erikhuda/thor/pull/613
cli_command :<%= command_name_snake %> do
# Calling this hook doesn't mean the subcommand is being executed - just
# Calling this activator doesn't mean the subcommand is being executed - just
# that we should be ready to do so. So, load the file that defines the
# functionality.
# For example, InSpec will activate this hook when `inspec help` is
# For example, InSpec will activate this activator when `inspec help` is
# executed, so that this plugin's usage message will be included in the help.
require '<%= plugin_name %>/cli_command'
require "<%= plugin_name %>/cli_command"
# Having loaded our functionality, return a class that will let the
# CLI engine tap into it.
@ -51,15 +51,15 @@ module InspecPlugins
end
<% end %>
<% if hooks[:reporter] %>
<% if activators[:reporter] %>
# Define a new Reporter.
# The argument here will be used to match against the CLI --reporter option.
# `--reporter <%= reporter_name_snake %>` will load your reporter and call its renderer.
reporter :<%= reporter_name_snake %> do
# Calling this hook doesn't mean the reporter is being executed - just
# 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 %>/reporter'
require "<%= plugin_name %>/reporter"
# Having loaded our functionality, return a class that will let the
# reporting engine tap into it.

View file

@ -3,6 +3,6 @@
# to learn the current version.
module InspecPlugins
module <%= module_name %>
VERSION = '0.1.0'.freeze
VERSION = "0.1.0".freeze
end
end

View file

@ -4,11 +4,11 @@
# Functional tests generally do not have inside knowledge of how the plugin works.
# Include our test harness
require_relative '../helper'
require_relative "../helper"
# Because InSpec is a Spec-style test suite, we're going to use Minitest::Spec
# here, for familiar look and feel. However, this isn't InSpec (or RSpec) code.
describe 'inspec list-resources core' do
describe "inspec list-resources core" do
# Our helper.rb locates this library from the InSpec install that
# Bundler installed for us. If we want its methods, we still must
# import it. Including it here will make it available in all child
@ -40,7 +40,7 @@ describe 'inspec list-resources core' do
# A selection of core resources, just spot checking.
# This is an example of using Ruby to define sets of tests.
['process', 'service', 'user', 'file'].each do |resource_name|
%w(process service user file).each do |resource_name|
it "should mention the '#{resource_name}' resource" do
outcome.stdout.must_include(resource_name)
end
@ -48,7 +48,7 @@ describe 'inspec list-resources core' do
# Check for the summary
it "should mention the summary" do
outcome.stdout.must_include('resources total')
outcome.stdout.must_include("resources total")
end
end
@ -63,12 +63,12 @@ describe 'inspec list-resources core' do
it("should be silent on stderr") { outcome.stderr.must_be_empty }
# Here, we want to know it DID match some things, and NOT some others.
['user', 'users'].each do |resource_name|
%w(user users).each do |resource_name|
it "should mention the '#{resource_name}' resource" do
outcome.stdout.must_include(resource_name)
end
end
['process', 'service', 'file'].each do |resource_name|
%w(process service file).each do |resource_name|
it "should NOT mention the '#{resource_name}' resource" do
outcome.stdout.wont_include(resource_name)
end
@ -89,14 +89,14 @@ describe 'inspec list-resources core' do
# Check for the summary
it "should mention a zero-resource summary" do
outcome.stdout.must_include('0 resources total')
outcome.stdout.must_include("0 resources total")
end
end
# Exercise the summary option, which defaults to 'true'.
describe "when run with the no-summary flag" do
# Alter the command string to include the no-summary option
let(:outcome) { run_inspec_process_with_this_plugin('listresources core --no-summary') }
let(:outcome) { run_inspec_process_with_this_plugin("listresources core --no-summary") }
# Should be well-behaved...
it("should exit successfully") { assert_exit_code 0, outcome }
@ -104,7 +104,7 @@ describe 'inspec list-resources core' do
# Check for the summary
it "should NOT mention summary" do
outcome.stdout.wont_include('0 resources total')
outcome.stdout.wont_include("0 resources total")
end
end
end

View file

@ -6,11 +6,11 @@
# InSpec core provides a number of such libraries and facilities, in the file
# lib/plugins/shared/core_plugin_test_helper.rb . So, one job in this file is
# to locate and load that file.
require 'inspec/../plugins/shared/core_plugin_test_helper'
require "inspec/../plugins/shared/core_plugin_test_helper"
# Also load the InSpec plugin system. We need this so we can unit-test the plugin
# classes, which will rely on the plugin system.
require 'inspec/plugin/v2'
require "inspec/plugin/v2"
# Caution: loading all of InSpec (i.e. require 'inspec') may cause interference with
# minitest/spec; one symptom would be appearing to have no tests.
@ -19,6 +19,6 @@ require 'inspec/plugin/v2'
# You can select from a number of test harnesses. Since InSpec uses Spec-style controls
# in profile code, you will probably want to use something like minitest/spec, which provides
# Spec-style tests.
require 'minitest/autorun' # loads all styles and runs tests automatically
require "minitest/autorun" # loads all styles and runs tests automatically
# You might want to put some debugging tools here. We run tests to find bugs, after all.

View file

@ -3,7 +3,7 @@
## What Tests are Provided?
* plugin_def_test.rb - Would be useful in any plugin. Verifies that the plugin is properly detected and registered.
<% if hooks.key?(:cli_command) %>
<% if activators.key?(:cli_command) %>
* cli_args_test.rb - Tests the CLI options for a CLI Command plugin
<% end %>

View file

@ -2,10 +2,10 @@
# <%= plugin_name %> are correct.
# Include our test harness
require_relative '../helper'
require_relative "../helper"
# Load the class under test, the CliCommand definition.
require '<%= plugin_name %>/cli_command'
require "<%= plugin_name %>/cli_command"
# Because InSpec is a Spec-style test suite, we're going to use Minitest::Spec
# here, for familiar look and feel. However, this isn't InSpec (or RSpec) code.
@ -24,10 +24,10 @@ describe InspecPlugins::<%= module_name %>::CliCommand do
# modify and add to the lines below to test your actual options.
# This is a Hash of Structs that tells us details of options for the 'do_something' subcommand.
let(:do_something_options) { cli_class.all_commands['do_something'].options }
let(:do_something_options) { cli_class.all_commands["do_something"].options }
# To group tests together, you can nest 'describe' in minitest/spec
describe 'the do-something subcommand' do
describe "the do-something subcommand" do
# Some tests through here use minitest Expectations, which attach to all
# Objects, and begin with 'must' (positive) or 'wont' (negative)

View file

@ -2,10 +2,10 @@
# the inspec-resource-lister plugin is configured correctly.
# Include our test harness
require_relative '../helper'
require_relative "../helper"
# Load the class under test, the Plugin definition.
require '<%= plugin_name %>/plugin'
require "<%= plugin_name %>/plugin"
# Because InSpec is a Spec-style test suite, we're going to use Minitest::Spec
# here, for familiar look and feel. However, this isn't InSpec (or RSpec) code.
@ -16,7 +16,7 @@ describe InspecPlugins::<%= module_name %>::Plugin do
# can reference easily.
# Internally, plugins are always known by a Symbol name. Convert here.
let(:plugin_name) { :'<%= plugin_name %>' }
let(:plugin_name) { :"<%= plugin_name %>" }
# The Registry knows about all plugins that ship with InSpec by
# default, as well as any that are installed by the user. When a
@ -43,9 +43,9 @@ describe InspecPlugins::<%= module_name %>::Plugin do
status.api_generation.must_equal(2)
end
# Plugins can support several different activator hooks, each of which has a type.
# Plugins can support several different activator, each of which has a type.
# Since this is (primarily) a CliCommand plugin, we'd expect to see that among our types.
it "should include a cli_command activator hook" do
it "should include a cli_command activator" do
status.plugin_types.must_include(:cli_command)
end
end

View file

@ -45,28 +45,28 @@ class InitPluginCli < Minitest::Test
File.join(plugin, "Gemfile") => [], # No interpolation
File.join(plugin, "Rakefile") => [], # No interpolation
File.join(plugin, plugin + ".gemspec") => [
%r{require '#{plugin}/version'},
/spec\.name\s+=\s+'#{plugin}'/,
%r{require "#{plugin}/version"},
/spec\.name\s+=\s+"#{plugin}"/,
/spec\.version\s+=\s+InspecPlugins::#{module_name}::VERSION/,
/README\.md\s+#{snake_case}\.gemspec\s+Gemfile/,
/spec\.authors\s+=\s+\['Your Name'\]/,
/spec\.email\s+=\s+\['you@example\.com'\]/,
/spec\.summary\s+=\s+'A plugin with a default summary'/,
/spec\.description\s+=\s+''/,
%r{spec\.homepage\s+=\s+'https://github.com/you/#{plugin}'},
/spec\.license\s+=\s+'Apache-2\.0'/,
/spec\.authors\s+=\s+\["Your Name"\]/,
/spec\.email\s+=\s+\["you@example\.com"\]/,
/spec\.summary\s+=\s+"A plugin with a default summary"/,
/spec\.description\s+=\s+""/,
%r{spec\.homepage\s+=\s+"https://github.com/you/#{plugin}},
/spec\.license\s+=\s+"Apache-2\.0"/,
],
File.join(plugin, "lib", plugin + ".rb") => [
%r{require\s'#{plugin}/plugin'},
%r{require\s"#{plugin}/plugin"},
],
File.join(plugin, "lib", plugin, "plugin.rb") => [
%r{require\s'#{plugin}/version'},
%r{require\s"#{plugin}/version"},
/\#\s#{plugin}\s=>\s#{module_name}/,
/module\s#{module_name}/,
/plugin_name\s+:'#{plugin}'/,
# Default assumes one cli hook
/plugin_name\s+:"#{plugin}"/,
# Default assumes one cli activator
/cli_command :my_command/,
%r{require\s'#{plugin}/cli_command'},
%r{require\s"#{plugin}/cli_command"},
/InspecPlugins::#{module_name}::CliCommand/,
],
File.join(plugin, "lib", plugin, "version.rb") => [
@ -75,8 +75,8 @@ class InitPluginCli < Minitest::Test
File.join(plugin, "lib", plugin, "cli_command.rb") => [
/module\sInspecPlugins::#{module_name}/,
/\#\smakes\s`inspec\smy-command\s\.\.\.`\swork\./,
/subcommand_desc\s'my_command\s\[COMMAND\]'/,
/\#\sas\s`inspec\smy-command\sdo-something/,
/subcommand_desc\s"my_command\s\[COMMAND\]"/,
/\#\sas\s`inspec\smy-command\sdo-something`/,
/\#\sin\s`inspec\shelp\smy-command`/,
/\#\sruns\s`inspec\smy-command\sdo-something`./,
%r{Edit\slib/#{plugin}/cli_command\.rb\sto\smake\sit\sdo},
@ -87,12 +87,12 @@ class InitPluginCli < Minitest::Test
# Whatever goes here
],
File.join(plugin, "test", "unit", "plugin_def_test.rb") => [
%r{require\s'#{plugin}/plugin'},
%r{require\s"#{plugin}/plugin"},
/describe InspecPlugins::#{module_name}::Plugin\sdo/,
/let\(:plugin_name\) \{ \:'#{plugin}\' \}/,
/let\(:plugin_name\) \{ \:"#{plugin}\" \}/,
],
File.join(plugin, "test", "unit", "cli_args_test.rb") => [
%r{require '#{plugin}/cli_command'},
%r{require "#{plugin}/cli_command"},
/describe InspecPlugins::#{module_name}::CliCommand do/,
/let\(\:cli_class\) \{ InspecPlugins::#{module_name}::CliCommand \}/,
],
@ -150,12 +150,12 @@ class InitPluginCli < Minitest::Test
File.join(plugin, "Rakefile") => [],
File.join(plugin, plugin + ".gemspec") => [
/spec\.version\s+=\s+InspecPlugins::FunPlugin::VERSION/,
/spec\.authors\s+=\s+\['Bob'\]/,
/spec\.email\s+=\s+\['bob@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'/,
/spec\.authors\s+=\s+\["Bob"\]/,
/spec\.email\s+=\s+\["bob@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") => [],