Module: Spoom::Context::Sorbet

Extended by:
T::Helpers, T::Sig
Defined in:
lib/spoom/context/sorbet.rb

Overview

Sorbet features for a context

Instance Method Summary collapse

Instance Method Details

#has_sorbet_config?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/spoom/context/sorbet.rb', line 119

def has_sorbet_config?
  file?(Spoom::Sorbet::CONFIG_PATH)
end

#read_file_strictness(relative_path) ⇒ Object



142
143
144
# File 'lib/spoom/context/sorbet.rb', line 142

def read_file_strictness(relative_path)
  Spoom::Sorbet::Sigils.file_strictness(absolute_path_to(relative_path))
end

#read_sorbet_configObject



130
131
132
# File 'lib/spoom/context/sorbet.rb', line 130

def read_sorbet_config
  read(Spoom::Sorbet::CONFIG_PATH)
end

#sorbet_configObject



124
125
126
# File 'lib/spoom/context/sorbet.rb', line 124

def sorbet_config
  Spoom::Sorbet::Config.parse_string(read_sorbet_config)
end

#sorbet_intro_commitObject



148
149
150
151
152
153
154
155
156
# File 'lib/spoom/context/sorbet.rb', line 148

def sorbet_intro_commit
  res = git_log("--diff-filter=A --format='%h %at' -1 -- sorbet/config")
  return nil unless res.status

  out = res.out.strip
  return nil if out.empty?

  Spoom::Git::Commit.parse_line(out)
end

#sorbet_removal_commitObject



160
161
162
163
164
165
166
167
168
# File 'lib/spoom/context/sorbet.rb', line 160

def sorbet_removal_commit
  res = git_log("--diff-filter=D --format='%h %at' -1 -- sorbet/config")
  return nil unless res.status

  out = res.out.strip
  return nil if out.empty?

  Spoom::Git::Commit.parse_line(out)
end

#srb(*arg, sorbet_bin: nil, capture_err: true) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/spoom/context/sorbet.rb', line 15

def srb(*arg, sorbet_bin: nil, capture_err: true)
  res = if sorbet_bin
    exec("#{sorbet_bin} #{arg.join(" ")}", capture_err: capture_err)
  else
    bundle_exec("srb #{arg.join(" ")}", capture_err: capture_err)
  end

  case res.exit_code
  when Spoom::Sorbet::KILLED_CODE
    raise Spoom::Sorbet::Error::Killed.new("Sorbet was killed.", res)
  when Spoom::Sorbet::SEGFAULT_CODE
    raise Spoom::Sorbet::Error::Segfault.new("Sorbet segfaulted.", res)
  end

  res
end

#srb_files(with_config: nil, include_rbis: true) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/spoom/context/sorbet.rb', line 65

def srb_files(with_config: nil, include_rbis: true)
  config = with_config || sorbet_config

  allowed_extensions = config.allowed_extensions
  allowed_extensions = Spoom::Sorbet::Config::DEFAULT_ALLOWED_EXTENSIONS if allowed_extensions.empty?
  allowed_extensions -= [".rbi"] unless include_rbis

  excluded_patterns = config.ignore.map do |string|
    # We need to simulate the behavior of Sorbet's `--ignore` flag.
    #
    # From Sorbet docs on `--ignore`:
    # > Ignores input files that contain the given string in their paths (relative to the input path passed to
    # > Sorbet). Strings beginning with / match against the prefix of these relative paths; others are substring
    # > matchs. Matches must be against whole folder and file names, so `foo` matches `/foo/bar.rb` and
    # > `/bar/foo/baz.rb` but not `/foo.rb` or `/foo2/bar.rb`.
    string = if string.start_with?("/")
      # Strings beginning with / match against the prefix of these relative paths
      File.join(absolute_path, string)
    else
      # Others are substring matchs
      File.join(absolute_path, "**", string)
    end
    # Matches must be against whole folder and file names
    "#{string.delete_suffix("/")}{,/**}"
  end

  collector = FileCollector.new(allow_extensions: allowed_extensions, exclude_patterns: excluded_patterns)
  collector.visit_paths(config.paths.map { |path| absolute_path_to(path) })
  collector.files.map { |file| file.delete_prefix("#{absolute_path}/") }.sort
end

#srb_files_with_strictness(strictness, with_config: nil, include_rbis: true) ⇒ Object



104
105
106
107
# File 'lib/spoom/context/sorbet.rb', line 104

def srb_files_with_strictness(strictness, with_config: nil, include_rbis: true)
  srb_files(with_config: with_config, include_rbis: include_rbis)
    .select { |file| read_file_strictness(file) == strictness }
end

#srb_metrics(*arg, sorbet_bin: nil, capture_err: true) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/spoom/context/sorbet.rb', line 45

def srb_metrics(*arg, sorbet_bin: nil, capture_err: true)
  metrics_file = "metrics.tmp"

  T.unsafe(self).srb_tc(
    "--metrics-file",
    metrics_file,
    *arg,
    sorbet_bin: sorbet_bin,
    capture_err: capture_err,
  )
  return nil unless file?(metrics_file)

  metrics_path = absolute_path_to(metrics_file)
  metrics = Spoom::Sorbet::MetricsParser.parse_file(metrics_path)
  remove!(metrics_file)
  metrics
end

#srb_tc(*arg, sorbet_bin: nil, capture_err: true) ⇒ Object



33
34
35
36
# File 'lib/spoom/context/sorbet.rb', line 33

def srb_tc(*arg, sorbet_bin: nil, capture_err: true)
  arg.prepend("tc") unless sorbet_bin
  T.unsafe(self).srb(*arg, sorbet_bin: sorbet_bin, capture_err: capture_err)
end

#srb_version(*arg, sorbet_bin: nil, capture_err: true) ⇒ Object



110
111
112
113
114
115
# File 'lib/spoom/context/sorbet.rb', line 110

def srb_version(*arg, sorbet_bin: nil, capture_err: true)
  res = T.unsafe(self).srb_tc("--no-config", "--version", *arg, sorbet_bin: sorbet_bin, capture_err: capture_err)
  return nil unless res.status

  res.out.split(" ")[2]
end

#write_sorbet_config!(contents, append: false) ⇒ Object



136
137
138
# File 'lib/spoom/context/sorbet.rb', line 136

def write_sorbet_config!(contents, append: false)
  write!(Spoom::Sorbet::CONFIG_PATH, contents, append: append)
end