Skip to content

Commit

Permalink
lint
Browse files Browse the repository at this point in the history
  • Loading branch information
gjtorikian committed Jan 20, 2023
1 parent 1dbb0b8 commit b1feb08
Show file tree
Hide file tree
Showing 16 changed files with 374 additions and 150 deletions.
10 changes: 8 additions & 2 deletions lib/html_proofer/check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ def run
end

def add_failure(description, line: nil, status: nil, content: nil)
@failures << Failure.new(@runner.current_filename, short_name, description, line: line, status: status,
content: content)
@failures << Failure.new(
@runner.current_filename,
short_name,
description,
line: line,
status: status,
content: content,
)
end

def short_name
Expand Down
14 changes: 10 additions & 4 deletions lib/html_proofer/check/favicon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ def run

if found
if @favicon.url.protocol_relative?
add_failure("favicon link #{@favicon.url} is a protocol-relative URL, use explicit https:// instead",
line: @favicon.line, content: @favicon.content)
add_failure(
"favicon link #{@favicon.url} is a protocol-relative URL, use explicit https:// instead",
line: @favicon.line,
content: @favicon.content,
)
elsif @favicon.url.remote?
add_to_external_urls(@favicon.url, @favicon.line)
elsif !@favicon.url.exists?
add_failure("internal favicon #{@favicon.url.raw_attribute} does not exist", line: @favicon.line,
content: @favicon.content)
add_failure(
"internal favicon #{@favicon.url.raw_attribute} does not exist",
line: @favicon.line,
content: @favicon.content,
)
end
else
add_failure("no favicon provided")
Expand Down
49 changes: 35 additions & 14 deletions lib/html_proofer/check/images.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,39 @@ def run
next if @img.ignore?

# screenshot filenames should return because of terrible names
add_failure("image has a terrible filename (#{@img.url.raw_attribute})", line: @img.line,
content: @img.content) if terrible_filename?
add_failure(
"image has a terrible filename (#{@img.url.raw_attribute})",
line: @img.line,
content: @img.content,
) if terrible_filename?

# does the image exist?
if missing_src?
add_failure("image has no src or srcset attribute", line: @img.line, content: @img.content)
elsif @img.url.protocol_relative?
add_failure("image link #{@img.url} is a protocol-relative URL, use explicit https:// instead",
line: @img.line, content: @img.content)
add_failure(
"image link #{@img.url} is a protocol-relative URL, use explicit https:// instead",
line: @img.line,
content: @img.content,
)
elsif @img.url.remote?
add_to_external_urls(@img.url, @img.line)
elsif !@img.url.exists? && !@img.multiple_srcsets? && !@img.multiple_sizes?
add_failure("internal image #{@img.url.raw_attribute} does not exist", line: @img.line,
content: @img.content)
add_failure(
"internal image #{@img.url.raw_attribute} does not exist",
line: @img.line,
content: @img.content,
)
elsif @img.multiple_srcsets? || @img.multiple_sizes?
@img.srcsets_wo_sizes.each do |srcset|
srcset_url = HTMLProofer::Attribute::Url.new(@runner, srcset, base_url: @img.base_url, extract_size: true)

if srcset_url.protocol_relative?
add_failure("image link #{srcset_url.url} is a protocol-relative URL, use explicit https:// instead",
line: @img.line, content: @img.content)
add_failure(
"image link #{srcset_url.url} is a protocol-relative URL, use explicit https:// instead",
line: @img.line,
content: @img.content,
)
elsif srcset_url.remote?
add_to_external_urls(srcset_url.url, @img.line)
elsif !srcset_url.exists?
Expand All @@ -44,16 +56,25 @@ def run
# if this is an img element, check that the alt attribute is present
if @img.img_tag? && !ignore_element?
if missing_alt_tag? && !ignore_missing_alt?
add_failure("image #{@img.url.raw_attribute} does not have an alt attribute", line: @img.line,
content: @img.content)
add_failure(
"image #{@img.url.raw_attribute} does not have an alt attribute",
line: @img.line,
content: @img.content,
)
elsif (empty_alt_tag? || alt_all_spaces?) && !ignore_empty_alt?
add_failure("image #{@img.url.raw_attribute} has an alt attribute, but no content", line: @img.line,
content: @img.content)
add_failure(
"image #{@img.url.raw_attribute} has an alt attribute, but no content",
line: @img.line,
content: @img.content,
)
end
end

