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)


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

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)


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

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.



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
108
# File 'lib/pdk/validate/invokable_validator.rb', line 60

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)


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

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)


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

def pattern_ignore; end

#prepare_invoke!Object

See Also:

  • Validator.prepare_invoke!


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

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



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

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



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

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


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

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


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

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

#valid_in_context?Boolean

This method is abstract.

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

Returns:

  • (Boolean)


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

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