rspec/ci/asciidoc_validation/custom-asciidoctor

85 lines
2.7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/ruby
# Based on asciidoctor main ruby script.
# This is only meant to introspect and log which asciidoc files were used.
require 'asciidoctor'
require 'asciidoctor/cli'
class MainFileLogger < Asciidoctor::Extensions::Preprocessor
include Asciidoctor::Logging
def process document, reader
main_file = document.normalize_system_path(reader.file, document.reader.dir)
# This assumes unix-style path separator.
if nil == main_file.match(/^.*\/rules\/S\d+\/(\w+\/)?rule.adoc$/)
abort("Main file does not follow expected pattern: #{main_file}")
end
logger.info("ASCIIDOC LOGGER MAIN FILE:#{main_file}")
reader
end
end
class IncludeLogger < Asciidoctor::Extensions::IncludeProcessor
include Asciidoctor::Logging
def initialize document
@config = {} # Defined in parent class; will be updated by the extension registry mechanism.
@document = document
# @document.reader.file is not defined yet at this stage.
# Therefore we cannot compute the main file path and cache it.
# This cannot be done once in handles? because the object is then frozen.
# For these reasons, we end up recomputing the rule directory path each time.
end
def get_main_file reader
# See how include_stack is used:
# https://github.com/asciidoctor/asciidoctor/blob/f3800cc9c92faf8370041b2b27a61124318ed289/lib/asciidoctor/reader.rb#L669
if reader.include_stack.empty?
reader.file
else
main_frame = reader.include_stack.fetch(0)
main_frame.fetch(1)
end
end
def handles? target
include_path = @document.normalize_system_path(target, @document.reader.dir)
main_file = get_main_file(@document.reader)
main_file = @document.normalize_system_path(main_file, @document.reader.dir)
rule_dir = File.dirname(File.dirname(main_file))
rule_id = File.basename(rule_dir)
if rule_id == 'rules'
# This is a language-agnostic rule description.
rule_dir = File.dirname(main_file)
rule_id = File.basename(rule_dir)
end
git_dir = File.dirname(File.dirname(rule_dir))
shared_dir = File.join(git_dir, 'shared_content')
rule_dir = rule_dir + '/' # Don't allow S100 to include things from S1000.
if !include_path.start_with?(rule_dir) && !include_path.start_with?(shared_dir)
logger.info("ASCIIDOC LOGGER CROSSREFERENCE:#{rule_id} cross-references #{include_path}")
end
logger.info("ASCIIDOC LOGGER INCLUDE:#{include_path}")
false # Actually, this include processor does nothing.
end
# Intentionnaly no process function here.
end
Asciidoctor::Extensions.register do
preprocessor MainFileLogger
include_processor IncludeLogger.new @document
end
invoker = Asciidoctor::Cli::Invoker.new ARGV
GC.start
invoker.invoke!
exit invoker.code