src/api/lib/haml-lint/custom_linters/set_pagetitle_in_view.rb
# This custom linter for haml-lint will report an offense if @pagetitle is not set in a Haml view. Partials are ignored by this linter.
module HamlLint
class Linter::SetPagetitleInView < Linter
CHUNKS_WITH_POSSIBLE_PAGETITLES = [HamlLint::RubyExtraction::RubyFilterChunk,
HamlLint::RubyExtraction::ScriptChunk,
HamlLint::RubyExtraction::ImplicitEndChunk].freeze
include LinterRegistry
# Report an offense if the instance variable @pagetitle is not set in a Haml view. Partials are ignored by this linter.
#
# @param [HamlLint::Tree::RootNode] the root of a syntax tree
def visit_root(root_node)
# Do not proceed if the view isn't under the directory 'app/views/webui/' and doesn't end with the extension '.html.haml'
return unless root_node.file.match?(%r{^app/views/webui/.*\.html\.haml$})
# Do not proceed if the view is a partial (only partials start with an underscore)
return if File.basename(root_node.file).start_with?('_')
# Do not proceed if the view defines the instance variable @pagetitle, then this rule is respected. Yay!
return if instance_variable_pagetitle_is_defined?(document)
record_lint(root_node, 'Set the instance variable @pagetitle to have a page title when the view is rendered.')
end
private
# @param [HamlLint::Document] a parsed Haml document and its associated metadata
def instance_variable_pagetitle_is_defined?(document)
chunks = HamlLint::RubyExtraction::ChunkExtractor.new(document, script_output_prefix: '').extract
ruby_source_code = chunks.select { |c| CHUNKS_WITH_POSSIBLE_PAGETITLES.member?(c.class) }.map(&:ruby_lines).join("\n")
parsed_ruby = HamlLint::RubyParser.new.parse(ruby_source_code)
parsed_ruby.each_node.find do |descendant_node|
# Details on Abstract Syntax Tree from Parser gem: https://github.com/whitequark/parser/blob/11c7644365fe554217bb4670a4cbc905ab8504cd/doc/AST_FORMAT.md#to-instance-variable
# Are we assigning an instance variable? Is it called @pagetitle?
descendant_node.ivasgn_type? && descendant_node.children.first == :@pagetitle
end
end
end
end