Class: PDK::Validate::InvokableValidator Abstract

Inherits:
Validator
  • Object
show all
Defined in:
lib/pdk/validate/invokable_validator.rb

Overview

This class is abstract.

A base class for file based validators. This class provides base methods and helpers to help determine the file targets to validate against. Acutal validator implementation should inherit from other child abstract classes e.g. ExternalCommandValdiator

See Also:

Instance Attribute Summary

Attributes inherited from Validator

#context, #options, #prepared

Instance Method Summary collapse

Methods inherited from Validator

#initialize, #invoke, #name, #spinners_enabled?, #start_spinner, #stop_spinner

Constructor Details

This class inherits a constructor from PDK::Validate::Validator

Instance Method Details

#allow_empty_targets?Boolean

This method is abstract.

Controls how the validator behaves if not passed any targets.

true  - PDK will not pass the globbed targets to the validator command
        and it will instead rely on the underlying tool to find its
        own default targets.
false - PDK will pass the globbed targets to the validator command.

Returns:

  • (Boolean)


170
171
172
# File 'lib/pdk/validate/invokable_validator.rb', line 170

def allow_empty_targets?
  false
end

#ignore_dotfiles?Boolean

This method is abstract.

Whether the target parsing ignores “dotfiles” (e.g. .gitignore or .pdkignore) which are considered hidden files in POSIX

Returns:

  • (Boolean)


112
113
114
# File 'lib/pdk/validate/invokable_validator.rb', line 112

def ignore_dotfiles?
  true
end

#invoke_styleObject

This method is abstract.

Controls how many times the validator is invoked.

:once -       The validator will be invoked once and passed all the
              targets.
:per_target - The validator will be invoked for each target
              separately.


18
19
20
# File 'lib/pdk/validate/invokable_validator.rb', line 18

def invoke_style
  :once
end

#parse_targetsObject

Parses the target strings provided from the CLI

Parameters:

  • options (Hash)

    A Hash containing the input options from the CLI.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/pdk/validate/invokable_validator.rb', line 59

def parse_targets
  requested_targets = options.fetch(:targets, [])
  # If no targets are specified and empty targets are allowed return with an empty list.
  # It will be up to the validator (and whatever validation tool it uses) to determine the
  # targets. For example, using rubocop with no targets, will allow rubocop to determine the
  # target list using it's .rubocop.yml file
  return [[], [], []] if requested_targets.empty? && allow_empty_targets?
  # If no targets are specified, then we will run validations from the base context directory.
  targets = requested_targets.empty? ? [context.root_path] : requested_targets
  targets.map! { |r| r.gsub(File::ALT_SEPARATOR, File::SEPARATOR) } if File::ALT_SEPARATOR

  # If this validator is not valid in this context then skip all of the targets
  return [[], targets, []] unless valid_in_context?

  skipped = []
  invalid = []
  matched = targets.map { |target|
    if pattern.nil?
      target
    else
      if PDK::Util::Filesystem.directory?(target) # rubocop:disable Style/IfInsideElse
        target_root = context.root_path
        pattern_glob = Array(pattern).map { |p| PDK::Util::Filesystem.glob(File.join(target_root, p), File::FNM_DOTMATCH) }
        target_list = pattern_glob.flatten
                                  .select { |glob| PDK::Util::Filesystem.fnmatch(File.join(PDK::Util::Filesystem.expand_path(PDK::Util.canonical_path(target)), '*'), glob, File::FNM_DOTMATCH) }
                                  .map { |glob| Pathname.new(glob).relative_path_from(Pathname.new(context.root_path)).to_s }

        ignore_list = ignore_pathspec
        target_list = target_list.reject { |file| ignore_list.match(file) }

        skipped << target if target_list.flatten.empty?
        target_list
      elsif PDK::Util::Filesystem.file?(target)
        if Array(pattern).include? target
          target
        elsif Array(pattern).any? { |p| PDK::Util::Filesystem.fnmatch(PDK::Util::Filesystem.expand_path(p), PDK::Util::Filesystem.expand_path(target), File::FNM_DOTMATCH) }
          target
        else
          skipped << target
          next
        end
      else
        invalid << target
        next
      end
    end
  }.compact.flatten.uniq
  [matched, skipped, invalid]
end

#patternArray[String], String

This method is abstract.

An array, or a string, of glob patterns to use to find targets

Returns:

  • (Array[String], String)


31
# File 'lib/pdk/validate/invokable_validator.rb', line 31

def pattern; end

#pattern_ignoreArray[String], ...

This method is abstract.

An array, or a string, of glob patterns to use to ignore targets

Returns:

  • (Array[String], String, Nil)


36
# File 'lib/pdk/validate/invokable_validator.rb', line 36

def pattern_ignore; end

#prepare_invoke!Object

See Also:

  • Validator.prepare_invoke!


39
40
41
42
43
44
45
46
# File 'lib/pdk/validate/invokable_validator.rb', line 39

def prepare_invoke!
  return if @prepared
  super

  # Register the spinner
  spinner
  nil
end

#process_invalid(report, invalid = []) ⇒ Object

Process any targets that were invalid by the validator and add the events to the validation report

Parameters:

  • report (PDK::Report)

    The report to add the events to

  • invalid (Array[String]) (defaults to: [])

    The list of invalid targets



150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/pdk/validate/invokable_validator.rb', line 150

def process_invalid(report, invalid = [])
  invalid.each do |invalid_target|
    PDK.logger.debug(_('%{validator}: Skipped \'%{target}\'. Target file not found.') % { validator: name, target: invalid_target })
    report.add_event(
      file:     invalid_target,
      source:   name,
      message:  _('File does not exist.'),
      severity: :error,
      state:    :error,
    )
  end
end

#process_skipped(report, skipped = []) ⇒ Object

Process any targets that were skipped by the validator and add the events to the validation report

Parameters:

  • report (PDK::Report)

    The report to add the events to

  • skipped (Array[String]) (defaults to: [])

    The list of skipped targets



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/pdk/validate/invokable_validator.rb', line 134

def process_skipped(report, skipped = [])
  skipped.each do |skipped_target|
    PDK.logger.debug(_('%{validator}: Skipped \'%{target}\'. Target does not contain any files to validate (%{pattern}).') % { validator: name, target: skipped_target, pattern: pattern })
    report.add_event(
      file:     skipped_target,
      source:   name,
      message:  _('Target does not contain any files to validate (%{pattern}).') % { pattern: pattern },
      severity: :info,
      state:    :skipped,
    )
  end
end

#spinnerObject

See Also:

  • Validator.spinner


123
124
125
126
127
128
129
# File 'lib/pdk/validate/invokable_validator.rb', line 123

def spinner
  return nil unless spinners_enabled?
  return @spinner unless @spinner.nil?
  require 'pdk/cli/util/spinner'

  @spinner = TTY::Spinner.new("[:spinner] #{spinner_text}", PDK::CLI::Util.spinner_opts_for_platform)
end

#spinner_textObject

This method is abstract.

See Also:

  • Validator.spinner_text


118
119
120
# File 'lib/pdk/validate/invokable_validator.rb', line 118

def spinner_text
  _('Running %{name} validator ...') % { name: name }
end

#valid_in_context?Boolean

Whether this Validator can be invoked in this context. By default any InvokableValidator can work in any Context, except ::None

Returns:

  • (Boolean)

See Also:



24
25
26
# File 'lib/pdk/validate/invokable_validator.rb', line 24

def valid_in_context?
  !context.is_a?(PDK::Context::None)
end