html-proofer 3.10.1 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b785a108ad8a82bdc21dbc428240bcba1b77ac3a0a5cf08d0de68bac11583e5
4
- data.tar.gz: 52f4c91fb3a9ba242667a9a4b079fe6426fde92d29e7f121116c0544062a3a16
3
+ metadata.gz: 03572c9956b3d257f19ce6b0692164a4bb18ced1351d05dfa79e3f218504e271
4
+ data.tar.gz: 92f19a6d0ecf5a5f298d1d6aa2df02c4d788d48e4348d28064d5edba32bb9f15
5
5
  SHA512:
6
- metadata.gz: 17c9ca468bb8ca4c20deb9387e3d85ff9c80281711f25cb87cdfbad22b733700a49ad5721e78b2169283d9178276434bef63974d250441de0297c3fbf4f698ea
7
- data.tar.gz: 89db5416f295bdfa12c8545d1b613aad7a4fb235f2e4c6470f2a2d4968e663d23689e6ca529e0cdf59e1fdcc3b95ca2467b62e9b83a6cab8bcb0790a12c12663
6
+ metadata.gz: ae17c5d646967fc246d0e2661f7c2fc45d1e07321db23a6cd3cf33398e2e675a825b59325154cd9bd249f2e949c4b3351845e260663591dc14aa9fa05d66f867
7
+ data.tar.gz: c8a7518a4d75224aa18a7ec617bfeb8b302592d4b07259bdd711690558a9d98cbf541c9b92765871dbded8ee32a8cba1524fd29e632c56f8d1b4c132efba7875
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  STDOUT.sync = true
3
5
 
4
6
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def require_all(path)
2
4
  dir = File.join(File.dirname(__FILE__), path)
3
5
  Dir[File.join(dir, '*.rb')].each do |f|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'utils'
2
4
 
3
5
  require 'json'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HTMLProofer
2
4
  # Mostly handles issue management and collecting of external URLs.
3
5
  class Check
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class FaviconCheck < ::HTMLProofer::Check
2
4
  def run
3
5
  found = false
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class HtmlCheck < ::HTMLProofer::Check
2
4
  SCRIPT_EMBEDS_MSG = /Element script embeds close tag/
3
5
  INVALID_TAG_MSG = /Tag ([\w\-:]+) invalid/
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ImageCheck < ::HTMLProofer::Check
2
4
  SCREEN_SHOT_REGEX = /Screen(?: |%20)Shot(?: |%20)\d+-\d+-\d+(?: |%20)at(?: |%20)\d+.\d+.\d+/
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class LinkCheck < ::HTMLProofer::Check
2
4
  include HTMLProofer::Utils
3
5
 
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  class OpenGraphElement < ::HTMLProofer::Element
4
5
  attr_reader :src
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ScriptCheck < ::HTMLProofer::Check
2
4
  attr_reader :src
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HTMLProofer
2
4
  module Configuration
3
5
  require_relative 'version'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'addressable/uri'
2
4
  require_relative './utils'
3
5
 
@@ -54,7 +56,7 @@ module HTMLProofer
54
56
 
55
57
  def url
56
58
  return @url if defined?(@url)
57
- @url = (@src || @srcset || @href || '').delete("\u200b")
59
+ @url = (@src || @srcset || @href || '').delete("\u200b").strip
58
60
  @url = Addressable::URI.join(base.attr('href') || '', url).to_s if base
59
61
  return @url if @check.options[:url_swap].empty?
60
62
  @url = swap(@url, @check.options[:url_swap])
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HTMLProofer
2
4
  class Issue
3
5
  attr_reader :path, :desc, :status, :line, :content
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yell'
2
- require 'colorized_string'
4
+ require 'rainbow'
3
5
 
4
6
  module HTMLProofer
5
7
  class Log
@@ -17,7 +19,7 @@ module HTMLProofer
17
19
  def log(level, message)
18
20
  color = case level
19
21
  when :debug
20
- :light_blue
22
+ :cyan
21
23
  when :info
22
24
  :blue
23
25
  when :warn
@@ -35,7 +37,7 @@ module HTMLProofer
35
37
 
36
38
  def colorize(color, message)
37
39
  if $stdout.isatty && $stderr.isatty
38
- ColorizedString.new(message).colorize(color)
40
+ Rainbow(message).send(color)
39
41
  else
40
42
  message
41
43
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HTMLProofer
4
+ class Middleware
5
+
6
+ class InvalidHtmlError < StandardError
7
+ def initialize(failures)
8
+ @failures = failures
9
+ end
10
+
11
+ def message
12
+ "HTML Validation errors (skip by adding `?proofer-ignore` to URL): \n#{@failures.join("\n")}"
13
+ end
14
+ end
15
+
16
+ def self.options
17
+ @options ||= {
18
+ type: :file,
19
+ allow_missing_href: true, # Permitted in html5
20
+ allow_hash_href: true,
21
+ check_external_hash: true,
22
+ check_html: true,
23
+ url_ignore: [/.*/], # Don't try to check local files exist
24
+ }
25
+ end
26
+
27
+ def initialize(app)
28
+ @app = app
29
+ end
30
+
31
+ HTML_SIGNATURE = [
32
+ '<!DOCTYPE HTML',
33
+ '<HTML',
34
+ '<HEAD',
35
+ '<SCRIPT',
36
+ '<IFRAME',
37
+ '<H1',
38
+ '<DIV',
39
+ '<FONT',
40
+ '<TABLE',
41
+ '<A',
42
+ '<STYLE',
43
+ '<TITLE',
44
+ '<B',
45
+ '<BODY',
46
+ '<BR',
47
+ '<P',
48
+ '<!--'
49
+ ]
50
+
51
+ def call(env)
52
+ result = @app.call(env)
53
+ return result if env['REQUEST_METHOD'] != 'GET'
54
+ return result if env['QUERY_STRING'] =~ /proofer-ignore/
55
+ return result if result.first != 200
56
+ body = []
57
+ result.last.each { |e| body << e }
58
+
59
+ body = body.join('')
60
+ begin
61
+ html = body.lstrip
62
+ rescue
63
+ return result # Invalid encoding; it's not gonna be html.
64
+ end
65
+ if HTML_SIGNATURE.any? { |sig| html.upcase.starts_with? sig }
66
+ parsed = HTMLProofer::Runner.new(
67
+ 'response',
68
+ Middleware.options
69
+ ).check_parsed(
70
+ Nokogiri::HTML(Utils.clean_content(html)), 'response'
71
+ )
72
+
73
+ if parsed[:failures].length > 0
74
+ raise InvalidHtmlError.new(parsed[:failures])
75
+ end
76
+ end
77
+ result
78
+ end
79
+ end
80
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HTMLProofer
2
4
  class Runner
