Skip to content

Commit 9c3e29b

Browse files
committed
Use Prism in Sorbet calls, if enabled
1 parent 041ad58 commit 9c3e29b

2 files changed

Lines changed: 120 additions & 1 deletion

File tree

lib/tapioca/helpers/sorbet_helper.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,67 @@ module SorbetHelper
1313

1414
SPOOM_CONTEXT = Spoom::Context.new(".") #: Spoom::Context
1515

16+
# Represents the `sorbet/config` file, and provides access to its options.
17+
# If the file doesn't exist, this object will still exist, but will return default values for all options.
18+
class SorbetConfig
19+
class << self
20+
#: (Spoom::Context spoom_context) -> SorbetConfig
21+
def parse_from(spoom_context)
22+
config_path = File.join(spoom_context.absolute_path, "sorbet", "config")
23+
content = File.exist?(config_path) ? File.read(config_path) : ""
24+
parse(content)
25+
end
26+
27+
#: (String content) -> SorbetConfig
28+
def parse(content)
29+
lines = content.lines.map(&:strip).reject(&:empty?)
30+
31+
options = lines.filter_map do |line|
32+
next if line.start_with?("#") # Skip comments
33+
next unless line.start_with?("--")
34+
35+
key, value = line.split("=", 2)
36+
key = key #: as !nil
37+
38+
[key, value]
39+
end.to_h #: Hash[String, String | bool | nil]
40+
41+
new(
42+
parser: options["--parser"] == "prism" ? :prism : :original,
43+
)
44+
end
45+
end
46+
47+
#: (parser: Symbol) -> void
48+
def initialize(parser:)
49+
@parser = parser #: Symbol
50+
end
51+
52+
#: Symbol
53+
attr_reader :parser
54+
55+
#: -> bool
56+
def parse_with_prism? = @parser == :prism
57+
end
58+
1659
FEATURE_REQUIREMENTS = {
1760
# feature_name: ::Gem::Requirement.new(">= ___"), # https://github.com/sorbet/sorbet/pull/___
1861
}.freeze #: Hash[Symbol, ::Gem::Requirement]
1962

2063
#: (*String sorbet_args) -> Spoom::ExecResult
2164
def sorbet(*sorbet_args)
65+
if sorbet_config.parse_with_prism?
66+
sorbet_args << "--parser=prism"
67+
end
68+
2269
SPOOM_CONTEXT.srb(sorbet_args.join(" "), sorbet_bin: sorbet_path)
2370
end
2471

72+
#: -> SorbetConfig
73+
def sorbet_config
74+
@sorbet_config ||= SorbetConfig.parse_from(SPOOM_CONTEXT) #: SorbetConfig?
75+
end
76+
2577
#: -> String
2678
def sorbet_path
2779
sorbet_path = ENV.fetch(SORBET_EXE_PATH_ENV_VAR, SORBET_BIN)

spec/tapioca/helpers/sorbet_helper_spec.rb

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,74 @@ class Tapioca::SorbetHelperSpec < Minitest::Spec
3434
end
3535
end
3636

37-
private
37+
describe Tapioca::SorbetHelper::SorbetConfig do
38+
it "ignores comment lines" do
39+
config = parse(<<~CONFIG)
40+
# --parser=prism
41+
CONFIG
42+
assert_equal(:original, config.parser)
43+
end
44+
45+
it "ignores blank lines" do
46+
config = parse(<<~CONFIG)
47+
48+
--parser=prism
49+
50+
CONFIG
51+
assert_equal(:prism, config.parser)
52+
end
53+
54+
it "ignores lines without -- prefix" do
55+
config = parse(<<~CONFIG)
56+
.
57+
src/
58+
--parser=prism
59+
CONFIG
60+
assert_equal(:prism, config.parser)
61+
end
62+
63+
describe "--parser" do
64+
it "detects --parser=prism" do
65+
config = parse(<<~CONFIG)
66+
.
67+
--parser=prism
68+
CONFIG
69+
assert_equal(:prism, config.parser)
70+
assert_predicate(config, :parse_with_prism?)
71+
end
72+
73+
it "defaults to :original for empty config" do
74+
config = parse("")
75+
assert_equal(:original, config.parser)
76+
refute_predicate(config, :parse_with_prism?)
77+
end
78+
79+
it "defaults to :original when no --parser option" do
80+
config = parse(<<~CONFIG)
81+
.
82+
--dir=foo
83+
CONFIG
84+
assert_equal(:original, config.parser)
85+
end
86+
87+
it "treats non-prism values as :original" do
88+
config = parse(<<~CONFIG)
89+
.
90+
--parser=original
91+
CONFIG
92+
assert_equal(:original, config.parser)
93+
refute_predicate(config, :parse_with_prism?)
94+
end
95+
end
96+
97+
private
98+
99+
#: (String content) -> Tapioca::SorbetHelper::SorbetConfig
100+
def parse(content) = Tapioca::SorbetHelper::SorbetConfig.parse(content)
101+
end
102+
103+
# Rubocop thinks the `private` call above (in the `describe` block) still applies here. It doesn't.
104+
private # rubocop:disable Lint/UselessAccessModifier
38105

39106
#: (String? path) { (String? custom_path) -> void } -> void
40107
def with_custom_sorbet_exe_path(path, &block)

0 commit comments

Comments
 (0)