From cd39c5fa9f893a1eb582713d816924f8f6714cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C4=81vis=20Namsons?= Date: Wed, 26 Oct 2022 16:54:27 +0300 Subject: [PATCH 1/4] Allow to configure parsers in packwerk --- USAGE.md | 24 +++++++++++++++- lib/packwerk/parsers/erb.rb | 7 +++++ lib/packwerk/parsers/factory.rb | 36 +++++++++--------------- lib/packwerk/parsers/parser_interface.rb | 4 +++ lib/packwerk/parsers/ruby.rb | 12 ++++++++ test/unit/parsers/factory_test.rb | 18 ++++++++---- 6 files changed, 71 insertions(+), 30 deletions(-) diff --git a/USAGE.md b/USAGE.md index 5bf11d86b..94f3c274f 100644 --- a/USAGE.md +++ b/USAGE.md @@ -80,6 +80,28 @@ Packwerk reads from the `packwerk.yml` configuration file in the root directory. | cache | false | when true, caches the results of parsing files | | cache_directory | tmp/cache/packwerk | the directory that will hold the packwerk cache | +### Using custom parsers + +You can specify a custom parser to parse different file formats (e.g. slim or haml) + +```ruby +class SlimParser + include ParserInterface + + REGEX = /\.slim\Z/ + + def call + # Your parsing logic here + end + + def match?(path) + REGEX.match?(path) + end +end + +Packwerk::Parsers::Factory.instance.parsers.append(SlimParser) +``` + ### Using a custom ERB parser You can specify a custom ERB parser if needed. For example, if you're using `<%graphql>` tags from https://github.com/github/graphql-client in your ERBs, you can use a custom parser subclass to comment them out so that Packwerk can parse the rest of the file: @@ -99,7 +121,7 @@ class CustomParser < Packwerk::Parsers::Erb end end -Packwerk::Parsers::Factory.instance.erb_parser_class = CustomParser +Packwerk::Parsers::Factory.instance.parsers = [Packwerk::Parsers::Ruby, CustomParser] ``` ## Using the cache diff --git a/lib/packwerk/parsers/erb.rb b/lib/packwerk/parsers/erb.rb index 98d056d8d..038046dac 100644 --- a/lib/packwerk/parsers/erb.rb +++ b/lib/packwerk/parsers/erb.rb @@ -11,6 +11,9 @@ module Parsers class Erb include ParserInterface + ERB_REGEX = /\.erb\Z/ + private_constant :ERB_REGEX + def initialize(parser_class: BetterHtml::Parser, ruby_parser: Ruby.new) @parser_class = parser_class @ruby_parser = ruby_parser @@ -33,6 +36,10 @@ def parse_buffer(buffer, file_path:) raise Parsers::ParseError, result end + def self.match?(path) + ERB_REGEX.match?(path) + end + private def to_ruby_ast(erb_ast, file_path) diff --git a/lib/packwerk/parsers/factory.rb b/lib/packwerk/parsers/factory.rb index c38c39413..1f1d05e84 100644 --- a/lib/packwerk/parsers/factory.rb +++ b/lib/packwerk/parsers/factory.rb @@ -9,34 +9,24 @@ class Factory extend T::Sig include Singleton - RUBY_REGEX = %r{ - # Although not important for regex, these are ordered from most likely to match to least likely. - \.(rb|rake|builder|gemspec|ru)\Z - | - (Gemfile|Rakefile)\Z - }x - private_constant :RUBY_REGEX + DEFAULT_PARSERS = T.let([ + Ruby, + Erb, + ], T::Array[ParserInterface]) - ERB_REGEX = /\.erb\Z/ - private_constant :ERB_REGEX + sig { returns(T::Array[ParserInterface]) } + attr_accessor :parsers - sig { params(path: String).returns(T.nilable(ParserInterface)) } - def for_path(path) - case path - when RUBY_REGEX - @ruby_parser ||= Ruby.new - when ERB_REGEX - @erb_parser ||= erb_parser_class.new - end + sig { void } + def initialize + @parsers = T.let(DEFAULT_PARSERS, T::Array[ParserInterface]) end - def erb_parser_class - @erb_parser_class ||= Erb - end + sig { params(path: String).returns(T.nilable(ParserInterface)) } + def for_path(path) + parser_for_path = parsers.find { |parser| parser.match?(path) } - def erb_parser_class=(klass) - @erb_parser_class = klass - @erb_parser = nil + parser_for_path&.new end end end diff --git a/lib/packwerk/parsers/parser_interface.rb b/lib/packwerk/parsers/parser_interface.rb index 451f009dd..97b631d28 100644 --- a/lib/packwerk/parsers/parser_interface.rb +++ b/lib/packwerk/parsers/parser_interface.rb @@ -12,6 +12,10 @@ module ParserInterface sig { abstract.params(io: File, file_path: String).returns(T.untyped) } def call(io:, file_path:) end + + sig { abstract.params(path: String).returns(T.boolean) } + def self.match?(path:) + end end end end diff --git a/lib/packwerk/parsers/ruby.rb b/lib/packwerk/parsers/ruby.rb index ed2e8385b..0dddc473c 100644 --- a/lib/packwerk/parsers/ruby.rb +++ b/lib/packwerk/parsers/ruby.rb @@ -9,6 +9,14 @@ module Parsers class Ruby include ParserInterface + RUBY_REGEX = %r{ + # Although not important for regex, these are ordered from most likely to match to least likely. + \.(rb|rake|builder|gemspec|ru)\Z + | + (Gemfile|Rakefile)\Z + }x + private_constant :RUBY_REGEX + class RaiseExceptionsParser < Parser::CurrentRuby def initialize(builder) super(builder) @@ -39,6 +47,10 @@ def call(io:, file_path: "") result = ParseResult.new(file: file_path, message: "Syntax error: #{e}") raise Parsers::ParseError, result end + + def self.match?(path) + RUBY_REGEX.match?(path) + end end end end diff --git a/test/unit/parsers/factory_test.rb b/test/unit/parsers/factory_test.rb index b0b3af765..845529607 100644 --- a/test/unit/parsers/factory_test.rb +++ b/test/unit/parsers/factory_test.rb @@ -23,13 +23,19 @@ class FactoryTest < Minitest::Test assert_instance_of(Parsers::Erb, factory.for_path("foo.html.erb")) assert_instance_of(Parsers::Erb, factory.for_path("foo.md.erb")) assert_instance_of(Parsers::Erb, factory.for_path("/sub/directory/foo.erb")) + end - fake_class = Class.new do + test "#for_path gives custom parser for paths the parser is defined to match" do + fake_erb_parser_class = Class.new do T.unsafe(self).include(ParserInterface) + + def self.match?(path) + /\.erb\Z/.match?(path) + end end - with_erb_parser_class(fake_class) do - assert_instance_of(fake_class, factory.for_path("foo.html.erb")) + with_parser_class(fake_erb_parser_class) do + assert_instance_of(fake_erb_parser_class, factory.for_path("foo.html.erb")) end end @@ -41,11 +47,11 @@ class FactoryTest < Minitest::Test private - def with_erb_parser_class(klass) - factory.erb_parser_class = klass + def with_parser_class(klass) + factory.parsers = [klass] yield ensure - factory.erb_parser_class = nil + factory.parsers = Parsers::Factory::DEFAULT_PARSERS end def factory From 3eeb98c2ae30e17c7e9b4aa20ed8f9e7d4f1444e Mon Sep 17 00:00:00 2001 From: Davis Namsons Date: Fri, 18 Nov 2022 01:59:26 +0200 Subject: [PATCH 2/4] Rename `ParserInterface` to `Parser` and move it out of `Parsers` module --- lib/packwerk.rb | 1 + lib/packwerk/file_processor.rb | 6 ++--- lib/packwerk/node.rb | 2 +- lib/packwerk/node_processor.rb | 4 ++-- lib/packwerk/parser.rb | 28 ++++++++++++++++++++++++ lib/packwerk/parsers/erb.rb | 6 ++--- lib/packwerk/parsers/factory.rb | 8 +++---- lib/packwerk/parsers/parser_interface.rb | 21 ------------------ lib/packwerk/parsers/ruby.rb | 8 +++---- lib/packwerk/reference_extractor.rb | 8 +++---- test/unit/parsers/factory_test.rb | 10 ++++----- 11 files changed, 55 insertions(+), 47 deletions(-) create mode 100644 lib/packwerk/parser.rb delete mode 100644 lib/packwerk/parsers/parser_interface.rb diff --git a/lib/packwerk.rb b/lib/packwerk.rb index 26d9bd127..bcf2addc5 100644 --- a/lib/packwerk.rb +++ b/lib/packwerk.rb @@ -35,6 +35,7 @@ module Packwerk autoload :Package autoload :PackageSet autoload :ParsedConstantDefinitions + autoload :Parser autoload :Parsers autoload :ParseRun autoload :UnresolvedReference diff --git a/lib/packwerk/file_processor.rb b/lib/packwerk/file_processor.rb index 104ecc48c..b0eefb211 100644 --- a/lib/packwerk/file_processor.rb +++ b/lib/packwerk/file_processor.rb @@ -56,7 +56,7 @@ def call(absolute_file) private sig do - params(node: Parser::AST::Node, absolute_file: String).returns(T::Array[UnresolvedReference]) + params(node: ::Parser::AST::Node, absolute_file: String).returns(T::Array[UnresolvedReference]) end def references_from_ast(node, absolute_file) references = [] @@ -68,14 +68,14 @@ def references_from_ast(node, absolute_file) references end - sig { params(absolute_file: String, parser: Parsers::ParserInterface).returns(T.untyped) } + sig { params(absolute_file: String, parser: Packwerk::Parser).returns(T.untyped) } def parse_into_ast(absolute_file, parser) File.open(absolute_file, "r", nil, external_encoding: Encoding::UTF_8) do |file| parser.call(io: file, file_path: absolute_file) end end - sig { params(file_path: String).returns(T.nilable(Parsers::ParserInterface)) } + sig { params(file_path: String).returns(T.nilable(Packwerk::Parser)) } def parser_for(file_path) @parser_factory.for_path(file_path) end diff --git a/lib/packwerk/node.rb b/lib/packwerk/node.rb index 1787ced76..7c657e919 100644 --- a/lib/packwerk/node.rb +++ b/lib/packwerk/node.rb @@ -60,7 +60,7 @@ def constant_name(constant_node) def each_child(node) if block_given? node.children.each do |child| - yield child if child.is_a?(Parser::AST::Node) + yield child if child.is_a?(::Parser::AST::Node) end else enum_for(:each_child, node) diff --git a/lib/packwerk/node_processor.rb b/lib/packwerk/node_processor.rb index c0eb12ddd..2477c87e6 100644 --- a/lib/packwerk/node_processor.rb +++ b/lib/packwerk/node_processor.rb @@ -19,8 +19,8 @@ def initialize(reference_extractor:, absolute_file:) sig do params( - node: Parser::AST::Node, - ancestors: T::Array[Parser::AST::Node] + node: ::Parser::AST::Node, + ancestors: T::Array[::Parser::AST::Node] ).returns(T.nilable(UnresolvedReference)) end def call(node, ancestors) diff --git a/lib/packwerk/parser.rb b/lib/packwerk/parser.rb new file mode 100644 index 000000000..c272fae97 --- /dev/null +++ b/lib/packwerk/parser.rb @@ -0,0 +1,28 @@ +# typed: strict +# frozen_string_literal: true + +module Packwerk + module Parser + extend T::Helpers + extend T::Sig + + interface! + + sig { abstract.params(io: File, file_path: String).returns(T.untyped) } + def call(io:, file_path:) + end + + module ClassMethods + extend T::Sig + extend T::Helpers + + abstract! + + sig { abstract.params(path: String).returns(T.boolean) } + def match?(path:) + end + end + + mixes_in_class_methods(ClassMethods) + end +end diff --git a/lib/packwerk/parsers/erb.rb b/lib/packwerk/parsers/erb.rb index 038046dac..c65bc7a98 100644 --- a/lib/packwerk/parsers/erb.rb +++ b/lib/packwerk/parsers/erb.rb @@ -9,7 +9,7 @@ module Packwerk module Parsers class Erb - include ParserInterface + include Packwerk::Parser ERB_REGEX = /\.erb\Z/ private_constant :ERB_REGEX @@ -20,7 +20,7 @@ def initialize(parser_class: BetterHtml::Parser, ruby_parser: Ruby.new) end def call(io:, file_path: "") - buffer = Parser::Source::Buffer.new(file_path) + buffer = ::Parser::Source::Buffer.new(file_path) buffer.source = io.read parse_buffer(buffer, file_path: file_path) end @@ -31,7 +31,7 @@ def parse_buffer(buffer, file_path:) rescue EncodingError => e result = ParseResult.new(file: file_path, message: e.message) raise Parsers::ParseError, result - rescue Parser::SyntaxError => e + rescue ::Parser::SyntaxError => e result = ParseResult.new(file: file_path, message: "Syntax error: #{e}") raise Parsers::ParseError, result end diff --git a/lib/packwerk/parsers/factory.rb b/lib/packwerk/parsers/factory.rb index 1f1d05e84..79e9834b5 100644 --- a/lib/packwerk/parsers/factory.rb +++ b/lib/packwerk/parsers/factory.rb @@ -12,17 +12,17 @@ class Factory DEFAULT_PARSERS = T.let([ Ruby, Erb, - ], T::Array[ParserInterface]) + ], T::Array[Packwerk::Parser]) - sig { returns(T::Array[ParserInterface]) } + sig { returns(T::Array[Packwerk::Parser]) } attr_accessor :parsers sig { void } def initialize - @parsers = T.let(DEFAULT_PARSERS, T::Array[ParserInterface]) + @parsers = T.let(DEFAULT_PARSERS, T::Array[Packwerk::Parser]) end - sig { params(path: String).returns(T.nilable(ParserInterface)) } + sig { params(path: String).returns(T.nilable(Packwerk::Parser)) } def for_path(path) parser_for_path = parsers.find { |parser| parser.match?(path) } diff --git a/lib/packwerk/parsers/parser_interface.rb b/lib/packwerk/parsers/parser_interface.rb deleted file mode 100644 index 97b631d28..000000000 --- a/lib/packwerk/parsers/parser_interface.rb +++ /dev/null @@ -1,21 +0,0 @@ -# typed: strict -# frozen_string_literal: true - -module Packwerk - module Parsers - module ParserInterface - extend T::Helpers - extend T::Sig - - interface! - - sig { abstract.params(io: File, file_path: String).returns(T.untyped) } - def call(io:, file_path:) - end - - sig { abstract.params(path: String).returns(T.boolean) } - def self.match?(path:) - end - end - end -end diff --git a/lib/packwerk/parsers/ruby.rb b/lib/packwerk/parsers/ruby.rb index 0dddc473c..cc8ccbd95 100644 --- a/lib/packwerk/parsers/ruby.rb +++ b/lib/packwerk/parsers/ruby.rb @@ -7,7 +7,7 @@ module Packwerk module Parsers class Ruby - include ParserInterface + include Packwerk::Parser RUBY_REGEX = %r{ # Although not important for regex, these are ordered from most likely to match to least likely. @@ -24,7 +24,7 @@ def initialize(builder) end end - class TolerateInvalidUtf8Builder < Parser::Builders::Default + class TolerateInvalidUtf8Builder < ::Parser::Builders::Default def string_value(token) value(token) end @@ -36,14 +36,14 @@ def initialize(parser_class: RaiseExceptionsParser) end def call(io:, file_path: "") - buffer = Parser::Source::Buffer.new(file_path) + buffer = ::Parser::Source::Buffer.new(file_path) buffer.source = io.read parser = @parser_class.new(@builder) parser.parse(buffer) rescue EncodingError => e result = ParseResult.new(file: file_path, message: e.message) raise Parsers::ParseError, result - rescue Parser::SyntaxError => e + rescue ::Parser::SyntaxError => e result = ParseResult.new(file: file_path, message: "Syntax error: #{e}") raise Parsers::ParseError, result end diff --git a/lib/packwerk/reference_extractor.rb b/lib/packwerk/reference_extractor.rb index 2dfed6fe3..3f633d58c 100644 --- a/lib/packwerk/reference_extractor.rb +++ b/lib/packwerk/reference_extractor.rb @@ -25,8 +25,8 @@ def initialize( sig do params( - node: Parser::AST::Node, - ancestors: T::Array[Parser::AST::Node], + node: ::Parser::AST::Node, + ancestors: T::Array[::Parser::AST::Node], absolute_file: String ).returns(T.nilable(UnresolvedReference)) end @@ -99,8 +99,8 @@ def self.get_fully_qualified_references_and_offenses_from(unresolved_references_ sig do params( constant_name: String, - node: Parser::AST::Node, - ancestors: T::Array[Parser::AST::Node], + node: ::Parser::AST::Node, + ancestors: T::Array[::Parser::AST::Node], absolute_file: String ).returns(T.nilable(UnresolvedReference)) end diff --git a/test/unit/parsers/factory_test.rb b/test/unit/parsers/factory_test.rb index 845529607..ad73af2e6 100644 --- a/test/unit/parsers/factory_test.rb +++ b/test/unit/parsers/factory_test.rb @@ -26,16 +26,16 @@ class FactoryTest < Minitest::Test end test "#for_path gives custom parser for paths the parser is defined to match" do - fake_erb_parser_class = Class.new do - T.unsafe(self).include(ParserInterface) + fake_class = Class.new do + T.unsafe(self).include(Packwerk::Parser) def self.match?(path) - /\.erb\Z/.match?(path) + /\.slim\Z/.match?(path) end end - with_parser_class(fake_erb_parser_class) do - assert_instance_of(fake_erb_parser_class, factory.for_path("foo.html.erb")) + with_parser_class(fake_class) do + assert_instance_of(fake_class, factory.for_path("foo.html.erb")) end end From 901cd23d78793a6e374eea758fd8fdc3b94917b5 Mon Sep 17 00:00:00 2001 From: Davis Namsons Date: Fri, 18 Nov 2022 02:06:08 +0200 Subject: [PATCH 3/4] Make custom parser registration automatic via `included` --- lib/packwerk/parser.rb | 27 ++++++++++++++++----------- lib/packwerk/parsers/erb.rb | 2 +- lib/packwerk/parsers/factory.rb | 19 ++----------------- lib/packwerk/parsers/ruby.rb | 4 ++-- test/unit/parsers/erb_test.rb | 2 +- test/unit/parsers/factory_test.rb | 17 +++++------------ test/unit/parsers/ruby_test.rb | 2 +- 7 files changed, 28 insertions(+), 45 deletions(-) diff --git a/lib/packwerk/parser.rb b/lib/packwerk/parser.rb index c272fae97..f332ccf9e 100644 --- a/lib/packwerk/parser.rb +++ b/lib/packwerk/parser.rb @@ -6,23 +6,28 @@ module Parser extend T::Helpers extend T::Sig + requires_ancestor { Kernel } + interface! - sig { abstract.params(io: File, file_path: String).returns(T.untyped) } - def call(io:, file_path:) - end + @parsers = T.let([], T::Array[Class]) - module ClassMethods - extend T::Sig - extend T::Helpers + sig { params(base: Class).void } + def self.included(base) + @parsers << base + end - abstract! + sig { returns(T::Array[T.untyped]) } + def self.all + T.unsafe(@parsers).map(&:new) + end - sig { abstract.params(path: String).returns(T.boolean) } - def match?(path:) - end + sig { abstract.params(io: File, file_path: String).returns(T.untyped) } + def call(io:, file_path:) end - mixes_in_class_methods(ClassMethods) + sig { abstract.params(path: String).returns(T::Boolean) } + def match?(path:) + end end end diff --git a/lib/packwerk/parsers/erb.rb b/lib/packwerk/parsers/erb.rb index c65bc7a98..6f8644a3c 100644 --- a/lib/packwerk/parsers/erb.rb +++ b/lib/packwerk/parsers/erb.rb @@ -36,7 +36,7 @@ def parse_buffer(buffer, file_path:) raise Parsers::ParseError, result end - def self.match?(path) + def match?(path:) ERB_REGEX.match?(path) end diff --git a/lib/packwerk/parsers/factory.rb b/lib/packwerk/parsers/factory.rb index 79e9834b5..de319c088 100644 --- a/lib/packwerk/parsers/factory.rb +++ b/lib/packwerk/parsers/factory.rb @@ -9,24 +9,9 @@ class Factory extend T::Sig include Singleton - DEFAULT_PARSERS = T.let([ - Ruby, - Erb, - ], T::Array[Packwerk::Parser]) - - sig { returns(T::Array[Packwerk::Parser]) } - attr_accessor :parsers - - sig { void } - def initialize - @parsers = T.let(DEFAULT_PARSERS, T::Array[Packwerk::Parser]) - end - - sig { params(path: String).returns(T.nilable(Packwerk::Parser)) } + sig { params(path: String).returns(T.nilable(T.untyped)) } def for_path(path) - parser_for_path = parsers.find { |parser| parser.match?(path) } - - parser_for_path&.new + Packwerk::Parser.all.find { |parser| parser.match?(path: path) } end end end diff --git a/lib/packwerk/parsers/ruby.rb b/lib/packwerk/parsers/ruby.rb index cc8ccbd95..feec45bb8 100644 --- a/lib/packwerk/parsers/ruby.rb +++ b/lib/packwerk/parsers/ruby.rb @@ -17,7 +17,7 @@ class Ruby }x private_constant :RUBY_REGEX - class RaiseExceptionsParser < Parser::CurrentRuby + class RaiseExceptionsParser < ::Parser::CurrentRuby def initialize(builder) super(builder) super.diagnostics.all_errors_are_fatal = true @@ -48,7 +48,7 @@ def call(io:, file_path: "") raise Parsers::ParseError, result end - def self.match?(path) + def match?(path:) RUBY_REGEX.match?(path) end end diff --git a/test/unit/parsers/erb_test.rb b/test/unit/parsers/erb_test.rb index c7cadb799..261b228fa 100644 --- a/test/unit/parsers/erb_test.rb +++ b/test/unit/parsers/erb_test.rb @@ -19,7 +19,7 @@ class ErbTest < Minitest::Test test "#call writes parse error to stdout" do error_message = "stub error" - err = Parser::SyntaxError.new(stub(message: error_message)) + err = ::Parser::SyntaxError.new(stub(message: error_message)) parser = stub parser.stubs(:ast).raises(err) diff --git a/test/unit/parsers/factory_test.rb b/test/unit/parsers/factory_test.rb index ad73af2e6..7df4d033d 100644 --- a/test/unit/parsers/factory_test.rb +++ b/test/unit/parsers/factory_test.rb @@ -25,18 +25,18 @@ class FactoryTest < Minitest::Test assert_instance_of(Parsers::Erb, factory.for_path("/sub/directory/foo.erb")) end - test "#for_path gives custom parser for paths the parser is defined to match" do + test "#for_path gives custom parser for matching paths" do fake_class = Class.new do T.unsafe(self).include(Packwerk::Parser) - def self.match?(path) + def match?(path:) /\.slim\Z/.match?(path) end end - with_parser_class(fake_class) do - assert_instance_of(fake_class, factory.for_path("foo.html.erb")) - end + assert_instance_of(fake_class, factory.for_path("foo.html.slim")) + assert_instance_of(fake_class, factory.for_path("foo.md.slim")) + assert_instance_of(fake_class, factory.for_path("/sub/directory/foo.slim")) end test "#for_path gives nil for unknown path" do @@ -47,13 +47,6 @@ def self.match?(path) private - def with_parser_class(klass) - factory.parsers = [klass] - yield - ensure - factory.parsers = Parsers::Factory::DEFAULT_PARSERS - end - def factory Parsers::Factory.instance end diff --git a/test/unit/parsers/ruby_test.rb b/test/unit/parsers/ruby_test.rb index 790652faa..efa700e77 100644 --- a/test/unit/parsers/ruby_test.rb +++ b/test/unit/parsers/ruby_test.rb @@ -16,7 +16,7 @@ class RubyTest < Minitest::Test test "#call writes parse error to stdout" do error_message = "stub error" - err = Parser::SyntaxError.new(stub(message: error_message)) + err = ::Parser::SyntaxError.new(stub(message: error_message)) parser = stub parser.stubs(:parse).raises(err) From 45d2a4643a2f31668a1b68bc74fc0cfcfeff69b5 Mon Sep 17 00:00:00 2001 From: Davis Namsons Date: Fri, 18 Nov 2022 02:39:53 +0200 Subject: [PATCH 4/4] Specify type --- lib/packwerk/parser.rb | 2 +- lib/packwerk/parsers/factory.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/packwerk/parser.rb b/lib/packwerk/parser.rb index f332ccf9e..94e3ed8ef 100644 --- a/lib/packwerk/parser.rb +++ b/lib/packwerk/parser.rb @@ -17,7 +17,7 @@ def self.included(base) @parsers << base end - sig { returns(T::Array[T.untyped]) } + sig { returns(T::Array[Parser]) } def self.all T.unsafe(@parsers).map(&:new) end diff --git a/lib/packwerk/parsers/factory.rb b/lib/packwerk/parsers/factory.rb index de319c088..32a4ff1a6 100644 --- a/lib/packwerk/parsers/factory.rb +++ b/lib/packwerk/parsers/factory.rb @@ -9,7 +9,7 @@ class Factory extend T::Sig include Singleton - sig { params(path: String).returns(T.nilable(T.untyped)) } + sig { params(path: String).returns(T.nilable(Packwerk::Parser)) } def for_path(path) Packwerk::Parser.all.find { |parser| parser.match?(path: path) } end