mirror of
https://github.com/inspec/inspec
synced 2025-02-17 06:28:40 +00:00
Merge pull request #5536 from inspec/vasundhara/update-inspec-init-plugin
Update inspec init plugin
This commit is contained in:
commit
e841b576ad
18 changed files with 201 additions and 131 deletions
54
dev-docs/inspec-init-plugin.md
Normal file
54
dev-docs/inspec-init-plugin.md
Normal 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.
|
|
@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
|
@ -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
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
|
@ -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.
|
|
@ -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 %>
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -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") => [],
|
||||
|
|
Loading…
Add table
Reference in a new issue