Class: HTMLProofer::Runner

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/html_proofer/runner.rb

Constant Summary collapse

URL_TYPES =
[:external, :internal].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#blank?, #create_nokogiri, #pluralize

Constructor Details

#initialize(src, opts = {}) ⇒ Runner

Returns a new instance of Runner.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/html_proofer/runner.rb', line 14

def initialize(src, opts = {})
  @options = HTMLProofer::Configuration.generate_defaults(opts)

  @type = @options.delete(:type)
  @source = src

  @logger = HTMLProofer::Log.new(@options[:log_level])
  @cache = Cache.new(self, @options[:cache])

  @external_urls = {}
  @internal_urls = {}
  @failures = []

  @before_request = []

  @resolved_paths = {}

  @current_check = nil
  @current_source = nil
  @current_filename = nil

  @reporter = Reporter::Terminal.new(logger: @logger)
end

Instance Attribute Details

#cacheObject (readonly)

Returns the value of attribute cache.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def cache
  @cache
end

#current_checkObject (readonly)

Returns the value of attribute current_check.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def current_check
  @current_check
end

#current_filenameObject (readonly)

Returns the value of attribute current_filename.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def current_filename
  @current_filename
end

#current_sourceObject (readonly)

Returns the value of attribute current_source.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def current_source
  @current_source
end

#external_urlsObject (readonly)

Returns the value of attribute external_urls.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def external_urls
  @external_urls
end

#internal_urlsObject (readonly)

Returns the value of attribute internal_urls.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def internal_urls
  @internal_urls
end

#loggerObject (readonly)

Returns the value of attribute logger.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def logger
  @logger
end

#optionsObject (readonly)

Returns the value of attribute options.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def options
  @options
end

#reporterObject

Returns the value of attribute reporter.



10
11
12
# File 'lib/html_proofer/runner.rb', line 10

def reporter
  @reporter
end

#resolved_pathsObject (readonly)

Returns the value of attribute resolved_paths.



9
10
11
# File 'lib/html_proofer/runner.rb', line 9

def resolved_paths
  @resolved_paths
end

Instance Method Details

#before_request(&block) {|Typhoeus::Request| ... } ⇒ Array<Block>

Set before_request callback.

Examples:

Set before_request.

request.before_request { |request| p "yay" }

Parameters:

  • block (Block)

    The block to execute.

Yields:

  • (Typhoeus::Request)

Returns:

  • (Array<Block>)

    All before_request blocks.



224
225
226
227
228
# File 'lib/html_proofer/runner.rb', line 224

def before_request(&block)
  @before_request ||= []
  @before_request << block if block
  @before_request
end

#check_filesObject

Walks over each implemented check and runs them on the files, in parallel. Sends the collected external URLs to Typhoeus for batch processing.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/html_proofer/runner.rb', line 78

def check_files
  process_files.each do |result|
    URL_TYPES.each do |url_type|
      type = :"#{url_type}_urls"
      ivar_name = "@#{type}"
      ivar = instance_variable_get(ivar_name)

      if ivar.empty?
        instance_variable_set(ivar_name, result[type])
      else
        result[type].each do |url, |
          ivar[url] = [] if ivar[url].nil?
          ivar[url].concat()
        end
      end
    end
    @failures.concat(result[:failures])
  end

  validate_external_urls unless @options[:disable_external]

  validate_internal_urls
end


66
67
68
69
70
71
72
73
74
# File 'lib/html_proofer/runner.rb', line 66

def check_list_of_links
  @external_urls = @source.uniq.each_with_object({}) do |link, hash|
    url = Attribute::Url.new(self, link, base_url: nil).to_s

    hash[url] = []
  end

  validate_external_urls
end

#check_parsed(path, source) ⇒ Object

Collects any external URLs found in a directory of files. Also collectes every failed test from process_files.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/html_proofer/runner.rb', line 122

def check_parsed(path, source)
  result = { internal_urls: {}, external_urls: {}, failures: [] }

  checks.each do |klass|
    @current_source = source
    @current_filename = path

    check = Object.const_get(klass).new(self, @html)
    @logger.log(:debug, "Running #{check.short_name} in #{path}")

    @current_check = check

    check.run

    result[:external_urls].merge!(check.external_urls) { |_key, old, current| old.concat(current) }
    result[:internal_urls].merge!(check.internal_urls) { |_key, old, current| old.concat(current) }
    result[:failures].concat(check.failures)
  end
  result
end

#check_sri?Boolean

Returns:

  • (Boolean)