add_failure("image #{@img.url.raw_attribute} uses the http scheme", line: @img.line,
content: @img.content) if @runner.enforce_https? && @img.url.http?
add_failure(
"image #{@img.url.raw_attribute} uses the http scheme",
line: @img.line,
content: @img.content,
) if @runner.enforce_https? && @img.url.http?
end

external_urls
Expand Down
49 changes: 35 additions & 14 deletions lib/html_proofer/check/links.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ def run
end

if @link.url.protocol_relative?
add_failure("#{@link.url} is a protocol-relative URL, use explicit https:// instead",
line: @link.line, content: @link.content)
add_failure(
"#{@link.url} is a protocol-relative URL, use explicit https:// instead",
line: @link.line,
content: @link.content,
)
next
end

Expand All @@ -55,8 +58,11 @@ def run
elsif @link.url.internal?
# does the local directory have a trailing slash?
if @link.url.unslashed_directory?(@link.url.absolute_path)
add_failure("internally linking to a directory #{@link.url.raw_attribute} without trailing slash",
line: @link.line, content: @link.content)
add_failure(
"internally linking to a directory #{@link.url.raw_attribute} without trailing slash",
line: @link.line,
content: @link.content,
)
next
end

Expand Down Expand Up @@ -88,17 +94,26 @@ def check_schemes

def handle_mailto
if @link.url.path.empty?
add_failure("#{@link.url.raw_attribute} contains no email address", line: @link.line,
content: @link.content) unless ignore_empty_mailto?
add_failure(
"#{@link.url.raw_attribute} contains no email address",
line: @link.line,
content: @link.content,
) unless ignore_empty_mailto?
elsif !/#{URI::MailTo::EMAIL_REGEXP}/o.match?(@link.url.path)
add_failure("#{@link.url.raw_attribute} contains an invalid email address", line: @link.line,
content: @link.content)
add_failure(
"#{@link.url.raw_attribute} contains an invalid email address",
line: @link.line,
content: @link.content,
)
end
end

def handle_tel
add_failure("#{@link.url.raw_attribute} contains no phone number", line: @link.line,
content: @link.content) if @link.url.path.empty?
add_failure(
"#{@link.url.raw_attribute} contains no phone number",
line: @link.line,
content: @link.content,
) if @link.url.path.empty?
end

def ignore_empty_mailto?
Expand All @@ -113,13 +128,19 @@ def check_sri
return unless SRI_REL_TYPES.include?(@link.node["rel"])

if blank?(@link.node["integrity"]) && blank?(@link.node["crossorigin"])
add_failure("SRI and CORS not provided in: #{@link.url.raw_attribute}", line: @link.line,
content: @link.content)
add_failure(
"SRI and CORS not provided in: #{@link.url.raw_attribute}",
line: @link.line,
content: @link.content,
)
elsif blank?(@link.node["integrity"])
add_failure("Integrity is missing in: #{@link.url.raw_attribute}", line: @link.line, content: @link.content)
elsif blank?(@link.node["crossorigin"])
add_failure("CORS not provided for external resource in: #{@link.link.url.raw_attribute}", line: @link.line,
content: @link.content)
add_failure(
"CORS not provided for external resource in: #{@link.link.url.raw_attribute}",
line: @link.line,
content: @link.content,
)
end
end

