Add rake guides:lint task to raise error on broken anchor links

Co-authored-by: zzak <zzakscott@gmail.com>
This commit is contained in:
Akhil G Krishnan 2024-05-01 17:28:39 +05:30
parent 325c04c1af
commit 61090b1f3f
3 changed files with 49 additions and 14 deletions

@ -23,12 +23,23 @@ namespace :guides do
end
end
desc "Lint guides, using `mdl`"
task :lint do
require "mdl"
all = Dir.glob("#{__dir__}/source/*.md")
files = all - Dir.glob("#{__dir__}/**/*_release_notes.md") # Ignore release notes
MarkdownLint.run files
desc "Lint guides, using `mdl` and check for broken links"
task lint: ["lint:check_links", "lint:mdl"]
namespace :lint do
desc "Check links in generated HTML guides"
task :check_links do
ENV["GUIDES_LINT"] = "1"
ruby "-Eutf-8:utf-8", "rails_guides.rb"
end
desc "Run mdl to check Markdown files for style guide violations and lint errors"
task :mdl do
require "mdl"
all = Dir.glob("#{__dir__}/source/*.md")
files = all - Dir.glob("#{__dir__}/**/*_release_notes.md") # Ignore release notes
MarkdownLint.run files
end
end
# Validate guides -------------------------------------------------------------------------

@ -26,5 +26,6 @@
only: env_value["ONLY"],
epub: env_flag["EPUB"],
language: env_value["GUIDES_LANGUAGE"],
direction: env_value["DIRECTION"]
direction: env_value["DIRECTION"],
lint: env_flag["GUIDES_LINT"]
).generate

@ -13,12 +13,13 @@
require "rails_guides/markdown"
require "rails_guides/helpers"
require "rails_guides/epub"
require "debug"
module RailsGuides
class Generator
GUIDES_RE = /\.(?:erb|md)\z/
def initialize(edge:, version:, all:, only:, epub:, language:, direction: nil)
def initialize(edge:, version:, all:, only:, epub:, language:, direction: nil, lint:)
@edge = edge
@version = version
@all = all
@ -26,24 +27,38 @@ def initialize(edge:, version:, all:, only:, epub:, language:, direction: nil)
@epub = epub
@language = language
@direction = direction || "ltr"
@lint = lint
@warnings = []
if @epub
register_special_mime_types
end
initialize_dirs
create_output_dir_if_needed
create_output_dir_if_needed if !dry_run?
initialize_markdown_renderer
end
def generate
generate_guides
process_scss
copy_assets
generate_epub if @epub
if @lint && @warnings.any?
puts "#{@warnings.join("\n")}"
exit 1
end
if !dry_run?
process_scss
copy_assets
generate_epub if @epub
end
end
private
def dry_run?
[@lint].any?
end
def register_special_mime_types
Mime::Type.register_alias("application/xml", :opf, %w(opf))
Mime::Type.register_alias("application/xml", :ncx, %w(ncx))
@ -168,12 +183,15 @@ def generate_guide(guide, output_file)
epub: @epub
).render(body)
warn_about_broken_links(result)
broken = warn_about_broken_links(result)
if broken.any?
@warnings << "[WARN] BROKEN LINK(s): #{guide}: #{broken.join(", ")}"
end
end
File.open(output_path, "w") do |f|
f.write(result)
end
end if !dry_run?
end
def warn_about_broken_links(html)
@ -199,13 +217,18 @@ def extract_anchors(html)
end
def check_fragment_identifiers(html, anchors)
broken_links = []
html.scan(/<a\s+href="#([^"]+)/).flatten.each do |fragment_identifier|
next if fragment_identifier == "mainCol" # in layout, jumps to some DIV
unless anchors.member?(CGI.unescape(fragment_identifier))
guess = DidYouMean::SpellChecker.new(dictionary: anchors).correct(fragment_identifier).first
puts "*** BROKEN LINK: ##{fragment_identifier}, perhaps you meant ##{guess}."
broken_links << "##{fragment_identifier}"
end
end
broken_links
end
end
end