3
5
  include HTMLProofer::Utils
@@ -90,9 +92,8 @@ module HTMLProofer
90
92
  end
91
93
  end
92
94
 
93
- def check_path(path)
95
+ def check_parsed(html, path)
94
96
  result = { external_urls: {}, failures: [] }
95
- html = create_nokogiri(path)
96
97
 
97
98
  @src = [@src] if @type == :file
98
99
 
@@ -112,6 +113,10 @@ module HTMLProofer
112
113
  result
113
114
  end
114
115
 
116
+ def check_path(path)
117
+ check_parsed create_nokogiri(path), path
118
+ end
119
+
115
120
  def validate_urls
116
121
  url_validator = HTMLProofer::UrlValidator.new(@logger, @external_urls, @options)
117
122
  @failures.concat(url_validator.run)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'typhoeus'
2
4
  require 'uri'
3
5
  require_relative './utils'
@@ -144,8 +146,12 @@ module HTMLProofer
144
146
  response_code = response.code
145
147
  response.body.gsub!("\x00", '')
146
148
 
147
- debug_msg = "Received a #{response_code} for #{href}"
148
- debug_msg << " in #{filenames.join(' ')}" unless filenames.nil?
149
+ if filenames.nil?
150
+ debug_msg = "Received a #{response_code} for #{href}"
151
+ else
152
+ debug_msg = "Received a #{response_code} for #{href} in #{filenames.join(' ')}"
153
+ end
154
+
149
155
  @logger.log :debug, debug_msg
150
156
 
151
157
  return if @options[:http_status_ignore].include?(response_code)
@@ -179,13 +185,18 @@ module HTMLProofer
179
185
  body_doc = create_nokogiri(response.body)
180
186
 
181
187
  unencoded_hash = Addressable::URI.unescape(hash)
182
- xpath = %(//*[@name="#{hash}"]|/*[@name="#{unencoded_hash}"]|//*[@id="#{hash}"]|//*[@id="#{unencoded_hash}"])
188
+ xpath = [%(//*[@name="#{hash}"]|/*[@name="#{unencoded_hash}"]|//*[@id="#{hash}"]|//*[@id="#{unencoded_hash}"])]
183
189
  # user-content is a special addition by GitHub.
184
190
  if URI.parse(href).host =~ /github\.com/i
185
- xpath << %(|//*[@name="user-content-#{hash}"]|//*[@id="user-content-#{hash}"])
191
+ xpath << [%(//*[@name="user-content-#{hash}"]|//*[@id="user-content-#{hash}"])]
192
+ # when linking to a file on GitHub, like #L12-L34, only the first "L" portion
193
+ # will be identified as a linkable portion
194
+ if hash =~ /\A(L\d)+/
195
+ xpath << [%(//td[@id="#{Regexp.last_match[1]}"])]
196
+ end
186
197
  end
187
198
 
188
- return unless body_doc.xpath(xpath).empty?
199
+ return unless body_doc.xpath(xpath.join('|')).empty?
189
200
 
190
201
  msg = "External link #{href} failed: #{effective_url} exists, but the hash '#{hash}' does not"
191
202
  add_external_issue(filenames, msg, response.code)
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nokogiri'
2
4
 
3
5
  module HTMLProofer
4
6
  module Utils
5
7
  def pluralize(count, single, plural)
6
- "#{count} " << (count == 1 ? single : plural)
8
+ "#{count} #{(count == 1 ? single : plural)}"
7
9
  end
8
10
 
9
11
  def create_nokogiri(path)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HTMLProofer
2
- VERSION = '3.10.1'.freeze
4
+ VERSION = '3.11.0'.freeze
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-proofer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.1
4
+ version: 3.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-16 00:00:00.000000000 Z
11
+ date: 2019-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mercenary
@@ -39,19 +39,19 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.9'
41
41
  - !ruby/object:Gem::Dependency
42
- name: colorize
42
+ name: rainbow
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.8'
47
+ version: '3.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.8'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: typhoeus
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -157,7 +157,21 @@ dependencies:
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
159
  - !ruby/object:Gem::Dependency
160
- name: rubocop-github
160
+ name: rubocop-standard
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: rubocop-performance
161
175
  requirement: !ruby/object:Gem::Requirement
162
176
  requirements:
163
177
  - - ">="
@@ -290,6 +304,7 @@ files:
290
304
  - lib/html-proofer/element.rb
291
305
  - lib/html-proofer/issue.rb
292
306
  - lib/html-proofer/log.rb
307
+ - lib/html-proofer/middleware.rb
293
308
  - lib/html-proofer/runner.rb
294
309
  - lib/html-proofer/url_validator.rb
295
310
  - lib/html-proofer/utils.rb