Expand Down
14 changes: 10 additions & 4 deletions lib/html_proofer/check/open_graph.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ def run
elsif !@open_graph.url.valid?
add_failure("#{@open_graph.src} is an invalid URL", line: @open_graph.line)
elsif @open_graph.url.protocol_relative?
add_failure("open graph link #{@open_graph.url} is a protocol-relative URL, use explicit https:// instead",
line: @open_graph.line, content: @open_graph.content)
add_failure(
"open graph link #{@open_graph.url} is a protocol-relative URL, use explicit https:// instead",
line: @open_graph.line,
content: @open_graph.content,
)
elsif @open_graph.url.remote?
add_to_external_urls(@open_graph.url, @open_graph.line)
else
add_failure("internal open graph #{@open_graph.url.raw_attribute} does not exist", line: @open_graph.line,
content: @open_graph.content) unless @open_graph.url.exists?
add_failure(
"internal open graph #{@open_graph.url.raw_attribute} does not exist",
line: @open_graph.line,
content: @open_graph.content,
) unless @open_graph.url.exists?
end
end

Expand Down
35 changes: 25 additions & 10 deletions lib/html_proofer/check/scripts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@ def run
if missing_src?
add_failure("script is empty and has no src attribute", line: @script.line, content: @script.content)
elsif @script.url.protocol_relative?
add_failure("script link #{@script.url} is a protocol-relative URL, use explicit https:// instead",
line: @script.line, content: @script.content)
add_failure(
"script link #{@script.url} is a protocol-relative URL, use explicit https:// instead",
line: @script.line,
content: @script.content,
)
elsif @script.url.remote?
add_to_external_urls(@script.url, @script.line)
check_sri if @runner.check_sri?
elsif !@script.url.exists?
add_failure("internal script reference #{@script.src} does not exist", line: @script.line,
content: @script.content)
add_failure(
"internal script reference #{@script.src} does not exist",
line: @script.line,
content: @script.content,
)
end
end

Expand All @@ -34,14 +40,23 @@ def missing_src?

