Class: HTMLProofer::Runner

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/html-proofer/runner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#create_nokogiri, #pluralize, #swap

Constructor Details

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

Returns a new instance of Runner.



9
10
11
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 9

def initialize(src, opts = {})
  @src = src

  @options = HTMLProofer::Configuration::PROOFER_DEFAULTS.merge(opts)

  @options[:typhoeus] = HTMLProofer::Configuration::TYPHOEUS_DEFAULTS.merge(opts[:typhoeus] || {})
  @options[:hydra] = HTMLProofer::Configuration::HYDRA_DEFAULTS.merge(opts[:hydra] || {})

  @options[:parallel] = HTMLProofer::Configuration::PARALLEL_DEFAULTS.merge(opts[:parallel] || {})
  @options[:validation] = HTMLProofer::Configuration::VALIDATION_DEFAULTS.merge(opts[:validation] || {})
  @options[:cache] = HTMLProofer::Configuration::CACHE_DEFAULTS.merge(opts[:cache] || {})

  @type = @options.delete(:type)
  @logger = HTMLProofer::Log.new(@options[:log_level])

  # Add swap patterns for internal domains
  unless @options[:internal_domains].empty?
    @options[:internal_domains].each do |dom|
      @options[:url_swap][Regexp.new("^http://#{dom}")] = ''
      @options[:url_swap][Regexp.new("^https://#{dom}")] = ''
      @options[:url_swap][Regexp.new("^//#{dom}")] = ''
    end
  end

  @failures = []
end

Instance Attribute Details

#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

#failuresObject (readonly)

Returns the value of attribute failures.



7
8
9
# File 'lib/html-proofer/runner.rb', line 7

def failures
  @failures
end

#optionsObject (readonly)

Returns the value of attribute options.



7
8
9
# File 'lib/html-proofer/runner.rb', line 7

def options
  @options
end

Instance Method Details

#check_filesObject

Collects any external URLs found in a directory of files. Also collectes every failed test from process_files. Sends the external URLs to Typhoeus for batch processing.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/html-proofer/runner.rb', line 67

def check_files
  @external_urls = {}

  process_files.each do |item|
    @external_urls.merge!(item[:external_urls])
    @failures.concat(item[:failures])
  end

  # TODO: lazy. if we're checking only external links,
  # we'll just trash all the failed tests. really, we should
  # just not run those other checks at all.
  if @options[:external_only]
    @failures = []
    validate_urls
  elsif !@options[:disable_external]
    validate_urls
  end
end


54
55
56
57
58
59
60
61
62
# File 'lib/html-proofer/runner.rb', line 54

def check_list_of_links
  if @options[:url_swap]
    @src = @src.map do |url|
      swap(url, @options[:url_swap])
    end
  end
  @external_urls = Hash[*@src.map { |s| [s, nil] }.flatten]
  validate_urls
end

#check_parsed(html, path) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/html-proofer/runner.rb', line 95

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

  @src = [@src] if @type == :file

  @src.each do |src|
    checks.each do |klass|
      @logger.log :debug, "Checking #{klass.to_s.downcase} on #{path} ..."
      check = Object.const_get(klass).new(src, path, html, @options)
      check.run
      external_urls = check.external_urls
      external_urls = Hash[check.external_urls.map { |url, file| [swap(url, @options[:url_swap]), file] }] if @options[:url_swap]
      result[:external_urls].merge!(external_urls)
      result[:failures].concat(check.issues)
    end
  end
  result
end

#check_path(path) ⇒ Object



114
115
116
# File 'lib/html-proofer/runner.rb', line 114

def check_path(path)
  check_parsed create_nokogiri(path), path
end

#checksObject



147
148
149
150
151
152
153
154
155
156
# File 'lib/html-proofer/runner.rb', line 147

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

  @checks = HTMLProofer::Check.subchecks.map(&:name)
  @checks.delete('FaviconCheck') unless @options[:check_favicon]
  @checks.delete('HtmlCheck') unless @options[:check_html]
  @checks.delete('OpenGraphCheck') unless @options[:check_opengraph]
  @options[:checks_to_ignore].each { |ignored| @checks.delete(ignored) }
  @checks
end

#failed_testsObject



158
159
160
161
162
163
164
# File 'lib/html-proofer/runner.rb', line 158

def failed_tests
  result = []
  return result if @failures.empty?

  @failures.each { |f| result << f.to_s }
  result
end

#filesObject



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/html-proofer/runner.rb', line 124

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

#ignore_file?(file) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
141
142
143
144
145
# File 'lib/html-proofer/runner.rb', line 138

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

  false
end


166
167
168
169
170
171
172
173
# File 'lib/html-proofer/runner.rb', line 166

def print_failed_tests
  sorted_failures = SortedIssues.new(@failures, @options[:error_sort], @logger)

  sorted_failures.sort_and_report
  count = @failures.length
  failure_text = pluralize(count, 'failure', 'failures')
  raise @logger.colorize :red, "HTML-Proofer found #{failure_text}!"
end

#process_filesObject

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



87
88
89
90
91
92
93
# File 'lib/html-proofer/runner.rb', line 87

def process_files
  if @options[:parallel].empty?
    files.map { |path| check_path(path) }
  else
    Parallel.map(files, @options[:parallel]) { |path| check_path(path) }
  end
end

#runObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/html-proofer/runner.rb', line 36

def run
  if @type == :links
    @logger.log :info, "Running #{checks} on #{@src}... \n\n"
    check_list_of_links unless @options[:disable_external]
  else
    @logger.log :info, "Running #{checks} on #{@src} on *#{@options[:extension]}... \n\n"
    check_files
    file_text = pluralize(files.length, 'file', 'files')
    @logger.log :info, "Ran on #{file_text}!\n\n"
  end

  if @failures.empty?
    @logger.log_with_color :info, :green, 'HTML-Proofer finished successfully.'
  else
    print_failed_tests
  end
end

#validate_urlsObject



118
119
120
121
122
# File 'lib/html-proofer/runner.rb', line 118

def validate_urls
  url_validator = HTMLProofer::UrlValidator.new(@logger, @external_urls, @options)
  @failures.concat(url_validator.run)
  @external_urls = url_validator.external_urls
end