html-proofer 5.0.3 → 5.0.4
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/lib/html_proofer/attribute/url.rb +8 -4
- data/lib/html_proofer/check/favicon.rb +10 -4
- data/lib/html_proofer/check/images.rb +35 -14
- data/lib/html_proofer/check/links.rb +35 -14
- data/lib/html_proofer/check/open_graph.rb +10 -4
- data/lib/html_proofer/check/scripts.rb +25 -10
- data/lib/html_proofer/check.rb +8 -2
- data/lib/html_proofer/configuration.rb +42 -22
- data/lib/html_proofer/log.rb +4 -2
- data/lib/html_proofer/runner.rb +4 -2
- data/lib/html_proofer/url_validator/external.rb +31 -3
- data/lib/html_proofer/url_validator/internal.rb +24 -6
- data/lib/html_proofer/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: faaebfa9ea13bfed7e8e4814ca266066f29b04d8bde57675db9e84d560a68064
|
4
|
+
data.tar.gz: e0db29fac2c3bb8f974986bb34f2a6b32b529e4921b84f513d17bcc1d9a8ede8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff8490d4416a9336818563c08311b1a0f227225969d00dd99f33e3db99b7c06d184e1658fad45a41684f65bb2c7e669aa13c6de616b2e3189d84c43e95402061
|
7
|
+
data.tar.gz: 2edb3c5fdbd02a279e934f9ed238b5fc50e7ceabd4858492d3e0f052209716f012fa6f8efa43576a803d68b709e65b4bb53c9d0cba3ff4ce19702a97a7fa1e0c
|
@@ -141,12 +141,16 @@ module HTMLProofer
|
|
141
141
|
# either overwrite with root_dir; or, if source is directory, use that; or, just get the current file's dirname
|
142
142
|
@runner.options[:root_dir] || (File.directory?(@runner.current_source) ? @runner.current_source : File.dirname(@runner.current_source))
|
143
143
|
# relative links, path is a file
|
144
|
-
elsif File.exist?(File.expand_path(
|
145
|
-
|
144
|
+
elsif File.exist?(File.expand_path(
|
145
|
+
path,
|
146
|
+
@runner.current_source,
|
147
|
+
)) || File.exist?(File.expand_path(path_dot_ext, @runner.current_source))
|
146
148
|
File.dirname(@runner.current_filename)
|
147
149
|
# relative links in nested dir, path is a file
|
148
|
-
elsif File.exist?(File.join(
|
149
|
-
|
150
|
+
elsif File.exist?(File.join(
|
151
|
+
File.dirname(@runner.current_filename),
|
152
|
+
path,
|
153
|
+
)) || File.exist?(File.join(File.dirname(@runner.current_filename), path_dot_ext))
|
150
154
|
File.dirname(@runner.current_filename)
|
151
155
|
# relative link, path is a directory
|
152
156
|
else
|
@@ -17,13 +17,19 @@ module HTMLProofer
|
|
17
17
|
|
18
18
|
if found
|
19
19
|
if @favicon.url.protocol_relative?
|
20
|
-
add_failure(
|
21
|
-
|
20
|
+
add_failure(
|
21
|
+
"favicon link #{@favicon.url} is a protocol-relative URL, use explicit https:// instead",
|
22
|
+
line: @favicon.line,
|
23
|
+
content: @favicon.content,
|
24
|
+
)
|
22
25
|
elsif @favicon.url.remote?
|
23
26
|
add_to_external_urls(@favicon.url, @favicon.line)
|
24
27
|
elsif !@favicon.url.exists?
|
25
|
-
add_failure(
|
26
|
-
|
28
|
+
add_failure(
|
29
|
+
"internal favicon #{@favicon.url.raw_attribute} does not exist",
|
30
|
+
line: @favicon.line,
|
31
|
+
content: @favicon.content,
|
32
|
+
)
|
27
33
|
end
|
28
34
|
else
|
29
35
|
add_failure("no favicon provided")
|
@@ -12,27 +12,39 @@ module HTMLProofer
|
|
12
12
|
next if @img.ignore?
|
13
13
|
|
14
14
|
# screenshot filenames should return because of terrible names
|
15
|
-
add_failure(
|
16
|
-
|
15
|
+
add_failure(
|
16
|
+
"image has a terrible filename (#{@img.url.raw_attribute})",
|
17
|
+
line: @img.line,
|
18
|
+
content: @img.content,
|
19
|
+
) if terrible_filename?
|
17
20
|
|
18
21
|
# does the image exist?
|
19
22
|
if missing_src?
|
20
23
|
add_failure("image has no src or srcset attribute", line: @img.line, content: @img.content)
|
21
24
|
elsif @img.url.protocol_relative?
|
22
|
-
add_failure(
|
23
|
-
|
25
|
+
add_failure(
|
26
|
+
"image link #{@img.url} is a protocol-relative URL, use explicit https:// instead",
|
27
|
+
line: @img.line,
|
28
|
+
content: @img.content,
|
29
|
+
)
|
24
30
|
elsif @img.url.remote?
|
25
31
|
add_to_external_urls(@img.url, @img.line)
|
26
32
|
elsif !@img.url.exists? && !@img.multiple_srcsets? && !@img.multiple_sizes?
|
27
|
-
add_failure(
|
28
|
-
|
33
|
+
add_failure(
|
34
|
+
"internal image #{@img.url.raw_attribute} does not exist",
|
35
|
+
line: @img.line,
|
36
|
+
content: @img.content,
|
37
|
+
)
|
29
38
|
elsif @img.multiple_srcsets? || @img.multiple_sizes?
|
30
39
|
@img.srcsets_wo_sizes.each do |srcset|
|
31
40
|
srcset_url = HTMLProofer::Attribute::Url.new(@runner, srcset, base_url: @img.base_url, extract_size: true)
|
32
41
|
|
33
42
|
if srcset_url.protocol_relative?
|
34
|
-
add_failure(
|
35
|
-
|
43
|
+
add_failure(
|
44
|
+
"image link #{srcset_url.url} is a protocol-relative URL, use explicit https:// instead",
|
45
|
+
line: @img.line,
|
46
|
+
content: @img.content,
|
47
|
+
)
|
36
48
|
elsif srcset_url.remote?
|
37
49
|
add_to_external_urls(srcset_url.url, @img.line)
|
38
50
|
elsif !srcset_url.exists?
|
@@ -44,16 +56,25 @@ module HTMLProofer
|
|
44
56
|
# if this is an img element, check that the alt attribute is present
|
45
57
|
if @img.img_tag? && !ignore_element?
|
46
58
|
if missing_alt_tag? && !ignore_missing_alt?
|
47
|
-
add_failure(
|
48
|
-
|
59
|
+
add_failure(
|
60
|
+
"image #{@img.url.raw_attribute} does not have an alt attribute",
|
61
|
+
line: @img.line,
|
62
|
+
content: @img.content,
|
63
|
+
)
|
49
64
|
elsif (empty_alt_tag? || alt_all_spaces?) && !ignore_empty_alt?
|
50
|
-
add_failure(
|
51
|
-
|
65
|
+
add_failure(
|
66
|
+
"image #{@img.url.raw_attribute} has an alt attribute, but no content",
|
67
|
+
line: @img.line,
|
68
|
+
content: @img.content,
|
69
|
+
)
|
52
70
|
end
|
53
71
|
end
|
54
72
|
|
55
|
-
add_failure(
|
56
|
-
|
73
|
+
add_failure(
|
74
|
+
"image #{@img.url.raw_attribute} uses the http scheme",
|
75
|
+
line: @img.line,
|
76
|
+
content: @img.content,
|
77
|
+
) if @runner.enforce_https? && @img.url.http?
|
57
78
|
end
|
58
79
|
|
59
80
|
external_urls
|
@@ -29,8 +29,11 @@ module HTMLProofer
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if @link.url.protocol_relative?
|
32
|
-
add_failure(
|
33
|
-
|
32
|
+
add_failure(
|
33
|
+
"#{@link.url} is a protocol-relative URL, use explicit https:// instead",
|
34
|
+
line: @link.line,
|
35
|
+
content: @link.content,
|
36
|
+
)
|
34
37
|
next
|
35
38
|
end
|
36
39
|
|
@@ -55,8 +58,11 @@ module HTMLProofer
|
|
55
58
|
elsif @link.url.internal?
|
56
59
|
# does the local directory have a trailing slash?
|
57
60
|
if @link.url.unslashed_directory?(@link.url.absolute_path)
|
58
|
-
add_failure(
|
59
|
-
|
61
|
+
add_failure(
|
62
|
+
"internally linking to a directory #{@link.url.raw_attribute} without trailing slash",
|
63
|
+
line: @link.line,
|
64
|
+
content: @link.content,
|
65
|
+
)
|
60
66
|
next
|
61
67
|
end
|
62
68
|
|
@@ -88,17 +94,26 @@ module HTMLProofer
|
|
88
94
|
|
89
95
|
def handle_mailto
|
90
96
|
if @link.url.path.empty?
|
91
|
-
add_failure(
|
92
|
-
|
97
|
+
add_failure(
|
98
|
+
"#{@link.url.raw_attribute} contains no email address",
|
99
|
+
line: @link.line,
|
100
|
+
content: @link.content,
|
101
|
+
) unless ignore_empty_mailto?
|
93
102
|
elsif !/#{URI::MailTo::EMAIL_REGEXP}/o.match?(@link.url.path)
|
94
|
-
add_failure(
|
95
|
-
|
103
|
+
add_failure(
|
104
|
+
"#{@link.url.raw_attribute} contains an invalid email address",
|
105
|
+
line: @link.line,
|
106
|
+
content: @link.content,
|
107
|
+
)
|
96
108
|
end
|
97
109
|
end
|
98
110
|
|
99
111
|
def handle_tel
|
100
|
-
add_failure(
|
101
|
-
|
112
|
+
add_failure(
|
113
|
+
"#{@link.url.raw_attribute} contains no phone number",
|
114
|
+
line: @link.line,
|
115
|
+
content: @link.content,
|
116
|
+
) if @link.url.path.empty?
|
102
117
|
end
|
103
118
|
|
104
119
|
def ignore_empty_mailto?
|
@@ -113,13 +128,19 @@ module HTMLProofer
|
|
113
128
|
return unless SRI_REL_TYPES.include?(@link.node["rel"])
|
114
129
|
|
115
130
|
if blank?(@link.node["integrity"]) && blank?(@link.node["crossorigin"])
|
116
|
-
add_failure(
|
117
|
-
|
131
|
+
add_failure(
|
132
|
+
"SRI and CORS not provided in: #{@link.url.raw_attribute}",
|
133
|
+
line: @link.line,
|
134
|
+
content: @link.content,
|
135
|
+
)
|
118
136
|
elsif blank?(@link.node["integrity"])
|
119
137
|
add_failure("Integrity is missing in: #{@link.url.raw_attribute}", line: @link.line, content: @link.content)
|
120
138
|
elsif blank?(@link.node["crossorigin"])
|
121
|
-
add_failure(
|
122
|
-
|
139
|
+
add_failure(
|
140
|
+
"CORS not provided for external resource in: #{@link.link.url.raw_attribute}",
|
141
|
+
line: @link.line,
|
142
|
+
content: @link.content,
|
143
|
+
)
|
123
144
|
end
|
124
145
|
end
|
125
146
|
|
@@ -17,13 +17,19 @@ module HTMLProofer
|
|
17
17
|
elsif !@open_graph.url.valid?
|
18
18
|
add_failure("#{@open_graph.src} is an invalid URL", line: @open_graph.line)
|
19
19
|
elsif @open_graph.url.protocol_relative?
|
20
|
-
add_failure(
|
21
|
-
|
20
|
+
add_failure(
|
21
|
+
"open graph link #{@open_graph.url} is a protocol-relative URL, use explicit https:// instead",
|
22
|
+
line: @open_graph.line,
|
23
|
+
content: @open_graph.content,
|
24
|
+
)
|
22
25
|
elsif @open_graph.url.remote?
|
23
26
|
add_to_external_urls(@open_graph.url, @open_graph.line)
|
24
27
|
else
|
25
|
-
add_failure(
|
26
|
-
|
28
|
+
add_failure(
|
29
|
+
"internal open graph #{@open_graph.url.raw_attribute} does not exist",
|
30
|
+
line: @open_graph.line,
|
31
|
+
content: @open_graph.content,
|
32
|
+
) unless @open_graph.url.exists?
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
@@ -14,14 +14,20 @@ module HTMLProofer
|
|
14
14
|
if missing_src?
|
15
15
|
add_failure("script is empty and has no src attribute", line: @script.line, content: @script.content)
|
16
16
|
elsif @script.url.protocol_relative?
|
17
|
-
add_failure(
|
18
|
-
|
17
|
+
add_failure(
|
18
|
+
"script link #{@script.url} is a protocol-relative URL, use explicit https:// instead",
|
19
|
+
line: @script.line,
|
20
|
+
content: @script.content,
|
21
|
+
)
|
19
22
|
elsif @script.url.remote?
|
20
23
|
add_to_external_urls(@script.url, @script.line)
|
21
24
|
check_sri if @runner.check_sri?
|
22
25
|
elsif !@script.url.exists?
|
23
|
-
add_failure(
|
24
|
-
|
26
|
+
add_failure(
|
27
|
+
"internal script reference #{@script.src} does not exist",
|
28
|
+
line: @script.line,
|
29
|
+
content: @script.content,
|
30
|
+
)
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
@@ -34,14 +40,23 @@ module HTMLProofer
|
|
34
40
|
|
35
41
|
def check_sri
|
36
42
|
if blank?(@script.node["integrity"]) && blank?(@script.node["crossorigin"])
|
37
|
-
add_failure(
|
38
|
-
|
43
|
+
add_failure(
|
44
|
+
"SRI and CORS not provided in: #{@script.url.raw_attribute}",
|
45
|
+
line: @script.line,
|
46
|
+
content: @script.content,
|
47
|
+
)
|
39
48
|
elsif blank?(@script.node["integrity"])
|
40
|
-
add_failure(
|
41
|
-
|
49
|
+
add_failure(
|
50
|
+
"Integrity is missing in: #{@script.url.raw_attribute}",
|
51
|
+
line: @script.line,
|
52
|
+
content: @script.content,
|
53
|
+
)
|
42
54
|
elsif blank?(@script.node["crossorigin"])
|
43
|
-
add_failure(
|
44
|
-
|
55
|
+
add_failure(
|
56
|
+
"CORS not provided for external resource in: #{@script.url.raw_attribute}",
|
57
|
+
line: @script.line,
|
58
|
+
content: @script.content,
|
59
|
+
)
|
45
60
|
end
|
46
61
|
end
|
47
62
|
end
|
data/lib/html_proofer/check.rb
CHANGED
@@ -25,8 +25,14 @@ module HTMLProofer
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def add_failure(description, line: nil, status: nil, content: nil)
|
28
|
-
@failures << Failure.new(
|
29
|
-
|
28
|
+
@failures << Failure.new(
|
29
|
+
@runner.current_filename,
|
30
|
+
short_name,
|
31
|
+
description,
|
32
|
+
line: line,
|
33
|
+
status: status,
|
34
|
+
content: content,
|
35
|
+
)
|
30
36
|
end
|
31
37
|
|
32
38
|
def short_name
|
@@ -280,17 +280,25 @@ module HTMLProofer
|
|
280
280
|
module ConfigurationHelp
|
281
281
|
TEXT = {
|
282
282
|
as_links: ["Assumes that `PATH` is a comma-separated array of links to check."],
|
283
|
-
assume_extension: [
|
284
|
-
|
283
|
+
assume_extension: [
|
284
|
+
"Automatically add specified extension to files for internal links, ",
|
285
|
+
"to allow extensionless URLs (as supported by most servers) (default: `.html`).",
|
286
|
+
],
|
285
287
|
directory_index_file: ["Sets the file to look for when a link refers to a directory. (default: `index.html`)."],
|
286
|
-
extensions: [
|
287
|
-
|
288
|
+
extensions: [
|
289
|
+
"A comma-separated list of Strings indicating the file extensions you",
|
290
|
+
"would like to check (default: `.html`)",
|
291
|
+
],
|
288
292
|
|
289
293
|
allow_hash_href: ['"If `true`, assumes `href="#"` anchors are valid (default: `true`)"'],
|
290
|
-
allow_missing_href: [
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
+
allow_missing_href: [
|
295
|
+
"If `true`, does not flag `a` tags missing `href`. In HTML5, this is technically ",
|
296
|
+
"allowed, but could also be human error. (default: `false`)",
|
297
|
+
],
|
298
|
+
checks: [
|
299
|
+
"A comma-separated list of Strings indicating which checks you",
|
300
|
+
"want to run (default: `[\"Links\", \"Images\", \"Scripts\"]",
|
301
|
+
],
|
294
302
|
check_external_hash: ["Checks whether external hashes exist (even if the webpage exists) (default: `true`)."],
|
295
303
|
check_internal_hash: ["Checks whether internal hashes exist (even if the webpage exists) (default: `true`)."],
|
296
304
|
check_sri: ["Check that `<link>` and `<script>` external resources use SRI (default: `false`)."],
|
@@ -298,31 +306,43 @@ module HTMLProofer
|
|
298
306
|
enforce_https: ["Fails a link if it's not marked as `https` (default: `true`)."],
|
299
307
|
root_dir: ["The absolute path to the directory serving your html-files."],
|
300
308
|
|
301
|
-
ignore_empty_alt: [
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
309
|
+
ignore_empty_alt: [
|
310
|
+
"If `true`, ignores images with empty/missing ",
|
311
|
+
"alt tags (in other words, `<img alt>` and `<img alt=\"\">`",
|
312
|
+
"are valid; set this to `false` to flag those) (default: `true`).",
|
313
|
+
],
|
314
|
+
ignore_empty_mailto: [
|
315
|
+
"If `true`, allows `mailto:` `href`s which don't",
|
316
|
+
"contain an email address (default: `false`)'.",
|
317
|
+
],
|
306
318
|
ignore_missing_alt: ["If `true`, ignores images with missing alt tags (default: `false`)."],
|
307
319
|
ignore_status_codes: ["A comma-separated list of numbers representing status codes to ignore."],
|
308
320
|
ignore_files: ["A comma-separated list of Strings or RegExps containing file paths that are safe to ignore"],
|
309
|
-
ignore_urls: [
|
310
|
-
|
321
|
+
ignore_urls: [
|
322
|
+
"A comma-separated list of Strings or RegExps containing URLs that are",
|
323
|
+
"safe to ignore. This affects all HTML attributes, such as `alt` tags on images.",
|
324
|
+
],
|
311
325
|
only_status_codes: ["A comma-separated list of numbers representing the only status codes to report on."],
|
312
326
|
only_4xx: ["Only reports errors for links that fall within the 4xx status code range."],
|
313
327
|
|
314
|
-
swap_attributes: [
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
328
|
+
swap_attributes: [
|
329
|
+
"JSON-formatted config that maps element names to the",
|
330
|
+
"preferred attribute to check (default: `{}`).",
|
331
|
+
],
|
332
|
+
swap_urls: [
|
333
|
+
"A comma-separated list containing key-value pairs of `RegExp => String`.",
|
334
|
+
"It transforms URLs that match `RegExp` into `String` via `gsub`.",
|
335
|
+
"The escape sequences `\\:` should be used to produce literal `:`s.",
|
336
|
+
],
|
319
337
|
|
320
338
|
typhoeus: ["JSON-formatted string of Typhoeus config; if set, overrides the html-proofer defaults."],
|
321
339
|
hydra: ["JSON-formatted string of Hydra config; if set, overrides the html-proofer defaults."],
|
322
340
|
cache: ["JSON-formatted string of cache config; if set, overrides the html-proofer defaults."],
|
323
341
|
|
324
|
-
log_level: [
|
325
|
-
|
342
|
+
log_level: [
|
343
|
+
"Sets the logging level. One of `:debug`, `:info`, ",
|
344
|
+
"`:warn`, `:error`, or `:fatal`. (default: `:info`)",
|
345
|
+
],
|
326
346
|
|
327
347
|
version: ["Prints the version of html-proofer."],
|
328
348
|
}.freeze
|
data/lib/html_proofer/log.rb
CHANGED
@@ -11,9 +11,11 @@ module HTMLProofer
|
|
11
11
|
STDERR_LEVELS = [:error, :fatal].freeze
|
12
12
|
|
13
13
|
def initialize(log_level)
|
14
|
-
@logger = Yell.new(
|
14
|
+
@logger = Yell.new(
|
15
|
+
format: false, \
|
15
16
|
name: "HTMLProofer", \
|
16
|
-
level: "gte.#{log_level}"
|
17
|
+
level: "gte.#{log_level}",
|
18
|
+
) do |l|
|
17
19
|
l.adapter(:stdout, level: "lte.warn")
|
18
20
|
l.adapter(:stderr, level: "gte.error")
|
19
21
|
end
|
data/lib/html_proofer/runner.rb
CHANGED
@@ -42,8 +42,10 @@ module HTMLProofer
|
|
42
42
|
@logger.log(:info, "Running #{check_text} (#{format_checks_list(checks)}) on #{@source} ...\n\n")
|
43
43
|
check_list_of_links unless @options[:disable_external]
|
44
44
|
else
|
45
|
-
@logger.log(
|
46
|
-
|
45
|
+
@logger.log(
|
46
|
+
:info,
|
47
|
+
"Running #{check_text} (#{format_checks_list(checks)}) in #{@source} on *#{@options[:extensions].join(", ")} files ...\n\n",
|
48
|
+
)
|
47
49
|
|
48
50
|
check_files
|
49
51
|
@logger.log(:info, "Ran on #{pluralize(files.length, "file", "files")}!\n\n")
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "typhoeus"
|
4
|
-
require "uri"
|
4
|
+
require "open-uri"
|
5
|
+
# require "uri"
|
6
|
+
require "pdf-reader"
|
5
7
|
|
6
8
|
module HTMLProofer
|
7
9
|
class UrlValidator
|
@@ -88,8 +90,12 @@ module HTMLProofer
|
|
88
90
|
return if @runner.options[:ignore_status_codes].include?(response_code)
|
89
91
|
|
90
92
|
if response_code.between?(200, 299)
|
91
|
-
@cache.add_external(href, filenames, response_code, "OK", true) unless check_hash_in_2xx_response(
|
92
|
-
|
93
|
+
@cache.add_external(href, filenames, response_code, "OK", true) unless check_hash_in_2xx_response(
|
94
|
+
href,
|
95
|
+
url,
|
96
|
+
response,
|
97
|
+
filenames,
|
98
|
+
)
|
93
99
|
elsif response.timed_out?
|
94
100
|
handle_timeout(href, filenames, response_code)
|
95
101
|
elsif response_code.zero?
|
@@ -115,6 +121,28 @@ module HTMLProofer
|
|
115
121
|
return false unless url.hash?
|
116
122
|
|
117
123
|
hash = url.hash
|
124
|
+
headers = response.options.fetch(:headers, {})
|
125
|
+
content_type = headers.find { |k, _| k.casecmp("content-type").zero? }
|
126
|
+
|
127
|
+
# attempt to verify PDF hash ref; see #787 for more details
|
128
|
+
# FIXME: this is re-reading the PDF response
|
129
|
+
if content_type && /pdf/.match?(content_type[1])
|
130
|
+
io = URI.parse(url.to_s).open
|
131
|
+
reader = PDF::Reader.new(io)
|
132
|
+
|
133
|
+
pages = reader.pages
|
134
|
+
if hash =~ /\Apage=(\d+)\z/
|
135
|
+
page = Regexp.last_match[1].to_i
|
136
|
+
|
137
|
+
unless pages[page - 1]
|
138
|
+
msg = "External link #{href} failed: #{url.sans_hash} exists, but the hash '#{hash}' does not"
|
139
|
+
add_failure(filenames, msg, response.code)
|
140
|
+
@cache.add_external(href, filenames, response.code, msg, false)
|
141
|
+
end
|
142
|
+
|
143
|
+
return true
|
144
|
+
end
|
145
|
+
end
|
118
146
|
|
119
147
|
body_doc = create_nokogiri(response.body)
|
120
148
|
|
@@ -36,8 +36,14 @@ module HTMLProofer
|
|
36
36
|
|
37
37
|
target_file_path = url.absolute_path
|
38
38
|
unless file_exists?(target_file_path)
|
39
|
-
@failed_checks << Failure.new(
|
40
|
-
|
39
|
+
@failed_checks << Failure.new(
|
40
|
+
@runner.current_filename,
|
41
|
+
"Links > Internal",
|
42
|
+
"internally linking to #{url}, which does not exist",
|
43
|
+
line: metadata[:line],
|
44
|
+
status: nil,
|
45
|
+
content: nil,
|
46
|
+
)
|
41
47
|
to_add << [url, metadata, false]
|
42
48
|
next
|
43
49
|
end
|
@@ -55,8 +61,14 @@ module HTMLProofer
|
|
55
61
|
next
|
56
62
|
end
|
57
63
|
unless hash_exists
|
58
|
-
@failed_checks << Failure.new(
|
59
|
-
|
64
|
+
@failed_checks << Failure.new(
|
65
|
+
@runner.current_filename,
|
66
|
+
"Links > Internal",
|
67
|
+
"internally linking to #{url}; the file exists, but the hash '#{url.hash}' does not",
|
68
|
+
line: metadata[:line],
|
69
|
+
status: nil,
|
70
|
+
content: nil,
|
71
|
+
)
|
60
72
|
to_add << [url, metadata, false]
|
61
73
|
next
|
62
74
|
end
|
@@ -75,8 +87,14 @@ module HTMLProofer
|
|
75
87
|
exists = hash_exists_in_html?(href_hash, html)
|
76
88
|
url_metadata.each do |(url, metadata)|
|
77
89
|
unless exists
|
78
|
-
@failed_checks << Failure.new(
|
79
|
-
|
90
|
+
@failed_checks << Failure.new(
|
91
|
+
metadata[:filename],
|
92
|
+
"Links > Internal",
|
93
|
+
"internally linking to #{url}; the file exists, but the hash '#{href_hash}' does not",
|
94
|
+
line: metadata[:line],
|
95
|
+
status: nil,
|
96
|
+
content: nil,
|
97
|
+
)
|
80
98
|
end
|
81
99
|
to_add << [url, metadata, exists]
|
82
100
|
end
|
data/lib/html_proofer/version.rb
CHANGED
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: 5.0.
|
4
|
+
version: 5.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garen Torikian
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.13'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pdf-reader
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.11'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.11'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rainbow
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|