184
185
186
# File 'lib/html_proofer/runner.rb', line 184

def check_sri?
  @options[:check_sri]
end

#checksObject



192
193
194
195
196
197
198
199
200
# File 'lib/html_proofer/runner.rb', line 192

def checks
  return @checks if defined?(@checks) && !@checks.nil?

  return (@checks = ["LinkCheck"]) if @type == :links

  @checks = HTMLProofer::Check.subchecks(@options).map(&:name)

  @checks
end

#enforce_https?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/html_proofer/runner.rb', line 188

def enforce_https?
  @options[:enforce_https]
end

#failed_checksObject



202
203
204
# File 'lib/html_proofer/runner.rb', line 202

def failed_checks
  @reporter.failures.flatten.select { |f| f.is_a?(Failure) }
end

#filesObject



154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/html_proofer/runner.rb', line 154

def files
  @files ||= if @type == :directory
    @source.map do |src|
      pattern = File.join(src, "**", "*{#{@options[:extensions].join(",")}}")
      Dir.glob(pattern).select do |f|
        File.file?(f) && !ignore_file?(f)
      end.map { |f| { source: src, path: f } }
    end.flatten
  elsif @type == :file && @options[:extensions].include?(File.extname(@source))
    [@source].reject { |f| ignore_file?(f) }.map { |f| { source: f, path: f } }
  else
    []
  end
end

#ignore_file?(file) ⇒ Boolean

Returns:

  • (Boolean)


169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/html_proofer/runner.rb', line 169

def ignore_file?(file)
  @options[:ignore_files].each do |pattern|
    if pattern.is_a?(String) && pattern == file
      @logger.log(:debug, "Ignoring #{file} because it matches #{pattern}")
      return true
    end
    next unless pattern.is_a?(Regexp) && pattern.match(file)

    @logger.log(:debug, "Ignoring #{file} because it matches regexp #{pattern}")
    return true
  end

  false
end

#load_external_cacheObject



234
235
236
# File 'lib/html_proofer/runner.rb', line 234

def load_external_cache
  load_cache(:external)
end

#load_file(path, source) ⇒ Object



115
116
117
118
# File 'lib/html_proofer/runner.rb', line 115

def load_file(path, source)
  @html = create_nokogiri(path)
  check_parsed(path, source)
end

#load_internal_cacheObject



230
231
232
# File 'lib/html_proofer/runner.rb', line 230

def load_internal_cache
  load_cache(:internal)
end

#process_filesObject

Walks over each implemented check and runs them on the files, in parallel.



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/html_proofer/runner.rb', line 103

def process_files
  loaded_files = []
  files.each do |file|
    Async do |task|
      task.async do
        loaded_files << load_file(file[:path], file[:source])
      end
    end
  end
  loaded_files
end

#report_failed_checksObject



206
207
208
209
210
211
212
# File 'lib/html_proofer/runner.rb', line 206

def report_failed_checks
  @reporter.report

  failure_text = pluralize(@failures.length, "failure", "failures")
  @logger.log(:fatal, "\nHTML-Proofer found #{failure_text}!")
  exit(1)
end

#runObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/html_proofer/runner.rb', line 38

def run
  check_text = pluralize(checks.length, "check", "checks")

  if @type == :links
    @logger.log(:info, "Running #{check_text} (#{format_checks_list(checks)}) on #{@source} ...\n\n")
    check_list_of_links unless @options[:disable_external]
  else
    @logger.log(
      :info,
      "Running #{check_text} (#{format_checks_list(checks)}) in #{@source} on *#{@options[:extensions].join(", ")} files ...\n\n",
    )

    check_files
    @logger.log(:info, "Ran on #{pluralize(files.length, "file", "files")}!\n\n")
  end

  @cache.write

  @reporter.failures = @failures

  if @failures.empty?
    @logger.log(:info, "HTML-Proofer finished successfully.")
  else
    @failures.uniq!
    report_failed_checks
  end
end

#validate_external_urlsObject



143
144
145
146
147
# File 'lib/html_proofer/runner.rb', line 143

def validate_external_urls
  external_url_validator = HTMLProofer::UrlValidator::External.new(self, @external_urls)
  external_url_validator.before_request = @before_request
  @failures.concat(external_url_validator.validate)
end

#validate_internal_urlsObject



149
150
151
152
# File 'lib/html_proofer/runner.rb', line 149

def validate_internal_urls
  internal_link_validator = HTMLProofer::UrlValidator::Internal.new(self, @internal_urls)
  @failures.concat(internal_link_validator.validate)
end