lib/packwerk/offenses_formatter.rb in packwerk-2.3.0 vs lib/packwerk/offenses_formatter.rb in packwerk-3.0.0

- old
+ new

@@ -4,16 +4,73 @@ module Packwerk module OffensesFormatter extend T::Sig extend T::Helpers - interface! + abstract! + class DuplicateFormatterError < StandardError + extend T::Sig + + sig { params(identifier: String).void } + def initialize(identifier) + super("Cannot have multiple identifiers with the same key (`#{identifier}`)") + end + end + + class << self + extend T::Sig + + sig { params(base: Class).void } + def included(base) + @offenses_formatters ||= T.let(@offenses_formatters, T.nilable(T::Array[Class])) + @offenses_formatters ||= [] + @offenses_formatters << base + end + + sig { returns(T::Array[OffensesFormatter]) } + def all + T.unsafe(@offenses_formatters).map(&:new) + end + + sig { params(identifier: String).returns(OffensesFormatter) } + def find(identifier) + formatter_by_identifier(identifier) + end + + private + + sig { params(name: String).returns(OffensesFormatter) } + def formatter_by_identifier(name) + @formatter_by_identifier ||= T.let(nil, T.nilable(T::Hash[String, T.nilable(OffensesFormatter)])) + @formatter_by_identifier ||= begin + index = T.let({}, T::Hash[String, T.nilable(OffensesFormatter)]) + OffensesFormatter.all.each do |formatter| + identifier = formatter.identifier + raise DuplicateFormatterError, identifier if index.key?(identifier) + + index[identifier] = formatter + end + T.let(index, T.nilable(T::Hash[String, T.nilable(OffensesFormatter)])) + end + + T.must(T.must(@formatter_by_identifier)[name]) + end + end + sig { abstract.params(offenses: T::Array[T.nilable(Offense)]).returns(String) } def show_offenses(offenses) end - sig { abstract.params(offense_collection: Packwerk::OffenseCollection, for_files: T::Set[String]).returns(String) } + sig { abstract.params(offense_collection: OffenseCollection, for_files: T::Set[String]).returns(String) } def show_stale_violations(offense_collection, for_files) + end + + sig { abstract.returns(String) } + def identifier + end + + sig { abstract.params(strict_mode_violations: T::Array[ReferenceOffense]).returns(String) } + def show_strict_mode_violations(strict_mode_violations) end end end