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.



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

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 = []

  @checked_paths = {}

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

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

Instance Attribute Details

#cacheObject (readonly)

Returns the value of attribute cache.



7
8
9
# File 'lib/html_proofer/runner.rb', line 7

def cache
  @cache
end

#checked_pathsObject (readonly)

Returns the value of attribute checked_paths.



7
8
9
# File 'lib/html_proofer/runner.rb', line 7

def checked_paths
  @checked_paths
end

#current_checkObject (readonly)

Returns the value of attribute current_check.



7
8
9
# File 'lib/html_proofer/runner.rb', line 7

def current_check
  @current_check
end

#current_filenameObject

Returns the value of attribute current_filename.



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

def current_filename
  @current_filename
end

#current_sourceObject

Returns the value of attribute current_source.



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

def current_source
  @current_source
end

#external_urlsObject (readonly)

Returns the value of attribute external_urls.



7
8
9
# File 'lib/html_proofer/runner.rb', line 7

def external_urls
  @external_urls
end

#internal_urlsObject (readonly)

Returns the value of attribute internal_urls.



7
8
9
# File 'lib/html_proofer/runner.rb', line 7

def internal_urls
  @internal_urls
end

#loggerObject (readonly)

Returns the value of attribute logger.



7
8
9
# File 'lib/html_proofer/runner.rb', line 7

def logger
  @logger
end

#optionsObject (readonly)

Returns the value of attribute options.



7
8
9
# File 'lib/html_proofer/runner.rb', line 7

def options
  @options
end

#reporterObject

Returns the value of attribute reporter.



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

def reporter
  @reporter
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.



212
213
214
215
216
# File 'lib/html_proofer/runner.rb', line 212

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.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/html_proofer/runner.rb', line 74

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


62
63
64
65
66
67
68
69
70
# File 'lib/html_proofer/runner.rb', line 62

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.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/html_proofer/runner.rb', line 116

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)


172
173
174
# File 'lib/html_proofer/runner.rb', line 172

def check_sri?
  @options[:check_sri]
end

#checksObject



180
181
182
183
184
185
186
187
188
# File 'lib/html_proofer/runner.rb', line 180

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)


176
177
178
# File 'lib/html_proofer/runner.rb', line 176

def enforce_https?
  @options[:enforce_https]
end

#failed_checksObject



190
191
192
# File 'lib/html_proofer/runner.rb', line 190

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

#filesObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/html_proofer/runner.rb', line 148

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)


163
164
165
166
167
168
169
170
# File 'lib/html_proofer/runner.rb', line 163

def ignore_file?(file)
  @options[:ignore_files].each do |pattern|
    return true if pattern.is_a?(String) && pattern == file
    return true if pattern.is_a?(Regexp) && pattern =~ file
  end

  false
end

#load_external_cacheObject



222
223
224
# File 'lib/html_proofer/runner.rb', line 222

def load_external_cache
  load_cache(:external)
end

#load_file(path, source) ⇒ Object



109
110
111
112
# File 'lib/html_proofer/runner.rb', line 109

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

#load_internal_cacheObject



218
219
220
# File 'lib/html_proofer/runner.rb', line 218

def load_internal_cache
  load_cache(:internal)
end

#process_filesObject

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



99
100
101
102
103
104
105
106
107
# File 'lib/html_proofer/runner.rb', line 99

def process_files
  if @options[:parallel][:enable]
    Parallel.map(files, @options[:parallel]) { |file| load_file(file[:path], file[:source]) }
  else
    files.map do |file|
      load_file(file[:path], file[:source])
    end
  end
end

#report_failed_checksObject



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

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



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

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



137
138
139
140
141
# File 'lib/html_proofer/runner.rb', line 137

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



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

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