html-proofer 3.0.0 → 3.1.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 +4 -4
- data/bin/htmlproofer +14 -5
- data/lib/html-proofer/check/html.rb +5 -0
- data/lib/html-proofer/check/images.rb +5 -1
- data/lib/html-proofer/configuration.rb +4 -1
- data/lib/html-proofer/element.rb +11 -6
- data/lib/html-proofer/runner.rb +14 -1
- data/lib/html-proofer/url_validator.rb +6 -3
- data/lib/html-proofer/version.rb +1 -1
- data/lib/html-proofer.rb +3 -2
- metadata +10 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d69ea6f2eb74095372c3f46f5b0b40beb25d4c2
|
|
4
|
+
data.tar.gz: b788331194e898263a88a47f41c60f77a4f3051a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a98a1fd90173d4481caae3c2fa7b702e1d5ab04cd262f4c555d250b7ce4518e29bcb0f3cfba7cd33d88526389bd05f3665b3ebb6ca0a46404057fa01f7663c62
|
|
7
|
+
data.tar.gz: 603de7c0256dde6120f0cce01e4803768c09468c620a04d81d6b053bd3d66e72573bc8fbe33efa9597a090fcd3c9f8744826021829e1619fc35fdc584c8c7513
|
data/bin/htmlproofer
CHANGED
|
@@ -18,9 +18,10 @@ Mercenary.program(:htmlproofer) do |p|
|
|
|
18
18
|
p.option 'alt_ignore', '--alt-ignore image1,[image2,...]', Array, 'A comma-separated list of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore'
|
|
19
19
|
p.option 'assume_extension', '--assume-extension', 'Automatically add extension (e.g. `.html`) to file paths, to allow extensionless URLs (as supported by Jekyll 3 and GitHub Pages) (default: `false`).'
|
|
20
20
|
p.option 'checks_to_ignore', '--checks-to-ignore check1,[check2,...]', Array, ' An array of Strings indicating which checks you\'d like to not perform.'
|
|
21
|
-
p.option 'check_external_hash', '--check-external-hash', 'Checks whether external hashes exist (even if the
|
|
21
|
+
p.option 'check_external_hash', '--check-external-hash', 'Checks whether external hashes exist (even if the webpage exists). This slows the checker down (default: `false`).'
|
|
22
22
|
p.option 'check_favicon', '--check-favicon', 'Enables the favicon checker (default: `false`).'
|
|
23
23
|
p.option 'check_html', '--check-html', 'Enables HTML validation errors from Nokogiri (default: `false`).'
|
|
24
|
+
p.option 'check_img_http', '--check-img-http', 'Fails an image if it\'s marked as `http` (default: `false`).'
|
|
24
25
|
p.option 'directory_index_file', '--directory-index-file', String, 'Sets the file to look for when a link refers to a directory. (default: `index.html`)'
|
|
25
26
|
p.option 'disable_external', '--disable-external', 'If `true`, does not run the external link checker, which can take a lot of time (default: `false`)'
|
|
26
27
|
p.option 'empty_alt_ignore', '--empty-alt-ignore', 'If `true`, ignores images with empty alt tags'
|
|
@@ -31,12 +32,14 @@ Mercenary.program(:htmlproofer) do |p|
|
|
|
31
32
|
p.option 'file_ignore', '--file-ignore file1,[file2,...]', Array, 'A comma-separated list of Strings or RegExps containing file paths that are safe to ignore'
|
|
32
33
|
p.option 'http_status_ignore', '--http-status-ignore 123,[xxx, ...]', Array, 'A comma-separated list of numbers representing status codes to ignore.'
|
|
33
34
|
p.option 'report_invalid_tags', '--report-invalid-tags', 'Ignore `check_html` errors associated with unknown markup (default: `false`)'
|
|
35
|
+
p.option 'report_missing_names', '--report-missing-names', 'Ignore `check_html` errors associated with missing entities (default: `false`)'
|
|
34
36
|
p.option 'report_script_embeds', '--report-script-embeds', 'Ignore `check_html` errors associated with `script`s (default: `false`)'
|
|
35
37
|
p.option 'log_level', '--log-level <level>', String, 'Sets the logging level, as determined by Yell'
|
|
36
38
|
p.option 'only_4xx', '--only-4xx', 'Only reports errors for links that fall within the 4xx status code range'
|
|
37
39
|
p.option 'timeframe', '--timeframe <time>', String, 'A string representing the caching timeframe.'
|
|
38
40
|
p.option 'url_ignore', '--url-ignore link1,[link2,...]', Array, 'A comma-separated list of Strings or RegExps containing URLs that are safe to ignore. It affects all HTML attributes. Note that non-HTTP(S) URIs are always ignored'
|
|
39
|
-
p.option 'url_swap', '--url-swap re:string,[re:string,...]', Array, 'A comma-separated list containing key-value pairs of `RegExp => String`. It transforms URLs that match `RegExp` into `String` via `gsub`.'
|
|
41
|
+
p.option 'url_swap', '--url-swap re:string,[re:string,...]', Array, 'A comma-separated list containing key-value pairs of `RegExp => String`. It transforms URLs that match `RegExp` into `String` via `gsub`. The escape sequences `\\:` should be used to produce literal `:`s.'
|
|
42
|
+
p.option 'internal_domains', '--internal-domains domain1,[domain2,...]', Array, 'A comma-separated list of Strings containing domains that will be treated as internal urls.'
|
|
40
43
|
|
|
41
44
|
p.action do |args, opts|
|
|
42
45
|
args = ['.'] if args.empty?
|
|
@@ -46,7 +49,7 @@ Mercenary.program(:htmlproofer) do |p|
|
|
|
46
49
|
|
|
47
50
|
# prepare everything to go to proofer
|
|
48
51
|
p.options.select { |o| !opts[o.config_key].nil? }.each do |option|
|
|
49
|
-
if option.
|
|
52
|
+
if opts[option.config_key].is_a?(Array)
|
|
50
53
|
opts[option.config_key] = opts[option.config_key].map { |i| HTMLProofer::Configuration.to_regex?(i) }
|
|
51
54
|
end
|
|
52
55
|
options[option.config_key.to_sym] = opts[option.config_key]
|
|
@@ -56,8 +59,11 @@ Mercenary.program(:htmlproofer) do |p|
|
|
|
56
59
|
unless opts['url_swap'].nil?
|
|
57
60
|
options[:url_swap] = {}
|
|
58
61
|
opts['url_swap'].each do |s|
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
splt = s.split(/(?<!\\):/,2)
|
|
63
|
+
|
|
64
|
+
re = splt[0].gsub(/\\:/, ':')
|
|
65
|
+
string = splt[1].gsub(/\\:/, ':')
|
|
66
|
+
options[:url_swap][Regexp.new(re)] = string
|
|
61
67
|
end
|
|
62
68
|
end
|
|
63
69
|
|
|
@@ -67,11 +73,14 @@ Mercenary.program(:htmlproofer) do |p|
|
|
|
67
73
|
# FIXME: this is gross
|
|
68
74
|
options[:validation] = {}
|
|
69
75
|
options[:validation][:report_script_embeds] = opts['report_script_embeds']
|
|
76
|
+
options[:validation][:report_missing_names] = opts['report_missing_names']
|
|
70
77
|
options[:validation][:report_invalid_tags] = opts['report_invalid_tags']
|
|
71
78
|
|
|
72
79
|
options[:cache] = {}
|
|
73
80
|
options[:cache][:timeframe] = opts['timeframe'] unless opts['timeframe'].nil?
|
|
74
81
|
|
|
82
|
+
options[:http_status_ignore] = Array(options[:http_status_ignore]).map(&:to_i)
|
|
83
|
+
|
|
75
84
|
paths = path.split(',')
|
|
76
85
|
if opts['as_links']
|
|
77
86
|
links = path.delete(' ').split(',')
|
|
@@ -2,6 +2,7 @@ class HtmlCheck < ::HTMLProofer::Check
|
|
|
2
2
|
SCRIPT_EMBEDS_MSG = /Element script embeds close tag/
|
|
3
3
|
INVALID_TAG_MSG = /Tag ([\w\-:]+) invalid/
|
|
4
4
|
INVALID_PREFIX = /Namespace prefix/
|
|
5
|
+
PARSE_ENTITY_REF = /htmlParseEntityRef: no name/
|
|
5
6
|
|
|
6
7
|
def run
|
|
7
8
|
@html.errors.each do |error|
|
|
@@ -12,6 +13,10 @@ class HtmlCheck < ::HTMLProofer::Check
|
|
|
12
13
|
next unless options[:validation][:report_invalid_tags]
|
|
13
14
|
end
|
|
14
15
|
|
|
16
|
+
if message =~ PARSE_ENTITY_REF
|
|
17
|
+
next unless options[:validation][:report_missing_names]
|
|
18
|
+
end
|
|
19
|
+
|
|
15
20
|
# tags embedded in scripts are used in templating languages: http://git.io/vOovv
|
|
16
21
|
next if !options[:validation][:report_script_embeds] && message =~ SCRIPT_EMBEDS_MSG
|
|
17
22
|
|
|
@@ -37,9 +37,13 @@ class ImageCheck < ::HTMLProofer::Check
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
if @img.alt.nil? || (empty_alt_tag? && !@img.ignore_empty_alt?)
|
|
40
|
+
if !@img.ignore_alt? && (@img.alt.nil? || (empty_alt_tag? && !@img.ignore_empty_alt?))
|
|
41
41
|
add_issue("image #{@img.url} does not have an alt attribute", line: line)
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
if @img.check_img_http? && @img.scheme == 'http'
|
|
45
|
+
add_issue("image #{@img.url} uses the http scheme", line: line)
|
|
46
|
+
end
|
|
43
47
|
end
|
|
44
48
|
|
|
45
49
|
external_urls
|
|
@@ -9,6 +9,7 @@ module HTMLProofer
|
|
|
9
9
|
:check_external_hash => false,
|
|
10
10
|
:check_favicon => false,
|
|
11
11
|
:check_html => false,
|
|
12
|
+
:check_img_http => false,
|
|
12
13
|
:checks_to_ignore => [],
|
|
13
14
|
:directory_index_file => 'index.html',
|
|
14
15
|
:disable_external => false,
|
|
@@ -19,10 +20,11 @@ module HTMLProofer
|
|
|
19
20
|
:external_only => false,
|
|
20
21
|
:file_ignore => [],
|
|
21
22
|
:http_status_ignore => [],
|
|
23
|
+
:internal_domains => [],
|
|
22
24
|
:log_level => :info,
|
|
23
25
|
:only_4xx => false,
|
|
24
26
|
:url_ignore => [],
|
|
25
|
-
:url_swap =>
|
|
27
|
+
:url_swap => {}
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
TYPHOEUS_DEFAULTS = {
|
|
@@ -40,6 +42,7 @@ module HTMLProofer
|
|
|
40
42
|
|
|
41
43
|
VALIDATION_DEFAULTS = {
|
|
42
44
|
:report_script_embeds => false,
|
|
45
|
+
:report_missing_names => false,
|
|
43
46
|
:report_invalid_tags => false
|
|
44
47
|
}
|
|
45
48
|
|
data/lib/html-proofer/element.rb
CHANGED
|
@@ -6,10 +6,10 @@ module HTMLProofer
|
|
|
6
6
|
class Element
|
|
7
7
|
include HTMLProofer::Utils
|
|
8
8
|
|
|
9
|
-
attr_reader :id, :name, :alt, :href, :link, :src, :line
|
|
9
|
+
attr_reader :id, :name, :alt, :href, :link, :src, :line, :data_proofer_ignore
|
|
10
10
|
|
|
11
11
|
def initialize(obj, check)
|
|
12
|
-
#
|
|
12
|
+
# Construct readable ivars for every element
|
|
13
13
|
obj.attributes.each_pair do |attribute, value|
|
|
14
14
|
name = "#{attribute.tr('-:.', '_')}".to_sym
|
|
15
15
|
(class << self; self; end).send(:attr_reader, name)
|
|
@@ -25,10 +25,11 @@ module HTMLProofer
|
|
|
25
25
|
# fix up missing protocols
|
|
26
26
|
@href.insert 0, 'http:' if @href =~ %r{^//}
|
|
27
27
|
@src.insert 0, 'http:' if @src =~ %r{^//}
|
|
28
|
+
@srcset.insert 0, 'http:' if @srcset =~ %r{^//}
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def url
|
|
31
|
-
url = @src || @srcset || @href || ''
|
|
32
|
+
url = (@src || @srcset || @href || '').gsub("\u200b", '')
|
|
32
33
|
return url if @check.options[:url_swap].empty?
|
|
33
34
|
swap(url, @check.options[:url_swap])
|
|
34
35
|
end
|
|
@@ -39,7 +40,7 @@ module HTMLProofer
|
|
|
39
40
|
|
|
40
41
|
def parts
|
|
41
42
|
@parts ||= Addressable::URI.parse url
|
|
42
|
-
rescue URI::Error, Addressable::URI::InvalidURIError
|
|
43
|
+
rescue URI::Error, Addressable::URI::InvalidURIError => e
|
|
43
44
|
@parts = nil
|
|
44
45
|
end
|
|
45
46
|
|
|
@@ -76,9 +77,9 @@ module HTMLProofer
|
|
|
76
77
|
|
|
77
78
|
# ignore user defined URLs
|
|
78
79
|
return true if ignores_pattern_check(@check.options[:url_ignore])
|
|
80
|
+
end
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
return false unless 'ImageCheck' == @type
|
|
82
|
+
def ignore_alt?
|
|
82
83
|
return true if ignores_pattern_check(@check.options[:alt_ignore])
|
|
83
84
|
end
|
|
84
85
|
|
|
@@ -90,6 +91,10 @@ module HTMLProofer
|
|
|
90
91
|
@check.options[:allow_hash_href]
|
|
91
92
|
end
|
|
92
93
|
|
|
94
|
+
def check_img_http?
|
|
95
|
+
@check.options[:check_img_http]
|
|
96
|
+
end
|
|
97
|
+
|
|
93
98
|
# path is external to the file
|
|
94
99
|
def external?
|
|
95
100
|
!internal?
|
data/lib/html-proofer/runner.rb
CHANGED
|
@@ -23,6 +23,15 @@ module HTMLProofer
|
|
|
23
23
|
FileUtils.mkdir_p(STORAGE_DIR)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# Add swap patterns for internal domains
|
|
27
|
+
unless @options[:internal_domains].empty?
|
|
28
|
+
@options[:internal_domains].each do |dom|
|
|
29
|
+
@options[:url_swap][Regexp.new("^http://#{dom}")] = ''
|
|
30
|
+
@options[:url_swap][Regexp.new("^https://#{dom}")] = ''
|
|
31
|
+
@options[:url_swap][Regexp.new("^//#{dom}")] = ''
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
26
35
|
@failures = []
|
|
27
36
|
end
|
|
28
37
|
|
|
@@ -96,7 +105,11 @@ module HTMLProofer
|
|
|
96
105
|
@logger.log :debug, "Checking #{klass.to_s.downcase} on #{path} ..."
|
|
97
106
|
check = Object.const_get(klass).new(src, path, html, @options)
|
|
98
107
|
check.run
|
|
99
|
-
|
|
108
|
+
external_urls = check.external_urls
|
|
109
|
+
if @options[:url_swap]
|
|
110
|
+
external_urls = Hash[check.external_urls.map { |url, file| [swap(url, @options[:url_swap]), file] }]
|
|
111
|
+
end
|
|
112
|
+
result[:external_urls].merge!(external_urls)
|
|
100
113
|
result[:failures].concat(check.issues)
|
|
101
114
|
end
|
|
102
115
|
end
|
|
@@ -150,7 +150,7 @@ module HTMLProofer
|
|
|
150
150
|
elsif response.timed_out?
|
|
151
151
|
handle_timeout(href, filenames, response_code)
|
|
152
152
|
elsif response_code == 0
|
|
153
|
-
handle_failure(href, filenames, response_code)
|
|
153
|
+
handle_failure(href, filenames, response_code, response.return_message)
|
|
154
154
|
elsif method == :head
|
|
155
155
|
queue_request(:get, href, filenames)
|
|
156
156
|
else
|
|
@@ -192,8 +192,11 @@ module HTMLProofer
|
|
|
192
192
|
add_external_issue(filenames, msg, response_code)
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
-
def handle_failure(href, filenames, response_code)
|
|
196
|
-
msg = "External link #{href} failed: response code #{response_code} means something's wrong
|
|
195
|
+
def handle_failure(href, filenames, response_code, return_message)
|
|
196
|
+
msg = "External link #{href} failed: response code #{response_code} means something's wrong.
|
|
197
|
+
It's possible libcurl couldn't connect to the server or perhaps the request timed out.
|
|
198
|
+
Sometimes, making too many requests at once also breaks things.
|
|
199
|
+
Either way, the return message (if any) from the server is: #{return_message}"
|
|
197
200
|
@cache.add(href, filenames, 0, msg)
|
|
198
201
|
return if @options[:only_4xx]
|
|
199
202
|
add_external_issue(filenames, msg, response_code)
|
data/lib/html-proofer/version.rb
CHANGED
data/lib/html-proofer.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
def require_all(path)
|
|
2
|
-
|
|
3
|
-
Dir[
|
|
2
|
+
dir = File.join(File.dirname(__FILE__), path)
|
|
3
|
+
Dir[File.join(dir, '*.rb')].each do |f|
|
|
4
4
|
require f
|
|
5
5
|
end
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
require_relative 'html-proofer/utils'
|
|
8
9
|
require_all 'html-proofer'
|
|
9
10
|
require_all 'html-proofer/check'
|
|
10
11
|
|
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.
|
|
4
|
+
version: 3.1.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: 2016-
|
|
11
|
+
date: 2016-09-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: mercenary
|
|
@@ -112,16 +112,22 @@ dependencies:
|
|
|
112
112
|
name: activesupport
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
|
-
- - "
|
|
115
|
+
- - ">="
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
117
|
version: '4.2'
|
|
118
|
+
- - "<"
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '6.0'
|
|
118
121
|
type: :runtime
|
|
119
122
|
prerelease: false
|
|
120
123
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
124
|
requirements:
|
|
122
|
-
- - "
|
|
125
|
+
- - ">="
|
|
123
126
|
- !ruby/object:Gem::Version
|
|
124
127
|
version: '4.2'
|
|
128
|
+
- - "<"
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '6.0'
|
|
125
131
|
- !ruby/object:Gem::Dependency
|
|
126
132
|
name: redcarpet
|
|
127
133
|
requirement: !ruby/object:Gem::Requirement
|