html-proofer 3.6.0 → 3.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/htmlproofer +2 -2
- data/lib/html-proofer.rb +6 -6
- data/lib/html-proofer/cache.rb +21 -24
- data/lib/html-proofer/check/images.rb +4 -6
- data/lib/html-proofer/check/links.rb +27 -8
- data/lib/html-proofer/check/opengraph.rb +5 -5
- data/lib/html-proofer/check/scripts.rb +2 -2
- data/lib/html-proofer/configuration.rb +38 -38
- data/lib/html-proofer/element.rb +13 -17
- data/lib/html-proofer/log.rb +5 -5
- data/lib/html-proofer/runner.rb +2 -2
- data/lib/html-proofer/url_validator.rb +3 -3
- data/lib/html-proofer/utils.rb +5 -5
- data/lib/html-proofer/version.rb +1 -1
- metadata +33 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6849cc3fcff2f9484b194cbeb1e6a74c5ce569df
|
4
|
+
data.tar.gz: a926c5b784dc04b8437b042b11fd96b9f2e0e822
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc5fb91918a157a54496abc4340f4731507a393aca4da5ce21f2afd42c83d49b7636d48777acabb1542e4854944aa0242c798605b3966fb5e55ee805648736d3
|
7
|
+
data.tar.gz: 1d7b2107525185bcdc87647c958f71c00d0fa575665a852306de8f945fb18652ad467b76473d5255d1b11de5c101e164363984340385de47aee7cc5482a713ea
|
data/bin/htmlproofer
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
STDOUT.sync = true
|
3
3
|
|
4
|
-
$LOAD_PATH.unshift File.join(File.dirname(__FILE__),
|
4
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
5
5
|
|
6
6
|
require 'html-proofer'
|
7
7
|
require 'mercenary'
|
@@ -51,7 +51,7 @@ Mercenary.program(:htmlproofer) do |p|
|
|
51
51
|
options = {}
|
52
52
|
|
53
53
|
# prepare everything to go to proofer
|
54
|
-
p.options.
|
54
|
+
p.options.reject { |o| opts[o.config_key].nil? }.each do |option|
|
55
55
|
if opts[option.config_key].is_a?(Array)
|
56
56
|
opts[option.config_key] = opts[option.config_key].map { |i| HTMLProofer::Configuration.to_regex?(i) }
|
57
57
|
end
|
data/lib/html-proofer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# rubocop:disable Style/FileName
|
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|
|
@@ -16,32 +18,30 @@ begin
|
|
16
18
|
require 'awesome_print'
|
17
19
|
require 'pry'
|
18
20
|
rescue LoadError; end
|
19
|
-
|
20
21
|
module HTMLProofer
|
21
|
-
|
22
22
|
def check_file(file, options = {})
|
23
|
-
|
23
|
+
raise ArgumentError unless file.is_a?(String)
|
24
24
|
options[:type] = :file
|
25
25
|
HTMLProofer::Runner.new(file, options)
|
26
26
|
end
|
27
27
|
module_function :check_file
|
28
28
|
|
29
29
|
def check_directory(directory, options = {})
|
30
|
-
|
30
|
+
raise ArgumentError unless directory.is_a?(String)
|
31
31
|
options[:type] = :directory
|
32
32
|
HTMLProofer::Runner.new([directory], options)
|
33
33
|
end
|
34
34
|
module_function :check_directory
|
35
35
|
|
36
36
|
def check_directories(directories, options = {})
|
37
|
-
|
37
|
+
raise ArgumentError unless directories.is_a?(Array)
|
38
38
|
options[:type] = :directory
|
39
39
|
HTMLProofer::Runner.new(directories, options)
|
40
40
|
end
|
41
41
|
module_function :check_directories
|
42
42
|
|
43
43
|
def check_links(links, options = {})
|
44
|
-
|
44
|
+
raise ArgumentError unless links.is_a?(Array)
|
45
45
|
options[:type] = :links
|
46
46
|
HTMLProofer::Runner.new(links, options)
|
47
47
|
end
|
data/lib/html-proofer/cache.rb
CHANGED
@@ -10,7 +10,7 @@ module HTMLProofer
|
|
10
10
|
include HTMLProofer::Utils
|
11
11
|
|
12
12
|
DEFAULT_STORAGE_DIR = File.join('tmp', '.htmlproofer')
|
13
|
-
DEFAULT_CACHE_FILE_NAME =
|
13
|
+
DEFAULT_CACHE_FILE_NAME = 'cache.log'.freeze
|
14
14
|
|
15
15
|
attr_reader :exists, :cache_log, :storage_dir, :cache_file
|
16
16
|
|
@@ -54,17 +54,17 @@ module HTMLProofer
|
|
54
54
|
when 'h'
|
55
55
|
time.hours.ago
|
56
56
|
else
|
57
|
-
|
57
|
+
raise ArgumentError, "#{date} is not a valid timeframe!"
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
def add(url, filenames, status, msg = '')
|
62
62
|
data = {
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
time: @cache_time,
|
64
|
+
filenames: filenames,
|
65
|
+
status: status,
|
66
|
+
message: msg
|
67
|
+
}
|
68
68
|
|
69
69
|
@cache_log[clean_url(url)] = data
|
70
70
|
end
|
@@ -148,28 +148,25 @@ module HTMLProofer
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def setup_cache!(options)
|
151
|
-
if options[:storage_dir]
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
151
|
+
@storage_dir = if options[:storage_dir]
|
152
|
+
options[:storage_dir]
|
153
|
+
else
|
154
|
+
DEFAULT_STORAGE_DIR
|
155
|
+
end
|
156
156
|
|
157
|
-
|
158
|
-
FileUtils.mkdir_p(storage_dir)
|
159
|
-
end
|
157
|
+
FileUtils.mkdir_p(storage_dir) unless Dir.exist?(storage_dir)
|
160
158
|
|
161
|
-
if options[:cache_file]
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
159
|
+
cache_file_name = if options[:cache_file]
|
160
|
+
options[:cache_file]
|
161
|
+
else
|
162
|
+
DEFAULT_CACHE_FILE_NAME
|
163
|
+
end
|
166
164
|
|
167
165
|
@cache_file = File.join(storage_dir, cache_file_name)
|
168
166
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
167
|
+
return unless File.exist?(cache_file)
|
168
|
+
contents = File.read(cache_file)
|
169
|
+
@cache_log = contents.empty? ? {} : JSON.parse(contents)
|
173
170
|
end
|
174
171
|
end
|
175
172
|
end
|
@@ -30,12 +30,10 @@ class ImageCheck < ::HTMLProofer::Check
|
|
30
30
|
# does the image exist?
|
31
31
|
if missing_src?
|
32
32
|
add_issue('image has no src or srcset attribute', line: line, content: content)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
add_issue("internal image #{@img.url} does not exist", line: line, content: content)
|
38
|
-
end
|
33
|
+
elsif @img.remote?
|
34
|
+
add_to_external_urls(@img.url)
|
35
|
+
elsif !@img.exists?
|
36
|
+
add_issue("internal image #{@img.url} does not exist", line: line, content: content)
|
39
37
|
end
|
40
38
|
|
41
39
|
if !@img.ignore_alt? && (@img.alt.nil? || (empty_alt_tag? && !@img.ignore_empty_alt?))
|
@@ -40,6 +40,7 @@ class LinkCheck < ::HTMLProofer::Check
|
|
40
40
|
next if @link.non_http_remote?
|
41
41
|
|
42
42
|
if !@link.internal? && @link.remote?
|
43
|
+
check_sri(line, content) if @link.check_sri?
|
43
44
|
# we need to skip these for now; although the domain main be valid,
|
44
45
|
# curl/Typheous inaccurately return 404s for some links. cc https://git.io/vyCFx
|
45
46
|
next if @link.try(:rel) == 'dns-prefetch'
|
@@ -107,18 +108,36 @@ class LinkCheck < ::HTMLProofer::Check
|
|
107
108
|
|
108
109
|
def hash_check(html, href_hash)
|
109
110
|
decoded_href_hash = URI.decode(href_hash)
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
111
|
+
fragment_ids = [href_hash, decoded_href_hash]
|
112
|
+
fragment_ids.include?('top') || !find_fragments(html, fragment_ids).empty?
|
113
|
+
end
|
114
|
+
|
115
|
+
def find_fragments(html, fragment_ids)
|
116
|
+
xpaths = fragment_ids.flat_map do |frag_id|
|
117
|
+
escaped_frag_id = "'#{frag_id.split("'").join("', \"'\", '")}', ''"
|
118
|
+
[
|
119
|
+
"//*[case_insensitive_equals(@id, concat(#{escaped_frag_id}))]",
|
120
|
+
"//*[case_insensitive_equals(@name, concat(#{escaped_frag_id}))]"
|
121
|
+
]
|
122
|
+
end
|
123
|
+
xpaths << XpathFunctions.new
|
124
|
+
|
125
|
+
html.xpath(*xpaths)
|
126
|
+
end
|
127
|
+
|
128
|
+
def check_sri(line, content)
|
129
|
+
if !defined?(@link.integrity) && !defined?(@link.crossorigin)
|
130
|
+
add_issue("SRI and CORS not provided in: #{@link.src}", line: line, content: content)
|
131
|
+
elsif !defined?(@link.integrity)
|
132
|
+
add_issue("Integrity is missing in: #{@link.src}", line: line, content: content)
|
133
|
+
elsif !defined?(@link.crossorigin)
|
134
|
+
add_issue("CORS not provided for external resource in: #{@link.src}", line: line, content: content)
|
135
|
+
end
|
117
136
|
end
|
118
137
|
|
119
138
|
class XpathFunctions
|
120
139
|
def case_insensitive_equals(node_set, str_to_match)
|
121
|
-
node_set.find_all {|node| node.to_s.
|
140
|
+
node_set.find_all { |node| node.to_s.casecmp(str_to_match.to_s.downcase).zero? }
|
122
141
|
end
|
123
142
|
end
|
124
143
|
end
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
class OpenGraphElement < ::HTMLProofer::Element
|
4
4
|
attr_reader :src
|
5
|
-
|
5
|
+
|
6
6
|
def initialize(obj, check)
|
7
7
|
super(obj, check)
|
8
8
|
# Fake up src from the content attribute
|
9
|
-
instance_variable_set(
|
10
|
-
|
9
|
+
instance_variable_set('@src', @content)
|
10
|
+
|
11
11
|
@src.insert 0, 'http:' if @src =~ %r{^//}
|
12
12
|
end
|
13
13
|
end
|
@@ -16,11 +16,11 @@ class OpenGraphCheck < ::HTMLProofer::Check
|
|
16
16
|
def missing_src?
|
17
17
|
!@opengraph.src
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def empty_src?
|
21
21
|
blank?(@opengraph.src)
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def run
|
25
25
|
@html.css('meta[property="og:url"], meta[property="og:image"]').each do |m|
|
26
26
|
@opengraph = OpenGraphElement.new(m, self)
|
@@ -19,17 +19,17 @@ class ScriptCheck < ::HTMLProofer::Check
|
|
19
19
|
add_issue('script is empty and has no src attribute', line: line, content: content)
|
20
20
|
elsif @script.remote?
|
21
21
|
add_to_external_urls(@script.src)
|
22
|
+
check_sri(line, content) if @script.check_sri?
|
22
23
|
elsif !@script.exists?
|
23
24
|
add_issue("internal script #{@script.src} does not exist", line: line, content: content)
|
24
25
|
end
|
25
|
-
check_sri(line, content) if @script.check_sri?
|
26
26
|
end
|
27
27
|
|
28
28
|
external_urls
|
29
29
|
end
|
30
30
|
|
31
31
|
def check_sri(line, content)
|
32
|
-
if !defined? @script.integrity
|
32
|
+
if !defined? @script.integrity && !defined? @script.crossorigin
|
33
33
|
add_issue("SRI and CORS not provided in: #{@script.src}", line: line, content: content)
|
34
34
|
elsif !defined? @script.integrity
|
35
35
|
add_issue("Integrity is missing in: #{@script.src}", line: line, content: content)
|
@@ -3,54 +3,54 @@ module HTMLProofer
|
|
3
3
|
require_relative 'version'
|
4
4
|
|
5
5
|
PROOFER_DEFAULTS = {
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
}
|
6
|
+
allow_hash_href: false,
|
7
|
+
alt_ignore: [],
|
8
|
+
assume_extension: false,
|
9
|
+
check_external_hash: false,
|
10
|
+
check_favicon: false,
|
11
|
+
check_html: false,
|
12
|
+
check_img_http: false,
|
13
|
+
check_opengraph: false,
|
14
|
+
checks_to_ignore: [],
|
15
|
+
check_sri: false,
|
16
|
+
directory_index_file: 'index.html',
|
17
|
+
disable_external: false,
|
18
|
+
empty_alt_ignore: false,
|
19
|
+
enforce_https: false,
|
20
|
+
error_sort: :path,
|
21
|
+
extension: '.html',
|
22
|
+
external_only: false,
|
23
|
+
file_ignore: [],
|
24
|
+
http_status_ignore: [],
|
25
|
+
internal_domains: [],
|
26
|
+
log_level: :info,
|
27
|
+
only_4xx: false,
|
28
|
+
url_ignore: [],
|
29
|
+
url_swap: {}
|
30
|
+
}.freeze
|
31
31
|
|
32
32
|
TYPHOEUS_DEFAULTS = {
|
33
|
-
:
|
34
|
-
:
|
33
|
+
followlocation: true,
|
34
|
+
headers: {
|
35
35
|
'User-Agent' => "Mozilla/5.0 (compatible; HTML Proofer/#{HTMLProofer::VERSION}; +https://github.com/gjtorikian/html-proofer)"
|
36
36
|
},
|
37
|
-
:
|
38
|
-
:
|
39
|
-
}
|
37
|
+
connecttimeout: 10,
|
38
|
+
timeout: 30
|
39
|
+
}.freeze
|
40
40
|
|
41
41
|
HYDRA_DEFAULTS = {
|
42
|
-
:
|
43
|
-
}
|
42
|
+
max_concurrency: 50
|
43
|
+
}.freeze
|
44
44
|
|
45
|
-
PARALLEL_DEFAULTS = {}
|
45
|
+
PARALLEL_DEFAULTS = {}.freeze
|
46
46
|
|
47
47
|
VALIDATION_DEFAULTS = {
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
}
|
48
|
+
report_script_embeds: false,
|
49
|
+
report_missing_names: false,
|
50
|
+
report_invalid_tags: false
|
51
|
+
}.freeze
|
52
52
|
|
53
|
-
CACHE_DEFAULTS = {}
|
53
|
+
CACHE_DEFAULTS = {}.freeze
|
54
54
|
|
55
55
|
def self.to_regex?(item)
|
56
56
|
if item.start_with?('/') && item.end_with?('/')
|
data/lib/html-proofer/element.rb
CHANGED
@@ -11,12 +11,12 @@ module HTMLProofer
|
|
11
11
|
def initialize(obj, check)
|
12
12
|
# Construct readable ivars for every element
|
13
13
|
obj.attributes.each_pair do |attribute, value|
|
14
|
-
name =
|
14
|
+
name = attribute.tr('-:.', '_').to_s.to_sym
|
15
15
|
(class << self; self; end).send(:attr_reader, name)
|
16
16
|
instance_variable_set("@#{name}", value.value)
|
17
17
|
end
|
18
18
|
|
19
|
-
@aria_hidden = @aria_hidden ==
|
19
|
+
@aria_hidden = @aria_hidden == 'true' ? true : false
|
20
20
|
|
21
21
|
@text = obj.content
|
22
22
|
@check = check
|
@@ -28,7 +28,7 @@ module HTMLProofer
|
|
28
28
|
|
29
29
|
parent_attributes = obj.ancestors.map { |a| a.try(:attributes) }
|
30
30
|
parent_attributes.pop # remove document at the end
|
31
|
-
@parent_ignorable = parent_attributes.any? { |a| !a[
|
31
|
+
@parent_ignorable = parent_attributes.any? { |a| !a['data-proofer-ignore'].nil? }
|
32
32
|
|
33
33
|
# fix up missing protocols
|
34
34
|
@href.insert 0, 'http:' if @href =~ %r{^//}
|
@@ -38,10 +38,8 @@ module HTMLProofer
|
|
38
38
|
|
39
39
|
def url
|
40
40
|
return @url if defined?(@url)
|
41
|
-
@url = (@src || @srcset || @href || '').
|
42
|
-
if base
|
43
|
-
@url = Addressable::URI.join(base.attr('href'), url).to_s
|
44
|
-
end
|
41
|
+
@url = (@src || @srcset || @href || '').delete("\u200b")
|
42
|
+
@url = Addressable::URI.join(base.attr('href') || '', url).to_s if base
|
45
43
|
return @url if @check.options[:url_swap].empty?
|
46
44
|
@url = swap(@url, @check.options[:url_swap])
|
47
45
|
end
|
@@ -70,7 +68,7 @@ module HTMLProofer
|
|
70
68
|
|
71
69
|
# path is to an external server
|
72
70
|
def remote?
|
73
|
-
%w
|
71
|
+
%w[http https].include? scheme
|
74
72
|
end
|
75
73
|
|
76
74
|
def non_http_remote?
|
@@ -84,7 +82,7 @@ module HTMLProofer
|
|
84
82
|
return true if url =~ /^javascript:/
|
85
83
|
|
86
84
|
# ignore base64 encoded images
|
87
|
-
if %w
|
85
|
+
if %w[ImageCheck FaviconCheck].include? @type
|
88
86
|
return true if url =~ /^data:image/
|
89
87
|
end
|
90
88
|
|
@@ -201,14 +199,12 @@ module HTMLProofer
|
|
201
199
|
end
|
202
200
|
|
203
201
|
def html
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
create_nokogiri(absolute_path)
|
211
|
-
end
|
202
|
+
# If link is on the same page, then URL is on the current page so can use the same HTML as for current page
|
203
|
+
if (hash_link || param_link) && internal?
|
204
|
+
@html
|
205
|
+
elsif slash_link && internal?
|
206
|
+
# link on another page, e.g. /about#Team - need to get HTML from the other page
|
207
|
+
create_nokogiri(absolute_path)
|
212
208
|
end
|
213
209
|
end
|
214
210
|
end
|
data/lib/html-proofer/log.rb
CHANGED
@@ -6,11 +6,11 @@ module HTMLProofer
|
|
6
6
|
include Yell::Loggable
|
7
7
|
|
8
8
|
def initialize(log_level)
|
9
|
-
@logger = Yell.new(:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
l.adapter :stdout, :
|
13
|
-
l.adapter :stderr, :
|
9
|
+
@logger = Yell.new(format: false, \
|
10
|
+
name: 'HTMLProofer', \
|
11
|
+
level: "gte.#{log_level}") do |l|
|
12
|
+
l.adapter :stdout, level: %i[debug info warn]
|
13
|
+
l.adapter :stderr, level: %i[error fatal]
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
data/lib/html-proofer/runner.rb
CHANGED
@@ -91,7 +91,7 @@ module HTMLProofer
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def check_path(path)
|
94
|
-
result = { :
|
94
|
+
result = { external_urls: {}, failures: [] }
|
95
95
|
html = create_nokogiri(path)
|
96
96
|
|
97
97
|
@src = [@src] if @type == :file
|
@@ -164,7 +164,7 @@ module HTMLProofer
|
|
164
164
|
sorted_failures.sort_and_report
|
165
165
|
count = @failures.length
|
166
166
|
failure_text = pluralize(count, 'failure', 'failures')
|
167
|
-
|
167
|
+
raise @logger.colorize :red, "HTML-Proofer found #{failure_text}!"
|
168
168
|
end
|
169
169
|
end
|
170
170
|
end
|
@@ -123,7 +123,7 @@ module HTMLProofer
|
|
123
123
|
def clean_url(href)
|
124
124
|
# catch any obvious issues, like strings in port numbers
|
125
125
|
parsed = Addressable::URI.parse(href)
|
126
|
-
if href !~
|
126
|
+
if href !~ /^([!#{$&}-;=?-\[\]_a-z~]|%[0-9a-fA-F]{2})+$/
|
127
127
|
parsed.normalize
|
128
128
|
else
|
129
129
|
href
|
@@ -131,7 +131,7 @@ module HTMLProofer
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def queue_request(method, href, filenames)
|
134
|
-
opts = @options[:typhoeus].merge(
|
134
|
+
opts = @options[:typhoeus].merge(method: method)
|
135
135
|
request = Typhoeus::Request.new(href, opts)
|
136
136
|
request.on_complete { |response| response_handler(response, filenames) }
|
137
137
|
@hydra.queue request
|
@@ -179,7 +179,7 @@ module HTMLProofer
|
|
179
179
|
|
180
180
|
# user-content is a special addition by GitHub.
|
181
181
|
xpath = %(//*[@name="#{hash}"]|//*[@id="#{hash}"])
|
182
|
-
if URI.parse(href).host
|
182
|
+
if URI.parse(href).host =~ /github\.com/i
|
183
183
|
xpath << %(|//*[@name="user-content-#{hash}"]|//*[@id="user-content-#{hash}"])
|
184
184
|
end
|
185
185
|
|
data/lib/html-proofer/utils.rb
CHANGED
@@ -7,11 +7,11 @@ module HTMLProofer
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def create_nokogiri(path)
|
10
|
-
if File.exist? path
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
content = if File.exist? path
|
11
|
+
File.open(path).read
|
12
|
+
else
|
13
|
+
path
|
14
|
+
end
|
15
15
|
|
16
16
|
Nokogiri::HTML(clean_content(content))
|
17
17
|
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: 3.
|
4
|
+
version: 3.7.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: 2017-
|
11
|
+
date: 2017-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mercenary
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.7'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: colored
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,6 +142,34 @@ dependencies:
|
|
142
142
|
- - ">="
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: rubocop
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: rubocop-github
|
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'
|
145
173
|
- !ruby/object:Gem::Dependency
|
146
174
|
name: rspec
|
147
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -272,7 +300,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
272
300
|
version: '0'
|
273
301
|
requirements: []
|
274
302
|
rubyforge_project:
|
275
|
-
rubygems_version: 2.
|
303
|
+
rubygems_version: 2.6.12
|
276
304
|
signing_key:
|
277
305
|
specification_version: 4
|
278
306
|
summary: A set of tests to validate your HTML output. These tests check if your image
|