def check_sri
if blank?(@script.node["integrity"]) && blank?(@script.node["crossorigin"])
add_failure("SRI and CORS not provided in: #{@script.url.raw_attribute}", line: @script.line,
content: @script.content)
add_failure(
"SRI and CORS not provided in: #{@script.url.raw_attribute}",
line: @script.line,
content: @script.content,
)
elsif blank?(@script.node["integrity"])
add_failure("Integrity is missing in: #{@script.url.raw_attribute}", line: @script.line,
content: @script.content)
add_failure(
"Integrity is missing in: #{@script.url.raw_attribute}",
line: @script.line,
content: @script.content,
)
elsif blank?(@script.node["crossorigin"])
add_failure("CORS not provided for external resource in: #{@script.url.raw_attribute}", line: @script.line,
content: @script.content)
add_failure(
"CORS not provided for external resource in: #{@script.url.raw_attribute}",
line: @script.line,
content: @script.content,
)
end
end
end
Expand Down
64 changes: 42 additions & 22 deletions lib/html_proofer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -280,49 +280,69 @@ def parse_json_option(option_name, config, symbolize_names: true)
module ConfigurationHelp
TEXT = {
as_links: ["Assumes that `PATH` is a comma-separated array of links to check."],
assume_extension: ["Automatically add specified extension to files for internal links, ",
"to allow extensionless URLs (as supported by most servers) (default: `.html`).",],
assume_extension: [
"Automatically add specified extension to files for internal links, ",
"to allow extensionless URLs (as supported by most servers) (default: `.html`).",
],
directory_index_file: ["Sets the file to look for when a link refers to a directory. (default: `index.html`)."],
extensions: ["A comma-separated list of Strings indicating the file extensions you",
"would like to check (default: `.html`)",],
extensions: [
"A comma-separated list of Strings indicating the file extensions you",
"would like to check (default: `.html`)",
],

allow_hash_href: ['"If `true`, assumes `href="#"` anchors are valid (default: `true`)"'],
allow_missing_href: ["If `true`, does not flag `a` tags missing `href`. In HTML5, this is technically ",
"allowed, but could also be human error. (default: `false`)",],
checks: ["A comma-separated list of Strings indicating which checks you",
"want to run (default: `[\"Links\", \"Images\", \"Scripts\"]",],
allow_missing_href: [
"If `true`, does not flag `a` tags missing `href`. In HTML5, this is technically ",
"allowed, but could also be human error. (default: `false`)",
],
checks: [
"A comma-separated list of Strings indicating which checks you",
"want to run (default: `[\"Links\", \"Images\", \"Scripts\"]",
],
check_external_hash: ["Checks whether external hashes exist (even if the webpage exists) (default: `true`)."],
check_internal_hash: ["Checks whether internal hashes exist (even if the webpage exists) (default: `true`)."],
check_sri: ["Check that `<link>` and `<script>` external resources use SRI (default: `false`)."],
disable_external: ["If `true`, does not run the external link checker (default: `false`)."],
enforce_https: ["Fails a link if it's not marked as `https` (default: `true`)."],
root_dir: ["The absolute path to the directory serving your html-files."],

ignore_empty_alt: ["If `true`, ignores images with empty/missing ",
"alt tags (in other words, `<img alt>` and `<img alt=\"\">`",
"are valid; set this to `false` to flag those) (default: `true`).",],
ignore_empty_mailto: ["If `true`, allows `mailto:` `href`s which don't",
"contain an email address (default: `false`)'.",],
ignore_empty_alt: [
"If `true`, ignores images with empty/missing ",
"alt tags (in other words, `<img alt>` and `<img alt=\"\">`",
"are valid; set this to `false` to flag those) (default: `true`).",
],
ignore_empty_mailto: [
"If `true`, allows `mailto:` `href`s which don't",
"contain an email address (default: `false`)'.",
],
ignore_missing_alt: ["If `true`, ignores images with missing alt tags (default: `false`)."],
ignore_status_codes: ["A comma-separated list of numbers representing status codes to ignore."],
ignore_files: ["A comma-separated list of Strings or RegExps containing file paths that are safe to ignore"],
ignore_urls: ["A comma-separated list of Strings or RegExps containing URLs that are",
"safe to ignore. This affects all HTML attributes, such as `alt` tags on images.",],
ignore_urls: [
"A comma-separated list of Strings or RegExps containing URLs that are",
"safe to ignore. This affects all HTML attributes, such as `alt` tags on images.",
],
only_status_codes: ["A comma-separated list of numbers representing the only status codes to report on."],
only_4xx: ["Only reports errors for links that fall within the 4xx status code range."],

swap_attributes: ["JSON-formatted config that maps element names to the",
"preferred attribute to check (default: `{}`).",],
swap_urls: ["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.",],
swap_attributes: [
"JSON-formatted config that maps element names to the",
"preferred attribute to check (default: `{}`).",
],
swap_urls: [
"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.",
],

typhoeus: ["JSON-formatted string of Typhoeus config; if set, overrides the html-proofer defaults."],
hydra: ["JSON-formatted string of Hydra config; if set, overrides the html-proofer defaults."],
cache: ["JSON-formatted string of cache config; if set, overrides the html-proofer defaults."],

log_level: ["Sets the logging level. One of `:debug`, `:info`, ",
"`:warn`, `:error`, or `:fatal`. (default: `:info`)",],
log_level: [
"Sets the logging level. One of `:debug`, `:info`, ",
"`:warn`, `:error`, or `:fatal`. (default: `:info`)",
],

version: ["Prints the version of html-proofer."],
}.freeze
Expand Down
6 changes: 4 additions & 2 deletions lib/html_proofer/log.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ class Log
STDERR_LEVELS = [:error, :fatal].freeze

def initialize(log_level)
@logger = Yell.new(format: false, \
@logger = Yell.new(
format: false, \
name: "HTMLProofer", \
level: "gte.#{log_level}") do |l|
level: "gte.#{log_level}",
) do |l|
l.adapter(:stdout, level: "lte.warn")
l.adapter(:stderr, level: "gte.error")
end
Expand Down
Loading

0 comments on commit b1feb08

Please sign in to comment.