Class: PDK::Validate::ExternalCommandValidator
- Inherits:
-
InvokableValidator
- Object
- Validator
- InvokableValidator
- PDK::Validate::ExternalCommandValidator
- Defined in:
- lib/pdk/validate/external_command_validator.rb
Overview
An abstract validator that runs external commands within a Ruby Bundled environment e.g. ‘puppet-lint`, or `puppet validate`
At a a minimum child classes should implment the ‘name`, `cmd`, `pattern` and `parse_output` methods
An example concrete implementation could look like:
module PDK
module Validate
module Ruby
class RubyRubocopValidator < ExternalCommandValidator
def name
'rubocop'
end
def cmd
'rubocop'
end
def pattern
'**/**.rb'
end
def parse_options(targets)
['--format', 'json']
end
def parse_output(report, result, _targets)
... ruby code ...
report.add_event(
line: offense['location']['line'],
column: offense['location']['column'],
message: offense['message'],
severity: offense['corrected'] ? 'corrected' : offense['severity'],
test: offense['cop_name'],
state: :failure,
)
end
end
end
end
end
Direct Known Subclasses
Metadata::MetadataJSONLintValidator, Puppet::PuppetEPPValidator, Puppet::PuppetLintValidator, Puppet::PuppetSyntaxValidator, Ruby::RubyRubocopValidator
Instance Attribute Summary collapse
- #commands ⇒ Object readonly private
Attributes inherited from Validator
Instance Method Summary collapse
-
#alternate_bin_paths ⇒ Array[String]
private
Alternate paths which the command (cmd) may exist in.
-
#cmd ⇒ String
abstract
The name of the command to be run for validation.
-
#cmd_path ⇒ String
private
The full path to the command (cmd) Can be overridden in child classes to a non-default path.
-
#invoke(report) ⇒ Object
Invokes the prepared commands as an ExecGroup.
-
#parse_options(_targets) ⇒ Object
abstract
An array of command line arguments to pass to the command for validation.
-
#parse_output(_report, _result, _targets) ⇒ Object
abstract
private
Parses the output from the command and appends formatted events to the report.
-
#prepare_invoke! ⇒ Object
private
Prepares for invokation by parsing targets and creating the needed commands.
- #spinner ⇒ Object
-
#spinner_text_for_targets(targets) ⇒ String
abstract
Calculates the text of the spinner based on the target list.
Methods inherited from InvokableValidator
#allow_empty_targets?, #fnmatch?, #ignore_dotfiles?, #invoke_style, #parse_targets, #pattern, #pattern_ignore, #process_invalid, #process_skipped, #spinner_text, #valid_in_context?
Methods inherited from Validator
#initialize, #name, #spinner_text, #spinners_enabled?, #start_spinner, #stop_spinner, #valid_in_context?
Constructor Details
This class inherits a constructor from PDK::Validate::Validator
Instance Attribute Details
#commands ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
52 53 54 |
# File 'lib/pdk/validate/external_command_validator.rb', line 52 def commands @commands end |
Instance Method Details
#alternate_bin_paths ⇒ Array[String]
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Alternate paths which the command (cmd) may exist in. Typically other ruby gem caches, or packaged installation bin directories.
74 75 76 77 78 79 80 81 |
# File 'lib/pdk/validate/external_command_validator.rb', line 74 def alternate_bin_paths [ PDK::Util::RubyVersion.bin_path, File.join(PDK::Util::RubyVersion.gem_home, 'bin'), PDK::Util::RubyVersion.gem_paths_raw.map { |gem_path_raw| File.join(gem_path_raw, 'bin') }, PDK::Util.package_install? ? File.join(PDK::Util.pdk_package_basedir, 'bin') : nil ].flatten.compact end |
#cmd ⇒ String
The name of the command to be run for validation
68 |
# File 'lib/pdk/validate/external_command_validator.rb', line 68 def cmd; end |
#cmd_path ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The full path to the command (cmd) Can be overridden in child classes to a non-default path
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/pdk/validate/external_command_validator.rb', line 87 def cmd_path return @cmd_path unless @cmd_path.nil? @cmd_path = File.join(context.root_path, 'bin', cmd) # Return the path to the command if it exists on disk, or we have a gemfile (i.e. Bundled install) # The Bundle may be created after the prepare_invoke so if the file doesn't exist, it may not be an error return @cmd_path if PDK::Util::Filesystem.exist?(@cmd_path) || !PDK::Util::Bundler::BundleHelper.new.gemfile.nil? # But if there is no Gemfile AND cmd doesn't exist in the default path, we need to go searching... @cmd_path = alternate_bin_paths.map { |alternate_path| File.join(alternate_path, cmd) } .find { |path| PDK::Util::Filesystem.exist?(path) } return @cmd_path unless @cmd_path.nil? # If we can't find it anywhere, just let the OS find it @cmd_path = cmd end |
#invoke(report) ⇒ Object
Invokes the prepared commands as an ExecGroup
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/pdk/validate/external_command_validator.rb', line 178 def invoke(report) prepare_invoke! process_skipped(report, @skipped) process_invalid(report, @invalid) # Nothing to execute so return success return 0 if @commands.empty? # If there's no Gemfile, then we can't ensure the binstubs are correct PDK::Util::Bundler.ensure_binstubs!(cmd) unless PDK::Util::Bundler::BundleHelper.new.gemfile.nil? exec_group = PDK::CLI::ExecGroup.create(name, { parallel: false }, ) # Register all of the commands for all of the targets @commands.each do |item| command = item[:command] invokation_targets = item[:invokation_targets] exec_group.register do result = command.execute! begin parse_output(report, result, invokation_targets.compact) rescue PDK::Validate::ParseOutputError => e $stderr.puts e. end result[:exit_code] end end # Now execute and get the return code exec_group.exit_code end |
#parse_options(_targets) ⇒ Object
An array of command line arguments to pass to the command for validation
107 108 109 |
# File 'lib/pdk/validate/external_command_validator.rb', line 107 def (_targets) [] end |
#parse_output(_report, _result, _targets) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Parses the output from the command and appends formatted events to the report. This is called for each command, which is a group of targets
120 |
# File 'lib/pdk/validate/external_command_validator.rb', line 120 def parse_output(_report, _result, _targets); end |
#prepare_invoke! ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Prepares for invokation by parsing targets and creating the needed commands.
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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/pdk/validate/external_command_validator.rb', line 125 def prepare_invoke! return if @prepared super @targets, @skipped, @invalid = parse_targets @targets = [] if @targets.nil? target_groups = if @targets.empty? && allow_empty_targets? # If we have no targets and we allow empty targets, create an empty target group list [[]] elsif invoke_style == :per_target # If invoking :per_target, split the targets array into an array of # single element arrays (one per target). @targets.combination(1).to_a.compact else # Else we're invoking :once, wrap the targets array in another array. This is so we # can loop through the invokes with the same logic, regardless of which invoke style # is needed. @targets.each_slice(1000).to_a.compact end # Register all of the commands for all of the targets @commands = [] target_groups.each do |invokation_targets| next if invokation_targets.empty? && !allow_empty_targets? cmd_argv = (invokation_targets).unshift(cmd_path).compact cmd_argv.unshift(File.join(PDK::Util::RubyVersion.bin_path, 'ruby.exe'), '-W0') if Gem.win_platform? command = PDK::CLI::Exec::Command.new(*cmd_argv).tap do |c| c.context = :module c.environment = { 'PUPPET_GEM_VERSION' => [:puppet] } if [:puppet] if spinners_enabled? parent_validator = [:parent_validator] if parent_validator.nil? || parent_validator.spinner.nil? || !parent_validator.spinner.is_a?(TTY::Spinner::Multi) c.add_spinner(spinner_text_for_targets(invokation_targets)) else spinner = TTY::Spinner.new("[:spinner] #{spinner_text_for_targets(invokation_targets)}", PDK::CLI::Util.spinner_opts_for_platform) parent_validator.spinner.register(spinner) c.register_spinner(spinner, PDK::CLI::Util.spinner_opts_for_platform) end end end @commands << { command: command, invokation_targets: invokation_targets } end nil end |
#spinner ⇒ Object
55 56 57 58 |
# File 'lib/pdk/validate/external_command_validator.rb', line 55 def spinner # The validator has sub-commands with their own spinners. nil end |
#spinner_text_for_targets(targets) ⇒ String
Calculates the text of the spinner based on the target list
63 |
# File 'lib/pdk/validate/external_command_validator.rb', line 63 def spinner_text_for_targets(targets); end |